added amb416 - SlapPlayer()

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401175
This commit is contained in:
David Anderson 2007-07-25 20:23:34 +00:00
parent c36a203276
commit 78d054e077
9 changed files with 440 additions and 2 deletions

View File

@ -24,6 +24,7 @@
#include "extension.h" #include "extension.h"
#include "vcallbuilder.h" #include "vcallbuilder.h"
#include "vnatives.h" #include "vnatives.h"
#include "vhelpers.h"
#include "tempents.h" #include "tempents.h"
#include "gamerules.h" #include "gamerules.h"
@ -37,6 +38,7 @@ IServerGameEnts *gameents = NULL;
IEngineTrace *enginetrace = NULL; IEngineTrace *enginetrace = NULL;
IEngineSound *engsound = NULL; IEngineSound *engsound = NULL;
INetworkStringTableContainer *netstringtables = NULL; INetworkStringTableContainer *netstringtables = NULL;
IServerPluginHelpers *pluginhelpers = NULL;
IBinTools *g_pBinTools = NULL; IBinTools *g_pBinTools = NULL;
IGameConfig *g_pGameConf = NULL; IGameConfig *g_pGameConf = NULL;
IGameHelpers *g_pGameHelpers = NULL; IGameHelpers *g_pGameHelpers = NULL;
@ -99,6 +101,7 @@ void SDKTools::SDK_OnUnload()
delete (*iter); delete (*iter);
} }
g_RegCalls.clear(); g_RegCalls.clear();
ShutdownHelpers();
g_TEManager.Shutdown(); g_TEManager.Shutdown();
@ -111,6 +114,7 @@ bool SDKTools::SDK_OnMetamodLoad(ISmmAPI *ismm, char *error, size_t maxlen, bool
GET_V_IFACE_ANY(engineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION); GET_V_IFACE_ANY(engineFactory, engsound, IEngineSound, IENGINESOUND_SERVER_INTERFACE_VERSION);
GET_V_IFACE_ANY(engineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER); GET_V_IFACE_ANY(engineFactory, enginetrace, IEngineTrace, INTERFACEVERSION_ENGINETRACE_SERVER);
GET_V_IFACE_ANY(engineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER); GET_V_IFACE_ANY(engineFactory, netstringtables, INetworkStringTableContainer, INTERFACENAME_NETWORKSTRINGTABLESERVER);
GET_V_IFACE_ANY(engineFactory, pluginhelpers, IServerPluginHelpers, INTERFACEVERSION_ISERVERPLUGINHELPERS);
return true; return true;
} }
@ -150,6 +154,7 @@ void SDKTools::NotifyInterfaceDrop(SMInterface *pInterface)
delete (*iter); delete (*iter);
} }
g_RegCalls.clear(); g_RegCalls.clear();
ShutdownHelpers();
g_TEManager.Shutdown(); g_TEManager.Shutdown();
} }

View File

@ -71,6 +71,7 @@ extern IServerGameEnts *gameents;
extern IEngineTrace *enginetrace; extern IEngineTrace *enginetrace;
extern IEngineSound *engsound; extern IEngineSound *engsound;
extern INetworkStringTableContainer *netstringtables; extern INetworkStringTableContainer *netstringtables;
extern IServerPluginHelpers *pluginhelpers;
/* Interfaces from SourceMod */ /* Interfaces from SourceMod */
extern IBinTools *g_pBinTools; extern IBinTools *g_pBinTools;
extern IGameConfig *g_pGameConf; extern IGameConfig *g_pGameConf;

View File

@ -215,6 +215,10 @@
RelativePath="..\vdecoder.cpp" RelativePath="..\vdecoder.cpp"
> >
</File> </File>
<File
RelativePath="..\vhelpers.cpp"
>
</File>
<File <File
RelativePath="..\vnatives.cpp" RelativePath="..\vnatives.cpp"
> >
@ -257,6 +261,10 @@
RelativePath="..\vdecoder.h" RelativePath="..\vdecoder.h"
> >
</File> </File>
<File
RelativePath="..\vhelpers.h"
>
</File>
<File <File
RelativePath="..\vnatives.h" RelativePath="..\vnatives.h"
> >

View File

@ -54,7 +54,7 @@
//#define SMEXT_ENABLE_DBMANAGER //#define SMEXT_ENABLE_DBMANAGER
#define SMEXT_ENABLE_GAMECONF #define SMEXT_ENABLE_GAMECONF
#define SMEXT_ENABLE_MEMUTILS #define SMEXT_ENABLE_MEMUTILS
//#define SMEXT_ENABLE_GAMEHELPERS #define SMEXT_ENABLE_GAMEHELPERS
//#define SMEXT_ENABLE_TIMERSYS //#define SMEXT_ENABLE_TIMERSYS
#define SMEXT_ENABLE_ADTFACTORY #define SMEXT_ENABLE_ADTFACTORY

