new const NINTENDOMOD_PRINCESS_PLUGIN[] = "Nintendo Mod - Princess"
new const NINTENDOMOD_PRINCESS_VERSION[] = "1.2"
new const NINTENDOMOD_PRINCESS_AUTHOR[] = "Soloist"

/*
	Passive: Umbrella
		* Lower Gravity.
	Skill 1: Slap
		* Slap your foe with your glove.
	Skill 2: Charm
		* Chance to lull your enemy with your divine beauty.
	Skill 3: Group Hug
		* Heal you and your nearby friends with the power of love.
	PowerUp: Cry for Help!
		* When in trouble do what you do best, cry for help! Brings forth a tide of friendly creatures to rain down on your enemy.

	Future Plans
		Add CVARS for values

	Written By Soloist
	Version 1.2
	Last Updated On 09/24/06

	*************************************************************************************

	Changelog
		Version 1.2
			* Fixed where powerup would random turn on people
		Version 1.1
			* Fixed Group Hug not healing teammates
			* Made Powerup glow team color
		Version 1.0
			* Release of the plugin
*/

#include <amxmodx>
#include <fun>
#include <cstrike>
#include <fakemeta>
#include <nintendomod>

new const Float:PRINCESS_JUMPGRAV[11] = {775.0, 750.0, 725.0, 700.0, 675.0, 650.0, 625.0, 600.0, 500.0, 400.0, 350.0};
new const Float:PRINCESS_SLAPPROB[3] = {0.001, 0.005, 0.01};
new const Float:PRINCESS_SLAPDMG[3] = {75.0, 50.0, 25.0};
new const Float:PRINCESS_CHARMPROB[3] = {0.01, 0.05, 0.1};
new const Float:PRINCESS_GROUPHUGHEALTH[3] = {1.0, 2.0, 3.0}

new charName[] = "Princess";
new passiveName[] = "Umbrella";
new skill1Name[] = "Slap";
new skill2Name[] = "Charm";
new skill3Name[] = "Group Hug";
new powerupName[] = "Cry";
new initName[] = "Princess_Init";
new keyDownName[] = "Princess_Mushroom";

new passiveHelp[] = "Lower Gravity.";
new skill1Help[] = "Slap your foe with your glove.";
new skill2Help[] = "Chance to lull your enemy with your divine beauty.";
new skill3Help[] = "Heal you and your nearby friends with the power of love.";
new powerupHelp[] = "Start to cry and your tears hurt your enemys.";

new PlayerLevel[33];
new PlayerSkill1[33];
new PlayerSkill2[33];
new PlayerSkill3[33];
new PlayerPowerUp[33];

new healthSpr;

public plugin_init()
{
	if(is_plugin_loaded("Nintendo Mod") == -1)
	{
		server_print("**********************************");
		server_print("*** Nintendo Mod is not loaded ***");
		server_print("**********************************");
		pause("ae");
		return;
	}

	register_plugin(NINTENDOMOD_PRINCESS_PLUGIN, NINTENDOMOD_PRINCESS_VERSION, NINTENDOMOD_PRINCESS_AUTHOR);

	register_cvar("NintendoMod_Princess_Version", NINTENDOMOD_PRINCESS_VERSION, FCVAR_SERVER|FCVAR_SPONLY);

	register_event("ResetHUD", "ResetHUD", "b");

	register_forward(FM_Touch, "Princess_Slap");
	register_forward(FM_PlayerPreThink, "Princess_Charm");

	Nintendo_RegisterChar(charName, passiveName, skill1Name, skill2Name, skill3Name, powerupName, initName);
	Nintendo_RegisterHelp(charName, passiveHelp, skill1Help, skill2Help, skill3Help, powerupHelp);
	Nintendo_RegisterKeyDown(charName, keyDownName);

	register_srvcmd(initName, initName);
	register_srvcmd(keyDownName, keyDownName);
}

public plugin_precache()
{
	engfunc(EngFunc_PrecacheModel, "models/player/princess_smallmodel/princess_smallmodel.mdl");
	healthSpr = engfunc(EngFunc_PrecacheModel, "sprites/nintendomod/princess_health.spr");
}

