#pragma semicolon 1
#pragma newdecls required

#include <sourcemod>
#include <sdkhooks>
#include <sdktools>
#include <dhooks>

public Plugin myinfo =
{
	name = "SetOwner",
	author = "xen",
	description = "Enables setting of entity owners for collision purposes",
	version = "1.0",
	url = ""
}

Handle g_hAcceptInput;

public void OnPluginStart()
{
	// Gamedata.
	Handle hConfig = LoadGameConfigFile("sdktools.games");
	if (hConfig == INVALID_HANDLE)
		SetFailState("Couldn't load sdktools game config!");

	int offset = GameConfGetOffset(hConfig, "AcceptInput");
	if (offset == -1)
		SetFailState("Failed to find AcceptInput offset");

	delete hConfig;

	// DHooks.
	g_hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, Hook_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);
	DHookAddParam(g_hAcceptInput, HookParamType_Int);
}

public void OnEntityCreated(int iEntity, const char[] sClassname)
{
	if (!strncmp(sClassname, "prop_", 5, false) ||
		!strncmp(sClassname, "func_", 5, false) ||
		StrEqual(sClassname, "player", false))
	{
		DHookEntity(g_hAcceptInput, false, iEntity);
	}
}

public MRESReturn Hook_AcceptInput(int iEntity, Handle hReturn, Handle hParams)
{
	char sCommand[128];
	DHookGetParamString(hParams, 1, sCommand, sizeof(sCommand));

	if (DHookIsNullParam(hParams, 2))
		return MRES_Ignored;

	int iActivator = DHookGetParam(hParams, 2);
	if (iActivator < 1 || iActivator > MaxClients)
		return MRES_Ignored;

	if (StrEqual(sCommand, "SetOwner", false))
	{
		SetEntPropEnt(iActivator, Prop_Data, "m_hOwnerEntity", iEntity);
		DHookSetReturn(hReturn, true);
		return MRES_Supercede;
	}
	else if (StrEqual(sCommand, "RemoveOwner", false))
	{
		SetEntPropEnt(iActivator, Prop_Data, "m_hOwnerEntity", -1);
		DHookSetReturn(hReturn, true);
		return MRES_Supercede;
	}

	return MRES_Ignored;
}