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