From b50d7697f6d72c70c6fde2eb5f3b8a8fe8cc4913 Mon Sep 17 00:00:00 2001 From: Borja Ferrer Date: Fri, 28 Sep 2007 19:56:19 +0000 Subject: [PATCH] added amb753, entity input native --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%401504 --- extensions/sdktools/extension.cpp | 14 ++ extensions/sdktools/extension.h | 2 + extensions/sdktools/inputnatives.cpp | 288 ++++++++++++++++++++++ extensions/sdktools/msvc8/sdktools.vcproj | 4 + extensions/sdktools/vdecoder.cpp | 8 +- gamedata/sdktools.games.txt | 30 +++ plugins/include/sdktools.inc | 1 + plugins/include/sdktools_entinput.inc | 116 +++++++++ 8 files changed, 459 insertions(+), 4 deletions(-) create mode 100644 extensions/sdktools/inputnatives.cpp create mode 100644 plugins/include/sdktools_entinput.inc diff --git a/extensions/sdktools/extension.cpp b/extensions/sdktools/extension.cpp index 91bcc762..b0d28a95 100644 --- a/extensions/sdktools/extension.cpp +++ b/extensions/sdktools/extension.cpp @@ -65,6 +65,7 @@ extern sp_nativeinfo_t g_TENatives[]; extern sp_nativeinfo_t g_TRNatives[]; extern sp_nativeinfo_t g_StringTableNatives[]; extern sp_nativeinfo_t g_VoiceNatives[]; +extern sp_nativeinfo_t g_EntInputNatives[]; bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late) { @@ -76,6 +77,7 @@ bool SDKTools::SDK_OnLoad(char *error, size_t maxlength, bool late) sharesys->AddNatives(myself, g_TRNatives); sharesys->AddNatives(myself, g_StringTableNatives); sharesys->AddNatives(myself, g_VoiceNatives); + sharesys->AddNatives(myself, g_EntInputNatives); SM_GET_IFACE(GAMEHELPERS, g_pGameHelpers); @@ -119,6 +121,12 @@ void SDKTools::SDK_OnUnload() g_RegCalls.clear(); ShutdownHelpers(); + if (g_pAcceptInput) + { + g_pAcceptInput->Destroy(); + g_pAcceptInput = NULL; + } + g_TEManager.Shutdown(); s_TempEntHooks.Shutdown(); @@ -182,6 +190,12 @@ void SDKTools::NotifyInterfaceDrop(SMInterface *pInterface) g_TEManager.Shutdown(); s_TempEntHooks.Shutdown(); + + if (g_pAcceptInput) + { + g_pAcceptInput->Destroy(); + g_pAcceptInput = NULL; + } } bool SDKTools::RegisterConCommandBase(ConCommandBase *pVar) diff --git a/extensions/sdktools/extension.h b/extensions/sdktools/extension.h index fa4b6574..bc762fa3 100644 --- a/extensions/sdktools/extension.h +++ b/extensions/sdktools/extension.h @@ -100,5 +100,7 @@ extern IGameHelpers *g_pGameHelpers; /* Handle types */ extern HandleType_t g_CallHandle; extern HandleType_t g_TraceHandle; +/* Call Wrappers */ +extern ICallWrapper *g_pAcceptInput; #endif //_INCLUDE_SOURCEMOD_EXTENSION_PROPER_H_ diff --git a/extensions/sdktools/inputnatives.cpp b/extensions/sdktools/inputnatives.cpp new file mode 100644 index 00000000..28aeba21 --- /dev/null +++ b/extensions/sdktools/inputnatives.cpp @@ -0,0 +1,288 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod SDKTools 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, version 3.0, as published by the + * Free Software Foundation. + * + * 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, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#include "extension.h" +#include + +#define SIZEOF_VARIANT_T 20 + +ICallWrapper *g_pAcceptInput = NULL; +unsigned char g_Variant_t[SIZEOF_VARIANT_T] = {0}; + +#define ENTINDEX_TO_CBASEENTITY(index, buffer) \ + pEdict = engine->PEntityOfEntIndex(index); \ + if (!pEdict || pEdict->IsFree()) \ + { \ + return pContext->ThrowNativeError("Entity %d is not valid or is freed", index); \ + } \ + pUnk = pEdict->GetUnknown(); \ + if (!pUnk) \ + { \ + return pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", index); \ + } \ + buffer = pUnk->GetBaseEntity(); \ + if (!buffer) \ + { \ + return pContext->ThrowNativeError("Entity %d is not a CBaseEntity", index); \ + } + +/* Hack to init the variant_t object for the first time */ +class VariantFirstTimeInit +{ +public: + VariantFirstTimeInit() + { + *(unsigned int *)(&g_Variant_t[12]) = INVALID_EHANDLE_INDEX; + } +} g_VariantFirstTimeInit; + +inline void _init_variant_t() +{ + unsigned char *vptr = g_Variant_t; + + *(int *)vptr = 0; + vptr += sizeof(int)*3; + *(unsigned long *)vptr = INVALID_EHANDLE_INDEX; + vptr += sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_VOID; +} + +static cell_t AcceptEntityInput(IPluginContext *pContext, const cell_t *params) +{ + if (!g_pAcceptInput) + { + int offset; + if (!g_pGameConf->GetOffset("AcceptInput", &offset)) + { + return pContext->ThrowNativeError("\"AcceptEntityInput\" not supported by this mod"); + } + + PassInfo pass[6]; + pass[0].type = PassType_Basic; + pass[0].flags = PASSFLAG_BYVAL; + pass[0].size = sizeof(const char *); + pass[1].type = pass[2].type = PassType_Basic; + pass[1].flags = pass[2].flags = PASSFLAG_BYVAL; + pass[1].size = pass[2].size = sizeof(CBaseEntity *); + pass[3].type = PassType_Object; + pass[3].flags = PASSFLAG_BYVAL|PASSFLAG_OCTOR|PASSFLAG_ODTOR; + pass[3].size = SIZEOF_VARIANT_T; + pass[4].type = PassType_Basic; + pass[4].flags = PASSFLAG_BYVAL; + pass[4].size = sizeof(int); + pass[5].type = PassType_Basic; + pass[5].flags = PASSFLAG_BYVAL; + pass[5].size = sizeof(bool); + + if (!(g_pAcceptInput=g_pBinTools->CreateVCall(offset, 0, 0, &pass[5], pass, 5))) + { + pContext->ThrowNativeError("\"AcceptEntityInput\" wrapper failed to initialized"); + } + } + + CBaseEntity *pActivator, *pCaller, *pDest; + edict_t *pEdict; + IServerUnknown *pUnk; + + char *inputname; + unsigned char vstk[sizeof(void *) + sizeof(const char *) + sizeof(CBaseEntity *)*2 + SIZEOF_VARIANT_T + sizeof(int)]; + unsigned char *vptr = vstk; + + ENTINDEX_TO_CBASEENTITY(params[1], pDest); + pContext->LocalToString(params[2], &inputname); + if (params[3] == -1) + { + pActivator = NULL; + } else { + ENTINDEX_TO_CBASEENTITY(params[3], pActivator); + } + if (params[4] == -1) + { + pCaller = NULL; + } else { + ENTINDEX_TO_CBASEENTITY(params[4], pCaller); + } + + *(void **)vptr = pDest; + vptr += sizeof(void *); + *(const char **)vptr = inputname; + vptr += sizeof(const char *); + *(CBaseEntity **)vptr = pActivator; + vptr += sizeof(CBaseEntity *); + *(CBaseEntity **)vptr = pCaller; + vptr += sizeof(CBaseEntity *); + memcpy(vptr, g_Variant_t, SIZEOF_VARIANT_T); + vptr += SIZEOF_VARIANT_T; + *(int *)vptr = params[5]; + + bool ret; + g_pAcceptInput->Execute(vstk, &ret); + + _init_variant_t(); + + return (ret) ? 1 : 0; +} + +static cell_t SetVariantBool(IPluginContext *pContext, const cell_t *params) +{ + unsigned char *vptr = g_Variant_t; + + *(bool *)vptr = (params[1]) ? true : false; + vptr += sizeof(int)*3 + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_BOOLEAN; + + return 1; +} + +static cell_t SetVariantString(IPluginContext *pContext, const cell_t *params) +{ + char *str; + unsigned char *vptr = g_Variant_t; + + pContext->LocalToString(params[1], &str); + + *(string_t *)vptr = MAKE_STRING(str); + vptr += sizeof(int)*3 + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_STRING; + + return 1; +} + +static cell_t SetVariantInt(IPluginContext *pContext, const cell_t *params) +{ + unsigned char *vptr = g_Variant_t; + + *(int *)vptr = params[1]; + vptr += sizeof(int)*3 + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_INTEGER; + + return 1; +} + +static cell_t SetVariantFloat(IPluginContext *pContext, const cell_t *params) +{ + unsigned char *vptr = g_Variant_t; + + *(float *)vptr = sp_ctof(params[1]); + vptr += sizeof(int)*3 + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_FLOAT; + + return 1; +} + +static cell_t SetVariantVector3D(IPluginContext *pContext, const cell_t *params) +{ + cell_t *val; + unsigned char *vptr = g_Variant_t; + + pContext->LocalToPhysAddr(params[1], &val); + + *(float *)vptr = sp_ctof(val[0]); + vptr += sizeof(float); + *(float *)vptr = sp_ctof(val[1]); + vptr += sizeof(float); + *(float *)vptr = sp_ctof(val[2]); + vptr += sizeof(float) + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_VECTOR; + + return 1; +} + +static cell_t SetVariantPosVector3D(IPluginContext *pContext, const cell_t *params) +{ + cell_t *val; + unsigned char *vptr = g_Variant_t; + + pContext->LocalToPhysAddr(params[1], &val); + + *(float *)vptr = sp_ctof(val[0]); + vptr += sizeof(float); + *(float *)vptr = sp_ctof(val[1]); + vptr += sizeof(float); + *(float *)vptr = sp_ctof(val[2]); + vptr += sizeof(float) + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_POSITION_VECTOR; + + return 1; +} + +static cell_t SetVariantColor(IPluginContext *pContext, const cell_t *params) +{ + cell_t *val; + unsigned char *vptr = g_Variant_t; + + pContext->LocalToPhysAddr(params[1], &val); + + *(unsigned char *)vptr = val[0]; + vptr += sizeof(unsigned char); + *(unsigned char *)vptr = val[1]; + vptr += sizeof(unsigned char); + *(unsigned char *)vptr = val[2]; + vptr += sizeof(unsigned char); + *(unsigned char *)vptr = val[3]; + vptr += sizeof(unsigned char) + sizeof(int)*2 + sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_COLOR32; + + return 1; +} + +static cell_t SetVariantEntity(IPluginContext *pContext, const cell_t *params) +{ + CBaseEntity *pEntity; + edict_t *pEdict; + IServerUnknown *pUnk; + unsigned char *vptr = g_Variant_t; + CBaseHandle bHandle; + + ENTINDEX_TO_CBASEENTITY(params[1], pEntity); + bHandle = reinterpret_cast(pEntity)->GetRefEHandle(); + + vptr += sizeof(int)*3; + *(unsigned long *)vptr = (unsigned long)(bHandle.ToInt()); + vptr += sizeof(unsigned long); + *(fieldtype_t *)vptr = FIELD_EHANDLE; + + return 1; +} + +sp_nativeinfo_t g_EntInputNatives[] = +{ + {"AcceptEntityInput", AcceptEntityInput}, + {"SetVariantBool", SetVariantBool}, + {"SetVariantString", SetVariantString}, + {"SetVariantInt", SetVariantInt}, + {"SetVariantFloat", SetVariantFloat}, + {"SetVariantVector3D", SetVariantVector3D}, + {"SetVariantPosVector3D", SetVariantPosVector3D}, + {"SetVariantColor", SetVariantColor}, + {"SetVariantEntity", SetVariantEntity}, + {NULL, NULL}, +}; diff --git a/extensions/sdktools/msvc8/sdktools.vcproj b/extensions/sdktools/msvc8/sdktools.vcproj index 4432d36c..8a9d4fe2 100644 --- a/extensions/sdktools/msvc8/sdktools.vcproj +++ b/extensions/sdktools/msvc8/sdktools.vcproj @@ -190,6 +190,10 @@ RelativePath="..\extension.cpp" > + + diff --git a/extensions/sdktools/vdecoder.cpp b/extensions/sdktools/vdecoder.cpp index b9866d0b..12bfaabb 100644 --- a/extensions/sdktools/vdecoder.cpp +++ b/extensions/sdktools/vdecoder.cpp @@ -430,13 +430,13 @@ DataStatus DecodeValveParam(IPluginContext *pContext, IServerUnknown *pUnknown = pEdict->GetUnknown(); if (!pUnknown) { - pContext->ThrowNativeError("Entity %d is a not an IServerUnknown"); + pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param); return Data_Fail; } pEntity = pUnknown->GetBaseEntity(); if (!pEntity) { - pContext->ThrowNativeError("Entity %d is not a CBaseEntity"); + pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param); return Data_Fail; } } @@ -498,13 +498,13 @@ DataStatus DecodeValveParam(IPluginContext *pContext, IServerUnknown *pUnknown = pEdict->GetUnknown(); if (!pUnknown) { - pContext->ThrowNativeError("Entity %d is a not an IServerUnknown"); + pContext->ThrowNativeError("Entity %d is a not an IServerUnknown", param); return Data_Fail; } pEntity = pUnknown->GetBaseEntity(); if (!pEntity) { - pContext->ThrowNativeError("Entity %d is not a CBaseEntity"); + pContext->ThrowNativeError("Entity %d is not a CBaseEntity", param); return Data_Fail; } } diff --git a/gamedata/sdktools.games.txt b/gamedata/sdktools.games.txt index 488fc748..3f5ee9d1 100644 --- a/gamedata/sdktools.games.txt +++ b/gamedata/sdktools.games.txt @@ -299,6 +299,11 @@ "windows" "118" "linux" "119" } + "AcceptInput" + { + "windows" "35" + "linux" "36" + } } } @@ -352,6 +357,11 @@ "windows" "118" "linux" "119" } + "AcceptInput" + { + "windows" "35" + "linux" "36" + } } } @@ -405,6 +415,11 @@ "windows" "118" "linux" "119" } + "AcceptInput" + { + "windows" "35" + "linux" "36" + } } } @@ -521,6 +536,11 @@ "windows" "120" "linux" "121" } + "AcceptInput" + { + "windows" "35" + "linux" "36" + } /* Offset into CBaseTempEntity constructor. * On Windows Dsytopia is heavily inlined; we use the function @@ -589,6 +609,11 @@ "windows" "107" "linux" "108" } + "AcceptInput" + { + "windows" "34" + "linux" "35" + } "s_pTempEntities" { "linux" "28" @@ -667,6 +692,11 @@ "windows" "118" "linux" "119" } + "AcceptInput" + { + "windows" "35" + "linux" "36" + } /* Temp Entities */ "s_pTempEntities" diff --git a/plugins/include/sdktools.inc b/plugins/include/sdktools.inc index 055cb03f..a4151ffc 100644 --- a/plugins/include/sdktools.inc +++ b/plugins/include/sdktools.inc @@ -46,6 +46,7 @@ #include #include #include +#include enum SDKCallType { diff --git a/plugins/include/sdktools_entinput.inc b/plugins/include/sdktools_entinput.inc new file mode 100644 index 00000000..fb161c35 --- /dev/null +++ b/plugins/include/sdktools_entinput.inc @@ -0,0 +1,116 @@ +/** + * vim: set ts=4 : + * ============================================================================= + * SourceMod (C)2004-2007 AlliedModders LLC. All rights reserved. + * ============================================================================= + * + * This file is part of the SourceMod/SourcePawn SDK. + * + * This program is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, version 3.0, as published by the + * Free Software Foundation. + * + * 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, see . + * + * As a special exception, AlliedModders LLC gives you permission to link the + * code of this program (as well as its derivative works) to "Half-Life 2," the + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software + * by the Valve Corporation. You must obey the GNU General Public License in + * all respects for all other code used. Additionally, AlliedModders LLC grants + * this exception to all derivative works. AlliedModders LLC defines further + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007), + * or . + * + * Version: $Id$ + */ + +#if defined _sdktools_entinput_included + #endinput +#endif +#define _sdktools_entinput_included + +/** + * Invokes a named input method on an entity. + * + * After completion (successful or not), the current global variant is re-initalized. + * + * @param dest Destination entity index. + * @param input Input action. + * @param activator Entity index which initiated the sequence of actions (-1 for a NULL entity). + * @param caller Entity index from which this event is sent (-1 for a NULL entity). + * @param outputid Unknown. + * @return True if successful otherwise false. + * @error Invalid entity index or no mod support. + */ +native bool:AcceptEntityInput(dest, const String:input[], activator=-1, caller=-1, outputid=0); + +/** + * Sets a bool value in the global variant object. + * + * @param val Input value. + * @noreturn + */ +native SetVariantBool(bool:val); + +/** + * Sets a string in the global variant object. + * + * @param str Input string. + * @noreturn + */ +native SetVariantString(const String:str[]); + +/** + * Sets an integer value in the global variant object. + * + * @param val Input value. + * @noreturn + */ +native SetVariantInt(val); + +/** + * Sets a floating point value in the global variant object. + * + * @param val Input value. + * @noreturn + */ +native SetVariantFloat(Float:val); + +/** + * Sets a 3D vector in the global variant object. + * + * @param vec Input vector. + * @noreturn + */ +native SetVariantVector3D(const Float:vec[3]); + +/** + * Sets a 3D position vector in the global variant object. + * + * @param vec Input position vector. + * @noreturn + */ +native SetVariantPosVector3D(const Float:vec[3]); + +/** + * Sets a color in the global variant object. + * + * @param color Input color. + * @noreturn + */ +native SetVariantColor(const color[4]); + +/** + * Sets an entity in the global variant object. + * + * @param Entity index. + * @noreturn + * @error Invalid entity index. + */ +native SetVariantEntity(entity);