Fixed build.
3 * =============================================================================
4 * SourceMod Team Fortress 2 Extension
5 * Copyright (C) 2004-2011 AlliedModders LLC. All rights reserved.
6 * =============================================================================
8 * This program is free software; you can redistribute it and/or modify it under
9 * the terms of the GNU General Public License, version 3.0, as published by the
10 * Free Software Foundation.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
17 * You should have received a copy of the GNU General Public License along with
18 * this program. If not, see <http://www.gnu.org/licenses/>.
20 * As a special exception, AlliedModders LLC gives you permission to link the
21 * code of this program (as well as its derivative works) to "Half-Life 2," the
22 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
23 * by the Valve Corporation. You must obey the GNU General Public License in
24 * all respects for all other code used. Additionally, AlliedModders LLC grants
25 * this exception to all derivative works. AlliedModders LLC defines further
26 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
27 * or <http://www.sourcemod.net/license.php>.
32 #include "extension.h"
33 #include "conditions.h"
36 #include <iplayerinfo.h>
38 typedef struct condflags_s {
42 condflags_t condflags_empty = { 0, 0 };
44 condflags_t g_PlayerConds[MAXPLAYERS+1];
46 IForward *g_addCondForward = NULL;
47 IForward *g_removeCondForward = NULL;
49 int playerCondOffset = -1;
50 int playerCondExOffset = -1;
51 int playerCondEx2Offset = -1;
52 int conditionBitsOffset = -1;
56 #define MAX_CONDS (sizeof(uint64_t) * 8)
58 inline condflags_t GetPlayerConds(CBaseEntity *pPlayer)
61 uint32_t playerCond = *(uint32_t *)((intptr_t)pPlayer + playerCondOffset);
62 uint32_t condBits = *(uint32_t *)((intptr_t)pPlayer + conditionBitsOffset);
63 uint32_t playerCondEx = *(uint32_t *)((intptr_t)pPlayer + playerCondExOffset);
64 uint32_t playerCondEx2 = *(uint32_t *)((intptr_t)pPlayer + playerCondEx2Offset);
66 uint64_t playerCondExAdj = playerCondEx;
67 playerCondExAdj <<= 32;
69 result.lower = playerCond|condBits|playerCondExAdj;
70 result.upper = playerCondEx2;
74 void Conditions_OnGameFrame(bool simulating)
82 condflags_t addedconds;
83 condflags_t removedconds;
85 int maxClients = gpGlobals->maxClients;
86 for (int i = 1; i <= maxClients; i++)
88 IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
89 if (!pPlayer || !pPlayer->IsInGame())
92 IPlayerInfo *info = pPlayer->GetPlayerInfo();
93 if (info->IsHLTV() || info->IsReplay())
96 CBaseEntity *pEntity = gamehelpers->ReferenceToEntity(i);
97 oldconds = g_PlayerConds[i];
98 newconds = GetPlayerConds(pEntity);
100 if (oldconds.lower == newconds.lower && oldconds.upper == newconds.upper)
103 addedconds.lower = newconds.lower &~ oldconds.lower;
104 removedconds.lower = oldconds.lower &~ newconds.lower;
105 addedconds.upper = newconds.upper &~ oldconds.upper;
106 removedconds.upper = oldconds.upper &~ newconds.upper;
111 uint64_t maxbit = MAX(addedconds.lower, addedconds.upper);
112 for (j = 0; j < MAX_CONDS && (bit = ((uint64_t)1 << j)) <= maxbit; j++)
114 if ((addedconds.lower & bit) == bit)
116 g_addCondForward->PushCell(i);
117 g_addCondForward->PushCell(j & 0xFFFFFFFF);
118 g_addCondForward->Execute(NULL, NULL);
120 if ((addedconds.upper & bit) == bit)
122 g_addCondForward->PushCell(i);
123 g_addCondForward->PushCell((j+64) & 0xFFFFFFFF);
124 g_addCondForward->Execute(NULL, NULL);
128 maxbit = MAX(removedconds.lower, removedconds.upper);
129 for (j = 0; j < MAX_CONDS && (bit = ((uint64_t)1 << j)) <= maxbit; j++)
131 if ((removedconds.lower & bit) == bit)
133 g_removeCondForward->PushCell(i);
134 g_removeCondForward->PushCell(j & 0xFFFFFFFF);
135 g_removeCondForward->Execute(NULL, NULL);
137 if ((removedconds.upper & bit) == bit)
139 g_removeCondForward->PushCell(i);
140 g_removeCondForward->PushCell((j+64) & 0xFFFFFFFF);
141 g_removeCondForward->Execute(NULL, NULL);
145 g_PlayerConds[i] = newconds;
149 bool InitialiseConditionChecks()
151 sm_sendprop_info_t prop;
152 if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCond", &prop))
154 g_pSM->LogError(myself, "Failed to find m_nPlayerCond prop offset");
158 playerCondOffset = prop.actual_offset;
160 if (!gamehelpers->FindSendPropInfo("CTFPlayer", "_condition_bits", &prop))
162 g_pSM->LogError(myself, "Failed to find _condition_bits prop offset");
166 conditionBitsOffset = prop.actual_offset;
168 if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCondEx", &prop))
170 g_pSM->LogError(myself, "Failed to find m_nPlayerCondEx prop offset");
174 playerCondExOffset = prop.actual_offset;
176 if (!gamehelpers->FindSendPropInfo("CTFPlayer", "m_nPlayerCondEx2", &prop))
178 g_pSM->LogError(myself, "Failed to find m_nPlayerCondEx2 prop offset");
182 playerCondEx2Offset = prop.actual_offset;
184 if (playerCondOffset == -1 || playerCondExOffset == -1 || conditionBitsOffset == -1 || playerCondEx2Offset == -1)
187 int maxClients = gpGlobals->maxClients;
188 for (int i = 1; i <= maxClients; i++)
190 IGamePlayer *pPlayer = playerhelpers->GetGamePlayer(i);
191 if (!pPlayer || !pPlayer->IsInGame())
194 g_PlayerConds[i] = GetPlayerConds(gamehelpers->ReferenceToEntity(i));
197 g_pSM->AddGameFrameHook(Conditions_OnGameFrame);
202 void Conditions_OnClientPutInServer(int client)
204 g_PlayerConds[client] = condflags_empty;
207 void RemoveConditionChecks()
209 g_pSM->RemoveGameFrameHook(Conditions_OnGameFrame);