csgo-plugins/FixPhysboxMultiplayerCollision/scripting/FixPhysboxMultiplayerCollision.sp
2020-03-25 20:09:12 +02:00

106 lines
4.0 KiB
SourcePawn

#include <sourcemod>
#include <sdktools>
#include <dhooks>
#pragma semicolon 1
#pragma newdecls required
#define PLUGIN_VERSION "1.0"
public Plugin myinfo =
{
name = "Fix func_physbox_multiplayer collision",
author = "xen",
description = "Sets the collision to weapons only whenever a func_physbox_multiplayer gets parented",
version = PLUGIN_VERSION,
url = ""
}
Handle g_hSetParent;
// Entity collision groups
enum
{
COLLISION_GROUP_NONE = 0, // 0
COLLISION_GROUP_DEBRIS, // 1 - Collides with nothing but world and static stuff
COLLISION_GROUP_DEBRIS_TRIGGER, // 2 - Same as debris, but hits triggers
COLLISION_GROUP_INTERACTIVE_DEBRIS, // 3 - Collides with everything except other interactive debris or debris
COLLISION_GROUP_INTERACTIVE, // 4 - Collides with everything except interactive debris or debris
COLLISION_GROUP_PLAYER, // 5
COLLISION_GROUP_BREAKABLE_GLASS, // 6
COLLISION_GROUP_VEHICLE, // 7
COLLISION_GROUP_PLAYER_MOVEMENT, // 8 - For HL2, same as Collision_Group_Player, for
// TF2, this filters out other players and CBaseObjects
COLLISION_GROUP_NPC, // 9 - Generic NPC group
COLLISION_GROUP_IN_VEHICLE, // 10 - for any entity inside a vehicle
COLLISION_GROUP_WEAPON, // 11 - for any weapons that need collision detection
COLLISION_GROUP_VEHICLE_CLIP, // 12 - vehicle clip brush to restrict vehicle movement
COLLISION_GROUP_PROJECTILE, // 13 - Projectiles!
COLLISION_GROUP_DOOR_BLOCKER, // 14 - Blocks entities not permitted to get near moving doors
COLLISION_GROUP_PASSABLE_DOOR, // 15 - Doors that the player shouldn't collide with
COLLISION_GROUP_DISSOLVING, // 16 - Things that are dissolving are in this group
COLLISION_GROUP_PUSHAWAY, // 17 - Nonsolid on client and server, pushaway in player code
COLLISION_GROUP_NPC_ACTOR, // 18 - Used so NPCs in scripts ignore the player.
COLLISION_GROUP_NPC_SCRIPTED, // 19 - USed for NPCs in scripts that should not collide with each other
LAST_SHARED_COLLISION_GROUP
};
// Physbox spawnflags
enum
{
SF_PHYSBOX_ASLEEP = 0x01000,
SF_PHYSBOX_IGNOREUSE = 0x02000,
SF_PHYSBOX_DEBRIS = 0x04000,
SF_PHYSBOX_MOTIONDISABLED = 0x08000,
SF_PHYSBOX_USEPREFERRED = 0x10000,
SF_PHYSBOX_ENABLE_ON_PHYSCANNON = 0x20000,
SF_PHYSBOX_NO_ROTORWASH_PUSH = 0x40000, // The rotorwash doesn't push these
SF_PHYSBOX_ENABLE_PICKUP_OUTPUT = 0x80000,
SF_PHYSBOX_ALWAYS_PICK_UP = 0x100000, // Physcannon can always pick this up, no matter what mass or constraints may apply.
SF_PHYSBOX_NEVER_PICK_UP = 0x200000, // Physcannon will never be able to pick this up.
SF_PHYSBOX_NEVER_PUNT = 0x400000, // Physcannon will never be able to punt this object.
SF_PHYSBOX_PREVENT_PLAYER_TOUCH_ENABLE = 0x800000 // If set, the player will not cause the object to enable its motion when bumped into
};
public void OnPluginStart()
{
Handle hGameConf = LoadGameConfigFile("FixPhysboxMultiplayer.games");
if(!hGameConf)
{
SetFailState("Can't find FixPhysBoxMultiplayers.games.txt gamedata.");
return;
}
int offset = GameConfGetOffset(hGameConf, "CBaseEntity::SetParent");
if (offset == -1)
SetFailState("Failed to find CBaseEntity::SetParent offset");
// DHooks
g_hSetParent = DHookCreate(offset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity, Hook_SetParent);
DHookAddParam(g_hSetParent, HookParamType_CBaseEntity);
DHookAddParam(g_hSetParent, HookParamType_Int);
CloseHandle(hGameConf);
}
public void OnEntityCreated(int iEntity, const char[] sClassname)
{
if(StrEqual(sClassname, "func_physbox_multiplayer", false))
DHookEntity(g_hSetParent, true, iEntity);
}
public MRESReturn Hook_SetParent(int iEntity)
{
SetDebrisCollisionGroup(iEntity);
return MRES_Ignored;
}
public void SetDebrisCollisionGroup(int iEntity)
{
// Set collisiongroup to WEAPON to replicate CS:S behavior when parented
char parent[64];
if(GetEntPropString(iEntity, Prop_Data, "m_iParent", parent, sizeof(parent)))
SetEntProp(iEntity, Prop_Data, "m_CollisionGroup", COLLISION_GROUP_WEAPON);
}