132 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			132 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
#pragma semicolon 1
 | 
						|
#pragma newdecls required
 | 
						|
 | 
						|
#include <sourcemod>
 | 
						|
#include <sdktools>
 | 
						|
#include <dhooks>
 | 
						|
 | 
						|
#define FVPHYSICS_NO_IMPACT_DMG			0x0400		// don't do impact damage to anything
 | 
						|
 | 
						|
public Plugin myinfo =
 | 
						|
{
 | 
						|
	name 			= "FixVPhysicsCrush",
 | 
						|
	author 			= "BotoX",
 | 
						|
	description 	= "",
 | 
						|
	version 		= "0.0",
 | 
						|
	url 			= ""
 | 
						|
};
 | 
						|
 | 
						|
Handle g_hAcceptInput;
 | 
						|
Handle g_hSetGameFlags;
 | 
						|
Handle g_hGetGameFlags;
 | 
						|
int g_hPhysicsObject;
 | 
						|
 | 
						|
 | 
						|
public void OnPluginStart()
 | 
						|
{
 | 
						|
	Handle hGameData = LoadGameConfigFile("sdktools.games");
 | 
						|
	if(!hGameData)
 | 
						|
		SetFailState("Couldn't load sdktools gamedata.");
 | 
						|
 | 
						|
	// CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
 | 
						|
	int Offset = GameConfGetOffset(hGameData, "AcceptInput");
 | 
						|
	if(Offset == -1)
 | 
						|
		SetFailState("Failed to find AcceptInput offset.");
 | 
						|
 | 
						|
	g_hAcceptInput = DHookCreate(Offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, OnAcceptInput);
 | 
						|
	if(g_hAcceptInput == INVALID_HANDLE)
 | 
						|
		SetFailState("Failed to DHook AcceptInput.");
 | 
						|
 | 
						|
	DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
 | 
						|
	DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
 | 
						|
	DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
 | 
						|
	DHookAddParam(g_hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
 | 
						|
	DHookAddParam(g_hAcceptInput, HookParamType_Int);
 | 
						|
 | 
						|
	hGameData = LoadGameConfigFile("FixVPhysicsCrush.games");
 | 
						|
	if(!hGameData)
 | 
						|
		SetFailState("Couldn't load FixVPhysicsCrush gamedata.");
 | 
						|
 | 
						|
	// CPhysicsObject::SetGameFlags(unsigned short)
 | 
						|
	StartPrepSDKCall(SDKCall_Raw);
 | 
						|
	if(!PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "SetGameFlags"))
 | 
						|
	{
 | 
						|
		delete hGameData;
 | 
						|
		SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"SetGameFlags\") failed!");
 | 
						|
	}
 | 
						|
	PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
 | 
						|
	g_hSetGameFlags = EndPrepSDKCall();
 | 
						|
 | 
						|
	// CPhysicsObject::GetGameFlags()
 | 
						|
	StartPrepSDKCall(SDKCall_Raw);
 | 
						|
	if(!PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, "GetGameFlags"))
 | 
						|
	{
 | 
						|
		delete hGameData;
 | 
						|
		SetFailState("PrepSDKCall_SetFromConf(hGameData, SDKConf_Virtual, \"GetGameFlags\") failed!");
 | 
						|
	}
 | 
						|
	PrepSDKCall_SetReturnInfo(SDKType_PlainOldData, SDKPass_Plain);
 | 
						|
	g_hGetGameFlags = EndPrepSDKCall();
 | 
						|
 | 
						|
	int hCollisionGroup = FindSendPropInfo("CBaseEntity", "m_CollisionGroup");
 | 
						|
	if (hCollisionGroup == -1)
 | 
						|
		SetFailState("Couldn't find CBaseEntity::m_CollisionGroup");
 | 
						|
 | 
						|
	// CNetworkVar( int, m_CollisionGroup );
 | 
						|
	// IPhysicsObject	*m_pPhysicsObject;
 | 
						|
	g_hPhysicsObject = hCollisionGroup + 4;
 | 
						|
 | 
						|
	// Late load.
 | 
						|
	int entity = INVALID_ENT_REFERENCE;
 | 
						|
	while((entity = FindEntityByClassname(entity, "phys_thruster")) != INVALID_ENT_REFERENCE)
 | 
						|
	{
 | 
						|
		OnEntityCreated(entity, "phys_thruster");
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
public void OnEntityCreated(int entity, const char[] classname)
 | 
						|
{
 | 
						|
	if(StrEqual(classname, "phys_thruster"))
 | 
						|
	{
 | 
						|
		DHookEntity(g_hAcceptInput, true, entity);
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
public MRESReturn OnAcceptInput(int entity, Handle hReturn, Handle hParams)
 | 
						|
{
 | 
						|
	if(!IsValidEntity(entity))
 | 
						|
		return;
 | 
						|
 | 
						|
	char sCommand[128];
 | 
						|
	DHookGetParamString(hParams, 1, sCommand, sizeof(sCommand));
 | 
						|
 | 
						|
	if(StrEqual(sCommand, "Activate", false))
 | 
						|
	{
 | 
						|
		int attachedObject = GetEntPropEnt(entity, Prop_Data, "m_attachedObject");
 | 
						|
		if(attachedObject != INVALID_ENT_REFERENCE)
 | 
						|
		{
 | 
						|
			int vphysObj = GetVPhysicsObject(attachedObject);
 | 
						|
			if(vphysObj)
 | 
						|
			{
 | 
						|
				int flags = VPhysicsGetGameFlags(vphysObj);
 | 
						|
				flags |= FVPHYSICS_NO_IMPACT_DMG;
 | 
						|
				VPhysicsSetGameFlags(vphysObj, flags);
 | 
						|
			}
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
int VPhysicsGetGameFlags(int vphysicsObj)
 | 
						|
{
 | 
						|
	return SDKCall(g_hGetGameFlags, vphysicsObj);
 | 
						|
}
 | 
						|
 | 
						|
void VPhysicsSetGameFlags(int vphysicsObj, int flags)
 | 
						|
{
 | 
						|
	SDKCall(g_hSetGameFlags, vphysicsObj, flags);
 | 
						|
}
 | 
						|
 | 
						|
int GetVPhysicsObject(int entity)
 | 
						|
{
 | 
						|
	return GetEntData(entity, g_hPhysicsObject, 4);
 | 
						|
}
 |