View File

@ -0,0 +1,128 @@
/**
* vim: set ts=4 :
* ===============================================================
* SourceMod SDK Tools Extension
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ===============================================================
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Version: $Id$
*/
#include "extension.h"
#include "vhelpers.h"
CallHelper s_Teleport;
CallHelper s_GetVelocity;
bool SetupTeleport()
{
if (s_Teleport.setup)
{
return s_Teleport.supported;
}
/* Setup Teleport */
int offset;
if (g_pGameConf->GetOffset("Teleport", &offset))
{
PassInfo info[3];
info[0].flags = info[1].flags = info[2].flags = PASSFLAG_BYVAL;
info[0].size = info[1].size = info[2].size = sizeof(void *);
info[0].type = info[1].type = info[2].type = PassType_Basic;
s_Teleport.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 3);
if (s_Teleport.call)
{
s_Teleport.supported = true;
}
}
s_Teleport.setup = true;
return s_Teleport.supported;
}
void Teleport(CBaseEntity *pEntity, Vector *origin, QAngle *ang, Vector *velocity)
{
unsigned char params[sizeof(void *) * 4];
unsigned char *vptr = params;
*(CBaseEntity **)vptr = pEntity;
vptr += sizeof(CBaseEntity *);
*(Vector **)vptr = origin;
vptr += sizeof(Vector *);
*(QAngle **)vptr = ang;
vptr += sizeof(QAngle *);
*(Vector **)vptr = velocity;
s_Teleport.call->Execute(params, NULL);
}
bool IsTeleportSupported()
{
return SetupTeleport();
}
bool SetupGetVelocity()
{
if (s_GetVelocity.setup)
{
return s_GetVelocity.supported;
}
int offset;
if (g_pGameConf->GetOffset("GetVelocity", &offset))
{
PassInfo info[2];
info[0].flags = info[1].flags = PASSFLAG_BYVAL;
info[0].size = info[1].size = sizeof(void *);
info[0].type = info[1].type = PassType_Basic;
s_GetVelocity.call = g_pBinTools->CreateVCall(offset, 0, 0, NULL, info, 2);
if (s_GetVelocity.call)
{
s_GetVelocity.supported = true;
}
}
s_GetVelocity.setup = true;
return s_GetVelocity.supported;
}
void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity)
{
unsigned char params[sizeof(void *) * 3];
unsigned char *vptr = params;
*(CBaseEntity **)vptr = pEntity;
vptr += sizeof(CBaseEntity *);
*(Vector **)vptr = velocity;
vptr += sizeof(Vector *);
*(AngularImpulse **)vptr = angvelocity;
s_GetVelocity.call->Execute(params, NULL);
}
bool IsGetVelocitySupported()
{
return SetupGetVelocity();
}
void ShutdownHelpers()
{
s_Teleport.Shutdown();
s_GetVelocity.Shutdown();
}

View File

@ -0,0 +1,60 @@
/**
* vim: set ts=4 :
* ===============================================================
* SourceMod SDK Tools Extension
* Copyright (C) 2004-2007 AlliedModders LLC. All rights reserved.
* ===============================================================
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* Version: $Id$
*/
#ifndef _INCLUDE_SDKTOOLS_VHELPERS_H_
#define _INCLUDE_SDKTOOLS_VHELPERS_H_
#include <sh_list.h>
#include <eiface.h>
#include <IBinTools.h>
using namespace SourceMod;
struct CallHelper
{
CallHelper() : call(NULL), supported(false), setup(false)
{
}
void Shutdown()
{
if (call)
{
call->Destroy();
call = NULL;
supported = false;
}
}
ICallWrapper *call;
bool supported;
bool setup;
};
void Teleport(CBaseEntity *pEntity, Vector *origin, QAngle *ang, Vector *velocity);
bool IsTeleportSupported();
void GetVelocity(CBaseEntity *pEntity, Vector *velocity, AngularImpulse *angvelocity);
bool IsGetVelocitySupported();
void ShutdownHelpers();
#endif //_INCLUDE_SDKTOOLS_VHELPERS_H_

View File

