//Fake Medigun script
//Original written by ficool2
//Slightly modified by Seelpit
function GiveFakeMedigun(player)
{
	player.ValidateScriptScope();
	local scope = player.GetScriptScope();
	if ("fake_medigun" in scope && scope.fake_medigun.IsValid())
		scope.fake_medigun.Destroy();
	
	local fake_medigun = Entities.CreateByClassname("tf_weapon_medigun");
	NetProps.SetPropInt(fake_medigun, "m_AttributeManager.m_Item.m_iItemDefinitionIndex", 29);
	NetProps.SetPropBool(fake_medigun, "m_AttributeManager.m_Item.m_bInitialized", true);
	Entities.DispatchSpawn(fake_medigun);

	player.AddCustomAttribute("overheal bonus",3,-1)
	// prevent switching to this weapon (not sure why this works
	fake_medigun.KeyValueFromString("classname", "tf_weapon_fake_medigun");
	
	fake_medigun.SetAbsOrigin(player.GetOrigin());
	NetProps.SetPropEntity(fake_medigun, "m_hOwner", player);
	NetProps.SetPropEntity(fake_medigun, "m_hOwnerEntity", player);
	EntFireByHandle(fake_medigun, "SetParent", "!activator", -1, player, null);
	
	scope.fake_medigun <- fake_medigun;
	scope.last_buttons <- 0;
	scope.autoheal <- Convars.GetClientConvarValue("tf_medigun_autoheal", player.entindex()).tointeger();
	scope.healing <- true;
	
	for (local i = 0; i < 8; i++)
	{
		if (NetProps.GetPropEntityArray(player, "m_hMyWeapons", i) == null)
		{
			NetProps.SetPropEntityArray(player, "m_hMyWeapons", fake_medigun, i);
			break;
		}
	}

	AddThinkToEnt(player, "FakeMedigunThink");
}

function FakeMedigunStartHeal(medigun)
{
	fake_medigun.PrimaryAttack();
}

function FakeMedigunStopHeal(medigun)
{
	local target = NetProps.GetPropEntity(medigun, "m_hHealingTarget");
	if (target)
	{
		// forcefully lose the target by pretending he is out of range (this is disgusting)
		local invalid_vec = Vector(99999, 99999, 99999);
		local mins = NetProps.GetPropVector(target, "m_Collision.m_vecMins");
		local maxs = NetProps.GetPropVector(target, "m_Collision.m_vecMaxs");
		NetProps.SetPropVector(target, "m_Collision.m_vecMins", invalid_vec);
		NetProps.SetPropVector(target, "m_Collision.m_vecMaxs", invalid_vec);			
		medigun.PrimaryAttack();
		NetProps.SetPropVector(target, "m_Collision.m_vecMins", mins);
		NetProps.SetPropVector(target, "m_Collision.m_vecMaxs", maxs);
		
		NetProps.SetPropEntity(medigun, "m_hLastHealingTarget", target);
		NetProps.SetPropEntity(medigun, "m_hHealingTarget", null);
	}
	
	NetProps.SetPropEntity(fake_medigun, "m_bHealing", false);
	NetProps.SetPropEntity(fake_medigun, "m_bAttacking", false);
}

function FakeMedigunThink()
{
	//Remove the think if the medigun is not real.
	if (!fake_medigun.IsValid())
	{
		AddThinkToEnt(self, null);
		NetProps.SetPropString(self, "m_iszScriptThinkFunction", "");
		
		return;
	}
	
	//Don't try to heal if the real medigun isn't out.
	local activeWeapon = NetProps.GetPropEntity(self, "m_hActiveWeapon");
	if (activeWeapon && !(activeWeapon.GetClassname() == "tf_weapon_medigun"))
	{
		FakeMedigunStopHeal(fake_medigun);
		return;
	}
	local buttons = NetProps.GetPropInt(self, "m_nButtons");
	local IN_ATTACK2 = Constants.FButtons.IN_ATTACK2;
	if (autoheal > 0)
	{
		local buttons_pressed = (buttons ^ last_buttons) & buttons;
		if (buttons_pressed & IN_ATTACK2)
		{
			if (healing)
				FakeMedigunStopHeal(fake_medigun);
			else
				FakeMedigunStartHeal(fake_medigun);
			healing = !healing;
		}
		last_buttons = buttons;
	}
	else
	{
		if (buttons & IN_ATTACK2)
			FakeMedigunStartHeal(fake_medigun);
		else
			FakeMedigunStopHeal(fake_medigun);
	}
	
	return -1;
}

// EXAMPLE
// GiveFakeMedigun(GetListenServerHost());