1.1 --- a/core/smn_hudtext.cpp Fri Jul 11 06:51:21 2008 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,475 +0,0 @@
1.4 -/**
1.5 - * vim: set ts=4 :
1.6 - * =============================================================================
1.7 - * SourceMod
1.8 - * Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
1.9 - * =============================================================================
1.10 - *
1.11 - * This program is free software; you can redistribute it and/or modify it under
1.12 - * the terms of the GNU General Public License, version 3.0, as published by the
1.13 - * Free Software Foundation.
1.14 - *
1.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
1.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
1.18 - * details.
1.19 - *
1.20 - * You should have received a copy of the GNU General Public License along with
1.21 - * this program. If not, see <http://www.gnu.org/licenses/>.
1.22 - *
1.23 - * As a special exception, AlliedModders LLC gives you permission to link the
1.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
1.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
1.26 - * by the Valve Corporation. You must obey the GNU General Public License in
1.27 - * all respects for all other code used. Additionally, AlliedModders LLC grants
1.28 - * this exception to all derivative works. AlliedModders LLC defines further
1.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
1.30 - * or <http://www.sourcemod.net/license.php>.
1.31 - *
1.32 - * Version: $Id$
1.33 - */
1.34 -
1.35 -#include "sm_globals.h"
1.36 -#include "GameConfigs.h"
1.37 -#include "UserMessages.h"
1.38 -#include "TimerSys.h"
1.39 -#include "PlayerManager.h"
1.40 -#include "HandleSys.h"
1.41 -
1.42 -#define MAX_HUD_CHANNELS 6
1.43 -
1.44 -int g_HudMsgNum = -1;
1.45 -
1.46 -struct hud_syncobj_t
1.47 -{
1.48 - int *player_channels;
1.49 -};
1.50 -
1.51 -struct player_chaninfo_t
1.52 -{
1.53 - double chan_times[MAX_HUD_CHANNELS];
1.54 - hud_syncobj_t *chan_syncobjs[MAX_HUD_CHANNELS];
1.55 -};
1.56 -
1.57 -struct hud_text_parms
1.58 -{
1.59 - float x;
1.60 - float y;
1.61 - int effect;
1.62 - byte r1, g1, b1, a1;
1.63 - byte r2, g2, b2, a2;
1.64 - float fadeinTime;
1.65 - float fadeoutTime;
1.66 - float holdTime;
1.67 - float fxTime;
1.68 - int channel;
1.69 -};
1.70 -
1.71 -class HudMsgHelpers :
1.72 - public SMGlobalClass,
1.73 - public IHandleTypeDispatch,
1.74 - public IClientListener
1.75 -{
1.76 -public:
1.77 - bool IsSupported()
1.78 - {
1.79 - return (g_HudMsgNum != -1);
1.80 - }
1.81 -
1.82 - virtual void OnSourceModAllInitialized_Post()
1.83 - {
1.84 - const char *key;
1.85 -
1.86 - key = g_pGameConf->GetKeyValue("HudTextMsg");
1.87 - if (key != NULL)
1.88 - {
1.89 - g_HudMsgNum = g_UserMsgs.GetMessageIndex(key);
1.90 - }
1.91 -
1.92 - if (!IsSupported())
1.93 - {
1.94 - m_hHudSyncObj = 0;
1.95 - m_PlayerHuds = NULL;
1.96 - return;
1.97 - }
1.98 -
1.99 - m_PlayerHuds = new player_chaninfo_t[256+1];
1.100 - m_hHudSyncObj = g_HandleSys.CreateType("HudSyncObj", this, 0, NULL, NULL, g_pCoreIdent, NULL);
1.101 -
1.102 - g_Players.AddClientListener(this);
1.103 - }
1.104 -
1.105 - virtual void OnSourceModShutdown()
1.106 - {
1.107 - if (!IsSupported())
1.108 - {
1.109 - return;
1.110 - }
1.111 -
1.112 - delete [] m_PlayerHuds;
1.113 - g_HandleSys.RemoveType(m_hHudSyncObj, g_pCoreIdent);
1.114 -
1.115 - g_Players.RemoveClientListener(this);
1.116 - }
1.117 -
1.118 - virtual void OnHandleDestroy(HandleType_t type, void *object)
1.119 - {
1.120 - hud_syncobj_t *obj = (hud_syncobj_t *)object;
1.121 -
1.122 - delete [] obj->player_channels;
1.123 - delete obj;
1.124 - }
1.125 -
1.126 - virtual bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
1.127 - {
1.128 - *pSize = sizeof(unsigned int) * g_Players.GetMaxClients();
1.129 - return true;
1.130 - }
1.131 -
1.132 - virtual void OnClientConnected(int client)
1.133 - {
1.134 - player_chaninfo_t *player;
1.135 -
1.136 - player = &m_PlayerHuds[client];
1.137 - memset(player->chan_syncobjs, 0, sizeof(player->chan_syncobjs));
1.138 - memset(player->chan_times, 0, sizeof(player->chan_times));
1.139 - }
1.140 -
1.141 - Handle_t CreateHudSyncObj(IdentityToken_t *pIdent)
1.142 - {
1.143 - Handle_t hndl;
1.144 - int max_clients;
1.145 - HandleError err;
1.146 - hud_syncobj_t *obj;
1.147 - HandleSecurity sec;
1.148 -
1.149 - if ((max_clients = g_Players.MaxClients()) == 0)
1.150 - {
1.151 - max_clients = 256+1;
1.152 - }
1.153 -
1.154 - obj = new hud_syncobj_t;
1.155 - obj->player_channels = new int[max_clients];
1.156 -
1.157 - memset(obj->player_channels, 0, sizeof(int) * max_clients);
1.158 -
1.159 - sec = HandleSecurity(pIdent, g_pCoreIdent);
1.160 -
1.161 - if ((hndl = g_HandleSys.CreateHandleEx(m_hHudSyncObj, obj, &sec, NULL, &err))
1.162 - == BAD_HANDLE)
1.163 - {
1.164 - delete [] obj->player_channels;
1.165 - delete obj;
1.166 - }
1.167 -
1.168 - return hndl;
1.169 - }
1.170 -
1.171 - HandleError ReadHudSyncObj(Handle_t hndl,
1.172 - IdentityToken_t *pOwner,
1.173 - hud_syncobj_t **pObj)
1.174 - {
1.175 - HandleSecurity sec(pOwner, g_pCoreIdent);
1.176 - return g_HandleSys.ReadHandle(hndl, m_hHudSyncObj, &sec, (void **)pObj);
1.177 - }
1.178 -
1.179 - unsigned int AutoSelectChannel(unsigned int client)
1.180 - {
1.181 - int last_channel;
1.182 - player_chaninfo_t *player;
1.183 -
1.184 - player = &m_PlayerHuds[client];
1.185 -
1.186 - last_channel = 0;
1.187 - for (unsigned int i = 1; i < MAX_HUD_CHANNELS; i++)
1.188 - {
1.189 - if (player->chan_times[i] < player->chan_times[last_channel])
1.190 - {
1.191 - last_channel = i;
1.192 - }
1.193 - }
1.194 -
1.195 - ManualSelectChannel(client, last_channel);
1.196 -
1.197 - return last_channel;
1.198 - }
1.199 -
1.200 - int TryReuseLastChannel(unsigned int client, hud_syncobj_t *obj)
1.201 - {
1.202 - int last_channel;
1.203 - player_chaninfo_t *player;
1.204 -
1.205 - player = &m_PlayerHuds[client];
1.206 -
1.207 - /* First, see if we can re-use the previous channel. */
1.208 - last_channel = obj->player_channels[client];
1.209 -
1.210 - if (player->chan_syncobjs[last_channel] == obj)
1.211 - {
1.212 - player->chan_times[last_channel] = *g_pUniversalTime;
1.213 - return last_channel;
1.214 - }
1.215 -
1.216 - return -1;
1.217 - }
1.218 -
1.219 - int AutoSelectChannel(unsigned int client, hud_syncobj_t *obj)
1.220 - {
1.221 - int last_channel;
1.222 - player_chaninfo_t *player;
1.223 -
1.224 - player = &m_PlayerHuds[client];
1.225 -
1.226 - /* First, see if we can re-use the previous channel. */
1.227 - last_channel = obj->player_channels[client];
1.228 -
1.229 - if (player->chan_syncobjs[last_channel] == obj)
1.230 - {
1.231 - player->chan_times[last_channel] = *g_pUniversalTime;
1.232 - return last_channel;
1.233 - }
1.234 -
1.235 - last_channel = 0;
1.236 - for (unsigned int i = 1; i < MAX_HUD_CHANNELS; i++)
1.237 - {
1.238 - if (player->chan_times[i] < player->chan_times[last_channel])
1.239 - {
1.240 - last_channel = i;
1.241 - }
1.242 - }
1.243 -
1.244 - obj->player_channels[client] = last_channel;
1.245 - player->chan_syncobjs[last_channel] = obj;
1.246 - player->chan_times[last_channel] = *g_pUniversalTime;
1.247 -
1.248 - return last_channel;
1.249 - }
1.250 -
1.251 - int ManualSelectChannel(unsigned int client, int channel)
1.252 - {
1.253 - player_chaninfo_t *player;
1.254 -
1.255 - player = &m_PlayerHuds[client];
1.256 - player->chan_times[channel] = *g_pUniversalTime;
1.257 - player->chan_syncobjs[channel] = NULL;
1.258 -
1.259 - return channel;
1.260 - }
1.261 -private:
1.262 - HandleType_t m_hHudSyncObj;
1.263 - player_chaninfo_t *m_PlayerHuds;
1.264 -} s_HudMsgHelpers;
1.265 -
1.266 -hud_text_parms g_hud_params;
1.267 -
1.268 -static cell_t CreateHudSynchronizer(IPluginContext *pContext, const cell_t *params)
1.269 -{
1.270 - return s_HudMsgHelpers.CreateHudSyncObj(pContext->GetIdentity());
1.271 -}
1.272 -
1.273 -static cell_t SetHudTextParams(IPluginContext *pContext, const cell_t *params)
1.274 -{
1.275 - g_hud_params.x = sp_ctof(params[1]);
1.276 - g_hud_params.y = sp_ctof(params[2]);
1.277 - g_hud_params.holdTime = sp_ctof(params[3]);
1.278 - g_hud_params.r1 = static_cast<byte>(params[4]);
1.279 - g_hud_params.g1 = static_cast<byte>(params[5]);
1.280 - g_hud_params.b1 = static_cast<byte>(params[6]);
1.281 - g_hud_params.a1 = static_cast<byte>(params[7]);
1.282 - g_hud_params.effect = params[8];
1.283 - g_hud_params.fxTime = sp_ctof(params[9]);
1.284 - g_hud_params.fadeinTime = sp_ctof(params[10]);
1.285 - g_hud_params.fadeoutTime = sp_ctof(params[11]);
1.286 - g_hud_params.r2 = 255;
1.287 - g_hud_params.g2 = 255;
1.288 - g_hud_params.b2 = 250;
1.289 - g_hud_params.a2 = 0;
1.290 -
1.291 - return 1;
1.292 -}
1.293 -
1.294 -static cell_t SetHudTextParamsEx(IPluginContext *pContext, const cell_t *params)
1.295 -{
1.296 - cell_t *color1, *color2;
1.297 -
1.298 - pContext->LocalToPhysAddr(params[4], &color1);
1.299 - pContext->LocalToPhysAddr(params[5], &color2);
1.300 -
1.301 - g_hud_params.x = sp_ctof(params[1]);
1.302 - g_hud_params.y = sp_ctof(params[2]);
1.303 - g_hud_params.holdTime = sp_ctof(params[3]);
1.304 - g_hud_params.r1 = static_cast<byte>(color1[0]);
1.305 - g_hud_params.g1 = static_cast<byte>(color1[1]);
1.306 - g_hud_params.b1 = static_cast<byte>(color1[2]);
1.307 - g_hud_params.a1 = static_cast<byte>(color1[3]);
1.308 - g_hud_params.effect = params[6];
1.309 - g_hud_params.fxTime = sp_ctof(params[7]);
1.310 - g_hud_params.fadeinTime = sp_ctof(params[8]);
1.311 - g_hud_params.fadeoutTime = sp_ctof(params[9]);
1.312 - g_hud_params.r2 = static_cast<byte>(color2[0]);
1.313 - g_hud_params.g2 = static_cast<byte>(color2[1]);
1.314 - g_hud_params.b2 = static_cast<byte>(color2[2]);
1.315 - g_hud_params.a2 = static_cast<byte>(color2[3]);
1.316 -
1.317 - return 1;
1.318 -}
1.319 -
1.320 -void UTIL_SendHudText(int client, const hud_text_parms &textparms, const char *pMessage)
1.321 -{
1.322 - bf_write *bf;
1.323 - cell_t players[1];
1.324 -
1.325 - players[0] = client;
1.326 -
1.327 - bf = g_UserMsgs.StartMessage(g_HudMsgNum, players, 1, 0);
1.328 - bf->WriteByte(textparms.channel & 0xFF );
1.329 - bf->WriteFloat(textparms.x);
1.330 - bf->WriteFloat(textparms.y);
1.331 - bf->WriteByte(textparms.r1);
1.332 - bf->WriteByte(textparms.g1);
1.333 - bf->WriteByte(textparms.b1);
1.334 - bf->WriteByte(textparms.a1);
1.335 - bf->WriteByte(textparms.r2);
1.336 - bf->WriteByte(textparms.g2);
1.337 - bf->WriteByte(textparms.b2);
1.338 - bf->WriteByte(textparms.a2);
1.339 - bf->WriteByte(textparms.effect);
1.340 - bf->WriteFloat(textparms.fadeinTime);
1.341 - bf->WriteFloat(textparms.fadeoutTime);
1.342 - bf->WriteFloat(textparms.holdTime);
1.343 - bf->WriteFloat(textparms.fxTime);
1.344 - bf->WriteString(pMessage);
1.345 - g_UserMsgs.EndMessage();
1.346 -}
1.347 -
1.348 -static cell_t ShowSyncHudText(IPluginContext *pContext, const cell_t *params)
1.349 -{
1.350 - int client;
1.351 - Handle_t err;
1.352 - CPlayer *pPlayer;
1.353 - hud_syncobj_t *obj;
1.354 - char message_buffer[255-36];
1.355 -
1.356 - if (!s_HudMsgHelpers.IsSupported())
1.357 - {
1.358 - return -1;
1.359 - }
1.360 -
1.361 - if ((err = s_HudMsgHelpers.ReadHudSyncObj(params[2], pContext->GetIdentity(), &obj)) != HandleError_None)
1.362 - {
1.363 - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err);
1.364 - }
1.365 -
1.366 - client = params[1];
1.367 - if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
1.368 - {
1.369 - return pContext->ThrowNativeError("Invalid client index %d", client);
1.370 - }
1.371 - else if (!pPlayer->IsInGame())
1.372 - {
1.373 - return pContext->ThrowNativeError("Client %d is not in-game", client);
1.374 - }
1.375 -
1.376 - g_SourceMod.FormatString(message_buffer, sizeof(message_buffer), pContext, params, 3);
1.377 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.378 - {
1.379 - return 0;
1.380 - }
1.381 -
1.382 - g_hud_params.channel = s_HudMsgHelpers.AutoSelectChannel(client, obj);
1.383 - UTIL_SendHudText(client, g_hud_params, message_buffer);
1.384 -
1.385 - return 1;
1.386 -}
1.387 -
1.388 -static cell_t ClearSyncHud(IPluginContext *pContext, const cell_t *params)
1.389 -{
1.390 - int client;
1.391 - int channel;
1.392 - Handle_t err;
1.393 - CPlayer *pPlayer;
1.394 - hud_syncobj_t *obj;
1.395 -
1.396 - if (!s_HudMsgHelpers.IsSupported())
1.397 - {
1.398 - return -1;
1.399 - }
1.400 -
1.401 - if ((err = s_HudMsgHelpers.ReadHudSyncObj(params[2], pContext->GetIdentity(), &obj)) != HandleError_None)
1.402 - {
1.403 - return pContext->ThrowNativeError("Invalid Handle %x (error %d)", params[2], err);
1.404 - }
1.405 -
1.406 - client = params[1];
1.407 - if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
1.408 - {
1.409 - return pContext->ThrowNativeError("Invalid client index %d", client);
1.410 - }
1.411 - else if (!pPlayer->IsInGame())
1.412 - {
1.413 - return pContext->ThrowNativeError("Client %d is not in-game", client);
1.414 - }
1.415 -
1.416 - if ((channel = s_HudMsgHelpers.TryReuseLastChannel(client, obj)) == -1)
1.417 - {
1.418 - return -1;
1.419 - }
1.420 -
1.421 - g_hud_params.channel = channel;
1.422 - UTIL_SendHudText(client, g_hud_params, "");
1.423 -
1.424 - return g_hud_params.channel;
1.425 -}
1.426 -
1.427 -static cell_t ShowHudText(IPluginContext *pContext, const cell_t *params)
1.428 -{
1.429 - int client;
1.430 - CPlayer *pPlayer;
1.431 - char message_buffer[255-36];
1.432 -
1.433 - if (!s_HudMsgHelpers.IsSupported())
1.434 - {
1.435 - return -1;
1.436 - }
1.437 -
1.438 - client = params[1];
1.439 - if ((pPlayer = g_Players.GetPlayerByIndex(client)) == NULL)
1.440 - {
1.441 - return pContext->ThrowNativeError("Invalid client index %d", client);
1.442 - }
1.443 - else if (!pPlayer->IsInGame())
1.444 - {
1.445 - return pContext->ThrowNativeError("Client %d is not in-game", client);
1.446 - }
1.447 -
1.448 - g_SourceMod.FormatString(message_buffer, sizeof(message_buffer), pContext, params, 3);
1.449 - if (pContext->GetLastNativeError() != SP_ERROR_NONE)
1.450 - {
1.451 - return 0;
1.452 - }
1.453 -
1.454 - if (params[2] == -1)
1.455 - {
1.456 - g_hud_params.channel = s_HudMsgHelpers.AutoSelectChannel(client);
1.457 - }
1.458 - else
1.459 - {
1.460 - g_hud_params.channel = params[2] % MAX_HUD_CHANNELS;
1.461 - s_HudMsgHelpers.ManualSelectChannel(client, g_hud_params.channel);
1.462 - }
1.463 -
1.464 - UTIL_SendHudText(client, g_hud_params, message_buffer);
1.465 -
1.466 - return g_hud_params.channel;
1.467 -}
1.468 -
1.469 -REGISTER_NATIVES(hudNatives)
1.470 -{
1.471 - {"ClearSyncHud", ClearSyncHud},
1.472 - {"CreateHudSynchronizer", CreateHudSynchronizer},
1.473 - {"SetHudTextParams", SetHudTextParams},
1.474 - {"SetHudTextParamsEx", SetHudTextParamsEx},
1.475 - {"ShowHudText", ShowHudText},
1.476 - {"ShowSyncHudText", ShowSyncHudText},
1.477 - {NULL, NULL},
1.478 -};