public client_connect(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	InitPlayer(id);

	return PLUGIN_CONTINUE;
}

public client_disconnect(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	InitPlayer(id);
	remove_task(id);

	return PLUGIN_CONTINUE;
}

public InitPlayer(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	PlayerLevel[id] = 0;
	PlayerSkill1[id] = 0;
	PlayerSkill2[id] = 0;
	PlayerSkill3[id] = 0;
	PlayerPowerUp[id] = 0;

	return PLUGIN_CONTINUE;
}

public Princess_Init()
{
	new temp[33];
	read_argv(1, temp, 32);
	new id = str_to_num(temp);

	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	read_argv(2, temp, 32);
	new index  = str_to_num(temp);

	if(index == 0)
	{
		read_argv(3, temp, 32);
		new level = str_to_num(temp);
		read_argv(4, temp, 32);
		new skill1 = str_to_num(temp);
		read_argv(5, temp, 32);
		new skill2 = str_to_num(temp);
		read_argv(6, temp, 32);
		new skill3 = str_to_num(temp);
		read_argv(7, temp, 32);
		new powerup = str_to_num(temp);

		PlayerLevel[id] = level;
		PlayerSkill1[id] = skill1;
		PlayerSkill2[id] = skill2;
		PlayerSkill3[id] = skill3;
		PlayerPowerUp[id] = powerup;
	}
	else
	{
		read_argv(3, temp, 32);
		new value = str_to_num(temp);

		switch(index)
		{
			case 1: PlayerLevel[id] = value
			case 2: PlayerSkill1[id] = value;
			case 3: PlayerSkill2[id] = value;
			case 4: PlayerSkill3[id] = value;
			case 5: PlayerPowerUp[id] = value;
		}
	}

	ResetHUD(id);

	return PLUGIN_CONTINUE;
}

public ResetHUD(id)
{
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	cs_reset_user_model(id);
	set_user_rendering(id);

	Princess_Passive(id);
	Princess_GroupHug(id);

	return PLUGIN_CONTINUE;
}

