cssdm_events.cpp
author Ruben Gonzalez <drifter01620@gmail.com>
Wed Oct 01 11:50:24 2014 -0400 (2014-10-01)
changeset 193 277c856152b0
parent 92 52cc55d67b2f
permissions -rw-r--r--
Update linix CS:GO gamedata
     1 /**
     2  * vim: set ts=4 :
     3  * ===============================================================
     4  * CS:S DM, Copyright (C) 2004-2007 AlliedModders LLC. 
     5  * By David "BAILOPAN" Anderson
     6  * All rights reserved.
     7  * ===============================================================
     8  *
     9  * This program is free software; you can redistribute it and/or modify
    10  * it under the terms of the GNU General Public License as published by
    11  * the Free Software Foundation; either version 2 of the License, or (at
    12  * your option) any later version.
    13  * 
    14  * This program is distributed in the hope that it will be useful, but
    15  * WITHOUT ANY WARRANTY; without even the implied warranty of
    16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    17  * General Public License for more details.
    18  * 
    19  * You should have received a copy of the GNU General Public License
    20  * along with this program; see the file COPYING; if not, write to the
    21  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
    22  * MA 02110-1301 USA
    23  * 
    24  * Version: $Id$
    25  */
    26 
    27 #include "cssdm_events.h"
    28 #include "cssdm_players.h"
    29 #include "cssdm_utils.h"
    30 #include "cssdm_config.h"
    31 #include "cssdm_headers.h"
    32 #include "cssdm_callbacks.h"
    33 #include "cssdm_weapons.h"
    34 #include "cssdm_detours.h"
    35 #include <sh_list.h>
    36 
    37 using namespace SourceHook;
    38 
    39 bool g_InRoundRestart = false;
    40 List<ITimer *> g_RagdollTimers;
    41 
    42 class RagdollRemoval : public ITimedEvent
    43 {
    44 public:
    45 	ResultType OnTimer(ITimer *pTimer, void *pData)
    46 	{
    47 		if (g_IsRunning)
    48 		{
    49 			IDataPack *pack = (IDataPack *)pData;
    50 			pack->Reset();
    51 			int index = pack->ReadCell();
    52 			int serial = pack->ReadCell();
    53 			edict_t *pEdict = gamehelpers->EdictOfIndex(index);
    54 			if (pEdict && !pEdict->IsFree() && DM_CheckSerial(pEdict, serial))
    55 			{
    56 				CBaseEntity *pEntity = DM_GetBaseEntity(index);
    57 				if (pEntity)
    58 				{
    59 					DM_RemoveEntity(pEntity);
    60 				}
    61 			}
    62 		}
    63 		g_RagdollTimers.remove(pTimer);
    64 
    65 		return Pl_Stop;
    66 	}
    67 
    68 	void OnTimerEnd(ITimer *pTimer, void *pData)
    69 	{
    70 		g_pSM->FreeDataPack((IDataPack *)pData);
    71 	}
    72 } s_RagdollRemover;
    73 
    74 class PlayerSpawner : public ITimedEvent
    75 {
    76 public:
    77 	ResultType OnTimer(ITimer *pTimer, void *pData)
    78 	{
    79 		if (!g_IsRunning)
    80 		{
    81 			return Pl_Stop;
    82 		}
    83 
    84 		/* Read pack data */
    85 		IDataPack *pack = (IDataPack *)pData;
    86 		pack->Reset();
    87 		int client = pack->ReadCell();
    88 
    89 		dm_player_t *player = DM_GetPlayer(client);
    90 
    91 		/* Make sure the team is valid */
    92 		int team = player->pInfo->GetTeamIndex();
    93 		if (team != CS_TEAM_T && team != CS_TEAM_CT)
    94 		{
    95 			return Pl_Stop;
    96 		}
    97 
    98 		/* Make sure they're dead */
    99 		if (DM_IsPlayerAlive(client))
   100 		{
   101 			return Pl_Stop;
   102 		}
   103 
   104 		DM_RespawnPlayer(client);
   105 
   106 		return Pl_Stop;
   107 	}
   108 
   109 	void OnTimerEnd(ITimer *pTimer, void *pData)
   110 	{
   111 		IDataPack *pack = (IDataPack *)pData;
   112 		pack->Reset();
   113 		int client = pack->ReadCell();
   114 
   115 		dm_player_t *player = DM_GetPlayer(client);
   116 		if (player->respawn_timer == pTimer)
   117 		{
   118 			player->respawn_timer = NULL;
   119 		}
   120 
   121 		g_pSM->FreeDataPack((IDataPack *)pData);
   122 	}
   123 } s_PlayerSpawner;
   124 
   125 void DM_ClearRagdollTimers()
   126 {
   127 	List<ITimer *>::iterator iter = g_RagdollTimers.begin();
   128 	while (iter != g_RagdollTimers.end())
   129 	{
   130 		timersys->KillTimer((*iter));
   131 		iter = g_RagdollTimers.erase(iter);
   132 	}
   133 }
   134 
   135 void DM_SchedRespawn(int client)
   136 {
   137 	dm_player_t *player = DM_GetPlayer(client);
   138 
   139 	if (player->respawn_timer)
   140 	{
   141 		timersys->KillTimer(player->respawn_timer);
   142 	}
   143 
   144 	IDataPack *pack = g_pSM->CreateDataPack();
   145 	pack->PackCell(client);
   146 
   147 	player->respawn_timer = timersys->CreateTimer(&s_PlayerSpawner, DM_GetRespawnWait(), pack, 0);
   148 }
   149 
   150 void OnClientCommand_Post(edict_t *edict, const CCommand &args)
   151 {
   152 	if (!g_IsRunning)
   153 	{
   154 		return;
   155 	}
   156 
   157 	const char *cmd = args.Arg(0);
   158 
   159 	if (strcmp(cmd, "joinclass") == 0)
   160 	{
   161 		int client = gamehelpers->IndexOfEdict(edict);
   162 		dm_player_t *player = DM_GetPlayer(client);
   163 		if (!player || !player->pEntity)
   164 		{
   165 			return;
   166 		}
   167 	
   168 		if (DM_IsPlayerAlive(client))
   169 		{
   170 			return;
   171 		}
   172 	
   173 		if (!player->will_respawn_on_class)
   174 		{
   175 			return;
   176 		}
   177 
   178 		player->will_respawn_on_class = false;
   179 
   180 		/* Respawn! */
   181 		DM_SchedRespawn(client);
   182 	}
   183 }
   184 
   185 void OnClientDropWeapons(CBaseEntity *pEntity)
   186 {
   187 	if (g_IsRunning)
   188 	{
   189 		/* Block them from having a defuse kit so they don't drop it. */
   190 		DM_SetDefuseKit(pEntity, false);
   191 	}
   192 }
   193 
   194 void OnClientDroppedWeapon(CBaseEntity *pEntity, CBaseEntity *pWeapon)
   195 {
   196 	if (!g_IsRunning || !pWeapon || !DM_ShouldRemoveDrops())
   197 	{
   198 		return;
   199 	}
   200 
   201 	if (DM_AllowC4())
   202 	{
   203 		edict_t *pEdict = gameents->BaseEntityToEdict(pWeapon);
   204 		if (pEdict && strcmp(pEdict->GetClassName(), "weapon_c4") == 0)
   205 		{
   206 			return;
   207 		}
   208 	}
   209 
   210 	DM_RemoveEntity(pWeapon);
   211 }
   212 
   213 #define IMPLEMENT_EVENT(name) \
   214 	cls_event_##name g_cls_event_##name; \
   215 	void cls_event_##name::FireGameEvent(IGameEvent *event)
   216 
   217 IMPLEMENT_EVENT(player_death)
   218 {
   219 	if (!g_IsRunning)
   220 	{
   221 		return;
   222 	}
   223 
   224 	int userid = event->GetInt("userid");
   225 
   226 	int client = playerhelpers->GetClientOfUserId(userid);
   227 	if (!client)
   228 	{
   229 		return;
   230 	}
   231 
   232 	dm_player_t *player = DM_GetPlayer(client);
   233 	if (!player)
   234 	{
   235 		return;
   236 	}
   237 
   238 	player->is_spawned = false;
   239 
   240 	/* Remove ragdoll */
   241 	unsigned int ragdollTime = DM_GetBodyStayTime();
   242 	if (ragdollTime <= 20 && !g_InRoundRestart)
   243 	{
   244 		int serial;
   245 		CBaseEntity *ragdoll = DM_GetAndClearRagdoll(player->pEntity, serial);
   246 		if (ragdollTime == 0)
   247 		{
   248 			DM_RemoveEntity(ragdoll);
   249 		} else {
   250 			edict_t *pEdict = gameents->BaseEntityToEdict(ragdoll);
   251 			if (pEdict)
   252 			{
   253 				int index = gamehelpers->IndexOfEdict(pEdict);
   254 				IDataPack *pack = g_pSM->CreateDataPack();
   255 				pack->PackCell(index);
   256 				pack->PackCell(serial);
   257 				ITimer *timer = timersys->CreateTimer(&s_RagdollRemover, ragdollTime, pack, 0);
   258 				g_RagdollTimers.push_back(timer);
   259 			}
   260 		}
   261 	}
   262 
   263 	if (!DM_OnClientDeath(client))
   264 	{
   265 		return;
   266 	}
   267 
   268 	DM_SchedRespawn(client);
   269 }
   270 
   271 IMPLEMENT_EVENT(player_team)
   272 {
   273 	if (!g_IsRunning)
   274 	{
   275 		return;
   276 	}
   277 
   278 	int userid = event->GetInt("userid");
   279 	int client = playerhelpers->GetClientOfUserId(userid);
   280 	if (!client)
   281 	{
   282 		return;
   283 	}
   284 
   285 	dm_player_t *player = DM_GetPlayer(client);
   286 	if (!player || !player->pEntity)
   287 	{
   288 		return;
   289 	}
   290 
   291 	if (DM_IsPlayerAlive(client) || event->GetBool("disconnect"))
   292 	{
   293 		return;
   294 	}
   295 
   296 	int old_team = event->GetInt("oldteam");
   297 	if (old_team == CS_TEAM_T || old_team == CS_TEAM_CT)
   298 	{
   299 		return;
   300 	}
   301 
   302 	int new_team = event->GetInt("team");
   303 	if (new_team != CS_TEAM_T && new_team != CS_TEAM_CT)
   304 	{
   305 		return;
   306 	}
   307 
   308 	if (player->pBot)
   309 	{
   310 		DM_SchedRespawn(client);
   311 	} else {
   312 		player->will_respawn_on_class = true;
   313 	}
   314 }
   315 
   316 IMPLEMENT_EVENT(player_spawn)
   317 {
   318 	if (!g_IsRunning)
   319 	{
   320 		return;
   321 	}
   322 
   323 	int userid = event->GetInt("userid");
   324 	int client = playerhelpers->GetClientOfUserId(userid);
   325 	if (!client)
   326 	{
   327 		return;
   328 	}
   329 
   330 	dm_player_t *player = DM_GetPlayer(client);
   331 	if (!player || !player->pEntity || (player->is_spawned && !g_InRoundRestart))
   332 	{
   333 		return;
   334 	}
   335 
   336 	/* This can be fired before a player gets a team! */
   337 	int team_idx = player->pInfo->GetTeamIndex();
   338 	if (team_idx != CS_TEAM_T
   339 		&& team_idx != CS_TEAM_CT)
   340 	{
   341 		return;
   342 	}
   343 
   344 	bool old_value = player->is_spawned;
   345 	player->is_spawned = true;
   346 
   347 	/* If we were waiting to respawn, cancel the timer */
   348 	if (player->respawn_timer && !player->pBot)
   349 	{
   350 		timersys->KillTimer(player->respawn_timer);
   351 		player->respawn_timer = NULL;
   352 	}
   353 
   354 	DM_OnClientSpawned(client, old_value);
   355 }
   356 
   357 IMPLEMENT_EVENT(server_shutdown)
   358 {
   359 	g_IsInGlobalShutdown = true;
   360 }
   361 
   362 IMPLEMENT_EVENT(round_start)
   363 {
   364 	g_InRoundRestart = false;
   365 }
   366 
   367 IMPLEMENT_EVENT(round_end)
   368 {
   369 	g_InRoundRestart = true;
   370 
   371 	DM_ClearRagdollTimers();
   372 
   373 	for (int i=1; i<=gpGlobals->maxClients; i++)
   374 	{
   375 		dm_player_t *player = DM_GetPlayer(i);
   376 		player->is_spawned = false;
   377 	}
   378 }
   379 
   380 IMPLEMENT_EVENT(item_pickup)
   381 {
   382 	if (!g_IsRunning || DM_AllowC4())
   383 	{
   384 		return;
   385 	}
   386 
   387 	const char *weapon = event->GetString("item");
   388 	if (strcmp(weapon, "c4") != 0)
   389 	{
   390 		return;
   391 	}
   392 
   393 	int userid = event->GetInt("userid");
   394 	int client = playerhelpers->GetClientOfUserId(userid);
   395 	if (!client)
   396 	{
   397 		return;
   398 	}
   399 
   400 	dm_player_t *player = DM_GetPlayer(client);
   401 	if (!player || !player->pEntity)
   402 	{
   403 		return;
   404 	}
   405 
   406 	CBaseEntity *pWeapon = DM_GetWeaponFromSlot(player->pEntity, (int)WeaponType_C4);
   407 	if (pWeapon)
   408 	{
   409 		DM_DropWeapon(player->pEntity, pWeapon);
   410 	}
   411 }
   412