@ -21,12 +21,16 @@
* Version: $Id$ * Version: $Id$
*/ */
#include <stdlib.h>
#include <sh_string.h> #include <sh_string.h>
#include "extension.h" #include "extension.h"
#include "vcallbuilder.h" #include "vcallbuilder.h"
#include "vnatives.h" #include "vnatives.h"
#include "vhelpers.h"
#include "CellRecipientFilter.h"
List<ValveCall *> g_RegCalls; List<ValveCall *> g_RegCalls;
List<ICallWrapper *> g_CallWraps;
inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0) inline void InitPass(ValvePassInfo &info, ValveType vtype, PassType type, unsigned int flags, unsigned int decflags=0)
{ {
@ -347,6 +351,157 @@ static cell_t SetLightStyle(IPluginContext *pContext, const cell_t *params)
return 1; return 1;
} }
static cell_t SlapPlayer(IPluginContext *pContext, const cell_t *params)
{
static bool s_slap_supported = false;
static bool s_slap_setup = false;
static ICallWrapper *s_teleport = NULL;
static int s_health_offs = NULL;
static int s_sound_count = 0;
static int s_frag_offs = 0;
if (!s_slap_setup)
{
int tries = 0;
s_slap_setup = true;
if (IsTeleportSupported())
{
tries++;
}
if (IsGetVelocitySupported())
{
tries++;
}
/* Setup health */
if (g_pGameConf->GetOffset("m_iHealth", &s_health_offs) && s_health_offs)
{
tries++;
}
if (tries == 3)
{
s_slap_supported = true;
const char *key;
if ((key = g_pGameConf->GetKeyValue("SlapSoundCount")) != NULL)
{
s_sound_count = atoi(key);
}
}
}
if (!s_slap_supported)
{
return pContext->ThrowNativeError("This function is not supported on this mod");
}
/* First check if the client is valid */
int client = params[1];
IGamePlayer *player = playerhelpers->GetGamePlayer(client);
if (!player)
{
return pContext->ThrowNativeError("Client %d is not valid", client);
} else if (!player->IsInGame()) {
return pContext->ThrowNativeError("Client %d is not in game", client);
}
edict_t *pEdict = player->GetEdict();
CBaseEntity *pEntity = pEdict->GetUnknown()->GetBaseEntity();
/* See if we should be taking away health */
bool should_slay = false;
if (params[2])
{
int *health = (int *)((char *)pEntity + s_health_offs);
if (*health - params[2] <= 0)
{
*health = 1;
should_slay = true;
} else {
*health -= params[2];
}
}
/* Teleport in a random direction - thank you, Mani!*/
Vector velocity;
GetVelocity(pEntity, &velocity, NULL);
velocity.x += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1);
velocity.y += ((rand() % 180) + 50) * (((rand() % 2) == 1) ? -1 : 1);
velocity.z += rand() % 200 + 100;
Teleport(pEntity, NULL, NULL, &velocity);
/* Play a random sound */
if (params[3] && s_sound_count > 0)
{
char name[48];
const char *sound_name;
cell_t player_list[256], total_players = 0;
int maxClients = playerhelpers->GetMaxClients();
int r = (rand() % s_sound_count) + 1;
snprintf(name, sizeof(name), "SlapSound%d", r);
if ((sound_name = g_pGameConf->GetKeyValue(name)) != NULL)
{
IGamePlayer *other;
for (int i=1; i<=maxClients; i++)
{
other = playerhelpers->GetGamePlayer(i);
if (other->IsInGame())
{
player_list[total_players++] = i;
}
}
const Vector & pos = pEdict->GetCollideable()->GetCollisionOrigin();
CellRecipientFilter rf;
rf.SetToReliable(true);
rf.Initialize(player_list, total_players);
engsound->EmitSound(rf, client, CHAN_AUTO, sound_name, VOL_NORM, ATTN_NORM, 0, PITCH_NORM, &pos);
}
}
if (!s_frag_offs)
{
const char *frag_prop = g_pGameConf->GetKeyValue("m_iFrags");
if (frag_prop)
{
datamap_t *pMap = gamehelpers->GetDataMap(pEntity);
typedescription_t *pType = gamehelpers->FindInDataMap(pMap, frag_prop);
if (pType != NULL)
{
s_frag_offs = pType->fieldOffset[TD_OFFSET_NORMAL];
}
}
if (!s_frag_offs)
{
s_frag_offs = -1;
}
}
int old_frags = 0;
if (s_frag_offs > 0)
{
old_frags = *(int *)((char *)pEntity + s_frag_offs);
}
/* Force suicide */
if (should_slay)
{
pluginhelpers->ClientCommand(pEdict, "kill\n");
}
if (s_frag_offs > 0)
{
*(int *)((char *)pEntity + s_frag_offs) = old_frags;
}
return 1;
}
sp_nativeinfo_t g_Natives[] = sp_nativeinfo_t g_Natives[] =
{ {
{"ExtinguishPlayer", ExtinguishPlayer}, {"ExtinguishPlayer", ExtinguishPlayer},
@ -361,6 +516,7 @@ sp_nativeinfo_t g_Natives[] =
{"TeleportEntity", TeleportPlayer}, {"TeleportEntity", TeleportPlayer},
{"SetClientViewEntity", SetClientViewEntity}, {"SetClientViewEntity", SetClientViewEntity},
{"SetLightStyle", SetLightStyle}, {"SetLightStyle", SetLightStyle},
{"SlapPlayer", SlapPlayer},
{NULL, NULL}, {NULL, NULL},
}; };