public Princess_Passive(id) // Passive
{
	if (!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	Nintendo_SetGravity(id, PRINCESS_JUMPGRAV[PlayerLevel[id]]);

	return PLUGIN_CONTINUE;
}

public Princess_Slap(victim, attacker) // Skill 1
{
	if(!Nintendo_Active() || !Nintendo_HasChar(attacker, charName) || !Nintendo_IsValidPlayer(victim) || !Nintendo_IsValidPlayer(attacker))
		return PLUGIN_HANDLED;

	if(PlayerSkill1[attacker] > 0)
	{
		if(Nintendo_TeamKill(victim, attacker))
		{
			new Float:randomnumber = random_float(0.0, 1.0);
			if(randomnumber <= PRINCESS_SLAPPROB[PlayerSkill3[attacker] - 1])
			{
				new curHealth = pev(victim, pev_health);
				if(curHealth <= PRINCESS_SLAPDMG[PlayerSkill1[attacker] - 1])
					Nintendo_SetHealth(victim, 1.0, false);
				else
					Nintendo_SetHealth(victim, PRINCESS_SLAPDMG[PlayerSkill1[attacker] - 1], false);

				new Float:vectors[3]
				vectors[0] = random_float(-900.0, 900.0);
				vectors[1] = random_float(-900.0, 900.0);
				vectors[2] = random_float(-900.0, 900.0);
				set_pev(victim, pev_punchangle, vectors);

				vectors[0] = random_float(200.0, 3500.0);
				vectors[1] = random_float(200.0, 3500.0);
				vectors[2] = random_float(200.0, 3500.0);
				set_pev(victim, pev_velocity, vectors);

				set_pev(victim, pev_takedamage, 0.0);
				set_task(5.0, "Princess_SlapRemoveGod", victim);

				switch (random_num(1, 4))
				{
					case 1: emit_sound(victim, CHAN_VOICE, "player/bhit_flesh-3.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
					case 2: emit_sound(victim, CHAN_VOICE, "player/bhit_flesh-2.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
					case 3: emit_sound(victim, CHAN_VOICE, "player/pl_die1.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
					case 4: emit_sound(victim, CHAN_VOICE, "player/pl_pain6.wav", 1.0, ATTN_NORM, 0, PITCH_NORM);
				}
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public Princess_SlapRemoveGod(id)
	set_pev(id, pev_takedamage, 2.0);

public Princess_Charm(id) // Skill 2
{
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	if(PlayerSkill2[id] > 0)
	{
		new victim, body
		get_user_aiming(id, victim, body);
		if(Nintendo_IsValidPlayer(victim))
		{
			if(Nintendo_TeamKill(id, victim))
			{
				new Float:randomnumber = random_float(0.0, 1.0);
				if(randomnumber <= PRINCESS_CHARMPROB[PlayerSkill2[id] - 1])
				{
					new Float:velocity[3];
					new idOrigin[3], vicOrigin[3];

					pev(victim, pev_origin, vicOrigin);
					pev(id, pev_origin, idOrigin);

					new distance = get_distance(idOrigin, vicOrigin);

					if(distance > 50)
					{
						new Float:length = distance / 500.0;

						velocity[0] = float((idOrigin[0] - vicOrigin[0])) / length;
						velocity[1] = float((idOrigin[1] - vicOrigin[1])) / length;
						velocity[2] = float((idOrigin[2] - vicOrigin[2])) / length;
					}
					else
					{
						velocity[0] = 0.0;
						velocity[1] = 0.0;
						velocity[2] = 0.0;
					}

					set_pev(victim, pev_velocity, velocity);
				}
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public Princess_GroupHug(id) // Skill 3
{
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	if(PlayerSkill3[id] > 0)
	{
		new Float:newHealth, curHealth;

		curHealth = pev(id, pev_health);

		if(curHealth < 100.0)
		{
			newHealth = curHealth + PRINCESS_GROUPHUGHEALTH[PlayerSkill3[id] - 1];
			if(newHealth > 100.0) newHealth = 100.0;
			Nintendo_SetHealth(id, newHealth, false);

			Princess_GroupHugSprite(id);
		}

		new players[32], num, player;
		get_players(players, num);
		for(new i = 0; i <= num; i++)
		{
			player = players[i];
			if(Nintendo_IsValidPlayer(player))
			{
				if((get_user_team(id) == get_user_team(player)) && (id != player))
				{
					new healer[3], healed[3];

					get_user_origin(id, healer);
					get_user_origin(player, healed);
					if(get_distance(healer, healed) <= 500)
					{
						curHealth = pev(player, pev_health);
						if(curHealth < 100.0)
						{
							newHealth = curHealth + PRINCESS_GROUPHUGHEALTH[PlayerSkill3[id] - 1];
							if(newHealth > 100.0) newHealth = 100.0;
							Nintendo_SetHealth(player, newHealth, false);
							Princess_GroupHugSprite(player);
						}
					}
				}
			}
		}

		set_task(2.0,"Princess_GroupHug", id)
	}

	return PLUGIN_CONTINUE;
}

public Princess_GroupHugSprite(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	message_begin(MSG_ALL, SVC_TEMPENTITY)
	write_byte(124)
	write_byte(id)
	write_coord(50)
	write_short(healthSpr)
	write_short(3)
	message_end()

	return PLUGIN_CONTINUE;
}

public Princess_Mushroom()
{
	new temp[6]
	read_argv(1, temp, 5)
	new id = str_to_num(temp)

	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	if(PlayerPowerUp[id] == 1)
	{
		Nintendo_PowerUpUsed(id, 1, 30);
		cs_set_user_model(id, "princess_smallmodel");
		if(get_user_team(id) == 1)
			set_user_rendering(id, kRenderFxGlowShell, 255, 0, 0, kRenderNormal, 25);
		else
			set_user_rendering(id, kRenderFxGlowShell, 0, 0, 255, kRenderNormal, 25);
		Nintendo_StatusHUD(id, "You have used a mushroom, so you are small.");
		set_task(5.0, "Princess_MushroomReset", id)
	}

	return PLUGIN_CONTINUE;
}

public Princess_MushroomReset(id)
{
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	set_user_rendering(id);
	cs_reset_user_model(id);
	Nintendo_StatusHUD(id, "You are back to normal.");

	return PLUGIN_CONTINUE;
}
