diff --git a/gamedata/tf2.utils.nosoop.txt b/gamedata/tf2.utils.nosoop.txt index c9b3c5f..e0ccdf3 100644 --- a/gamedata/tf2.utils.nosoop.txt +++ b/gamedata/tf2.utils.nosoop.txt @@ -68,6 +68,12 @@ "linux" "@_ZN15CTFPlayerShared18GetMaxBuffedHealthEbb" "windows" "\x55\x8B\xEC\x83\xEC\x08\x56\x8B\xF1\x57\x8B\x8E\x2A\x01\x00\x00" } + "PointInRespawnRoom()" + { + "library" "server" + "linux" "@_Z18PointInRespawnRoomPK11CBaseEntityRK6Vectorb" + "windows" "\x55\x8B\xEC\x53\x33\xDB\x56\x57" + } } } } diff --git a/scripting/include/tf2utils.inc b/scripting/include/tf2utils.inc index c6b4eec..15a56e4 100644 --- a/scripting/include/tf2utils.inc +++ b/scripting/include/tf2utils.inc @@ -103,6 +103,21 @@ native int TF2Util_GetPlayerWearableCount(int client); */ native void TF2Util_UpdatePlayerSpeed(int client, bool immediate = false); +/** + * Returns whether or not a position / entity is in an active respawn room. If an entity is + * passed in, this also checks if the entity is touching an active respawn room, instead of just + * the given position. + * + * @param position A position to check. Should be the center / origin of an entity. + * @param entity An optional entity to check. + * @param bTouchingSameTeam Whether or not the respawn room must either match the entity's + * team, or not be assigned to a team. Always treated as true if + * the position is in an active spawn room. Has no effect if no + * entity is provided. + */ +native bool TF2Util_IsPointInRespawnRoom(const float[3] position, + int entity = INVALID_ENT_REFERENCE, bool bRestrictToSameTeam = false); + public SharedPlugin __pl_tf2utils = { name = "nosoop_tf2utils", file = "tf2utils.smx", diff --git a/scripting/tf2utils.sp b/scripting/tf2utils.sp index e5eb986..af5196a 100644 --- a/scripting/tf2utils.sp +++ b/scripting/tf2utils.sp @@ -11,7 +11,7 @@ #include -#define PLUGIN_VERSION "0.9.0" +#define PLUGIN_VERSION "0.10.0" public Plugin myinfo = { name = "TF2 Utils", author = "nosoop", @@ -34,6 +34,8 @@ Handle g_SDKCallWeaponGetSlot; Handle g_SDKCallWeaponGetID; Handle g_SDKCallWeaponGetMaxClip; +Handle g_SDKCallPointInRespawnRoom; + Address offs_CTFPlayer_hMyWearables; public APLRes AskPluginLoad2(Handle self, bool late, char[] error, int maxlen) { @@ -54,6 +56,8 @@ public APLRes AskPluginLoad2(Handle self, bool late, char[] error, int maxlen) { CreateNative("TF2Util_GetPlayerShootPosition", Native_GetPlayerShootPosition); + CreateNative("TF2Util_IsPointInRespawnRoom", Native_IsPointInRespawnRoom); + return APLRes_Success; } @@ -115,6 +119,14 @@ public void OnPluginStart() { PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain); g_SDKCallWeaponGetMaxClip = EndPrepSDKCall(); + StartPrepSDKCall(SDKCall_Static); + PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "PointInRespawnRoom()"); + PrepSDKCall_SetReturnInfo(SDKType_Bool, SDKPass_Plain); + PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer, VDECODE_FLAG_ALLOWNULL); + PrepSDKCall_AddParameter(SDKType_Vector, SDKPass_ByRef); + PrepSDKCall_AddParameter(SDKType_Bool, SDKPass_Plain); + g_SDKCallPointInRespawnRoom = EndPrepSDKCall(); + // networked CUtlVector offset support landed in 1.11; try to locate an offset there first offs_CTFPlayer_hMyWearables = view_as
(FindSendPropInfo("CTFPlayer", "m_hMyWearables")); @@ -284,6 +296,26 @@ public int Native_GetWeaponMaxClip(Handle plugin, int nParams) { return SDKCall(g_SDKCallWeaponGetMaxClip, entity); } +// bool(const float[3] position, int entity, bool bRestrictToSameTeam) +public int Native_IsPointInRespawnRoom(Handle plugin, int nParams) { + if (IsNativeParamNullVector(1)) { + return ThrowNativeError(SP_ERROR_NATIVE, "Cannot use NULL_VECTOR as origin"); + } + + float origin[3]; + GetNativeArray(1, origin, sizeof(origin)); + + int entity = GetNativeCell(2); + if (entity != INVALID_ENT_REFERENCE && !IsValidEntity(entity)) { + return ThrowNativeError(SP_ERROR_NATIVE, "Entity %d (%d) is invalid", entity, + EntRefToEntIndex(entity)); + } + + bool bRestrictToSameTeam = GetNativeCell(3); + + return SDKCall(g_SDKCallPointInRespawnRoom, entity, origin, bRestrictToSameTeam); +} + bool IsEntityWeapon(int entity) { if (!IsValidEntity(entity)) { ThrowNativeError(SP_ERROR_NATIVE, "Entity %d (%d) is invalid", entity,