View File

@ -1,5 +1,26 @@
"Games" "Games"
{ {
/* Sounds */
"#default"
{
"Keys"
{
"SlapSoundCount" "3"
"SlapSound1" "player/pl_fallpain1.wav"
"SlapSound2" "player/pl_fallpain3.wav"
"SlapSound3" "player/pl_pain5.wav"
"m_iFrags" "m_iFrags"
}
"Offsets"
{
"m_iHealth"
{
"class" "CBasePlayer"
"prop" "m_iHealth"
}
}
}
/* General Temp Entities */ /* General Temp Entities */
"#default" "#default"
{ {
@ -102,6 +123,14 @@
/* Counter-Strike: Source */ /* Counter-Strike: Source */
"cstrike" "cstrike"
{ {
"Keys"
{
"SlapSoundCount" "3"
"SlapSound1" "player/damage1.wav"
"SlapSound2" "player/damage2.wav"
"SlapSound3" "player/damage3.wav"
}
"Offsets" "Offsets"
{ {
"GiveNamedItem" "GiveNamedItem"
@ -139,6 +168,11 @@
"windows" "357" "windows" "357"
"linux" "358" "linux" "358"
} }
"GetVelocity"
{
"windows" "126"
"linux" "127"
}
} }
} }
@ -182,6 +216,11 @@
"windows" "356" "windows" "356"
"linux" "357" "linux" "357"
} }
"GetVelocity"
{
"windows" "126"
"linux" "127"
}
} }
} }
@ -225,6 +264,11 @@
"windows" "356" "windows" "356"
"linux" "357" "linux" "357"
} }
"GetVelocity"
{
"windows" "126"
"linux" "127"
}
} }
} }
@ -269,6 +313,11 @@
"windows" "343" "windows" "343"
"linux" "344" "linux" "344"
} }
"GetVelocity"
{
"windows" "124"
"linux" "125"
}
/* Temp Entities */ /* Temp Entities */
"TE_GetServerClass" "TE_GetServerClass"
@ -321,6 +370,11 @@
"windows" "360" "windows" "360"
"linux" "361" "linux" "361"
} }
"GetVelocity"
{
"windows" "128"
"linux" "129"
}
/* Offset into CBaseTempEntity constructor. /* Offset into CBaseTempEntity constructor.
* On Windows Dsytopia is heavily inlined; we use the function * On Windows Dsytopia is heavily inlined; we use the function
@ -379,6 +433,11 @@
"windows" "90" "windows" "90"
"linux" "91" "linux" "91"
} }
"GetVelocity"
{
"windows" "115"
"linux" "116"
}
/* Temp Entities */ /* Temp Entities */
"s_pTempEntities" "s_pTempEntities"
@ -429,6 +488,11 @@
"windows" "356" "windows" "356"
"linux" "357" "linux" "357"
} }
"GetVelocity"
{
"windows" "126"
"linux" "127"
}
/* Temp Entities */ /* Temp Entities */
"s_pTempEntities" "s_pTempEntities"
@ -474,6 +538,11 @@
"windows" "90" "windows" "90"
"linux" "91" "linux" "91"
} }
"GetVelocity"
{
"windows" "114"
"linux" "115"
}
/* Temp Entities */ /* Temp Entities */
"s_pTempEntities" "s_pTempEntities"

View File

@ -89,10 +89,21 @@ native TeleportEntity(entity, const Float:origin[3], const Float:angles[3], cons
* *
* @param client Client index. * @param client Client index.
* @noreturn * @noreturn
* @error Invalid entity or client not in game, or lack of mod support. * @error Invalid client or client not in game, or lack of mod support.
*/ */
native ForcePlayerSuicide(client); native ForcePlayerSuicide(client);
/**
* Slaps a player in a random direction.
*
* @param client Client index.
* @param health Health to subtract.
* @param sound False to disable the sound effects.
* @noreturn
* @error Invalid client or client not in game, or lack of mod support.
*/
native SlapPlayer(client, health=5, bool:sound=true);
/** /**
* @deprecated * @deprecated
*/ */