diff --git a/extensions/tf2/natives.cpp b/extensions/tf2/natives.cpp index 076c0b92..29aed779 100644 --- a/extensions/tf2/natives.cpp +++ b/extensions/tf2/natives.cpp @@ -143,18 +143,21 @@ cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params) { static ICallWrapper *pWrapper = NULL; - //CTFPlayerShared::Disguise(int, int) + //CTFPlayerShared::Disguise(int, int, CTFPlayer *) if (!pWrapper) { REGISTER_NATIVE_ADDR("Disguise", - PassInfo pass[2]; \ + PassInfo pass[3]; \ pass[0].flags = PASSFLAG_BYVAL; \ pass[0].size = sizeof(int); \ pass[0].type = PassType_Basic; \ pass[1].flags = PASSFLAG_BYVAL; \ pass[1].size = sizeof(int); \ pass[1].type = PassType_Basic; \ - pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 2)) + pass[2].flags = PASSFLAG_BYVAL; \ + pass[2].size = sizeof(CBaseEntity *); \ + pass[2].type = PassType_Basic; \ + pWrapper = g_pBinTools->CreateCall(addr, CallConv_ThisCall, NULL, pass, 3)) } CBaseEntity *pEntity; @@ -164,6 +167,13 @@ cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params) } void *obj = (void *)((uint8_t *)pEntity + playerSharedOffset->actual_offset); + + CBaseEntity *pTarget = NULL; + // Compatibility fix for the newly-added target parameter + if (params[0] >= 4 && params[4] > 0 && !(pTarget = UTIL_GetCBaseEntity(params[4], true))) + { + return pContext->ThrowNativeError("Target client index %d is not valid", params[1]); + } unsigned char vstk[sizeof(void *) + 2*sizeof(int)]; unsigned char *vptr = vstk; @@ -174,6 +184,8 @@ cell_t TF2_Disguise(IPluginContext *pContext, const cell_t *params) *(int *)vptr = params[2]; vptr += sizeof(int); *(int *)vptr = params[3]; + vptr += sizeof(int); + *(CBaseEntity **)vptr = pTarget; pWrapper->Execute(vstk, NULL); @@ -254,7 +266,7 @@ cell_t TF2_RemoveCondition(IPluginContext *pContext, const cell_t *params) { static ICallWrapper *pWrapper = NULL; - // CTFPlayerShared::RemoveCond(int) + // CTFPlayerShared::RemoveCond(int, bool) if (!pWrapper) { REGISTER_NATIVE_ADDR("RemoveCondition", diff --git a/gamedata/sm-tf2.games.txt b/gamedata/sm-tf2.games.txt index 1edb45d7..3145301b 100644 --- a/gamedata/sm-tf2.games.txt +++ b/gamedata/sm-tf2.games.txt @@ -33,8 +33,8 @@ { "library" "server" "windows" "\x51\x53\x56\x8B\xF1\x8B\x8E\x2A\x2A\x00\x00\xE8\x2A\x2A\x2A\x2A\x8B\xD8\x8B\x86\x2A\x2A\x00\x00\x8B\x80" - "linux" "@_ZN15CTFPlayerShared8DisguiseEii" - "mac" "@_ZN15CTFPlayerShared8DisguiseEii" + "linux" "@_ZN15CTFPlayerShared8DisguiseEiiP9CTFPlayer" + "mac" "@_ZN15CTFPlayerShared8DisguiseEiiP9CTFPlayer" } "CalcCritical" { diff --git a/plugins/include/tf2.inc b/plugins/include/tf2.inc index 1c6e36e6..1b50b80a 100644 --- a/plugins/include/tf2.inc +++ b/plugins/include/tf2.inc @@ -192,10 +192,11 @@ native TF2_SetPlayerPowerPlay(client, bool:enabled); * @param client Player's index. * @param team Team to disguise the player as (only TFTeam_Red and TFTeam_Blue have an effect) * @param class TFClassType class to disguise the player as + * @param target Specific target player to disguise as (0 for any) * @noreturn * @error Invalid client index, client not in game, or no mod support. */ -native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class); +native TF2_DisguisePlayer(client, TFTeam:team, TFClassType:class, target=0); /** * Removes the current disguise from a client. Only has an effect on spies.