new const NINTENDOMOD_DONKEYKONG_PLUGIN[] = "Nintendo Mod - Donkey Kong"
new const NINTENDOMOD_DONKEYKONG_VERSION[] = "1.0"
new const NINTENDOMOD_DONKEYKONG_AUTHOR[] = "Soloist"

/*
	Passive: Thickened Skin
		* As level increases, health increases.
	Skill 1: Banana Nades
		* Increase hegrenade damage.
	Skill 2: Chest Beat
		* Scares enemies, when enemy attacks Donkey Kong, he moves randomly in different directions.
	Skill 3: Knockback
		* Chance on attack to push the target backwards a few feet
	PowerUp: Stomp
		* Stuns enemy for 5 seconds

	Future Plans
		Add CVARS for values

	Written By Soloist
	Version 1.0
	Last Updated On 08/26/06

	*************************************************************************************

	Changelog
		Version 1.0
			* Release of the plugin
*/

#include <amxmodx>
#include <fun>
#include <fakemeta>
#include <nintendomod>

new charName[] = "DonkeyKong";
new passiveName[] = "Thickened Skin";
new skill1Name[] = "Banana Nades";
new skill2Name[] = "Chest Beat";
new skill3Name[] = "Knockback";
new powerupName[] = "Stomp";
new initName[] = "DonkeyKong_Init";
new keyDownName[] = "DonkeyKong_Stomp";

new passiveHelp[] = "As level increases, health increases.";
new skill1Help[] = "Increase hegrenade damage.";
new skill2Help[] = "Scares enemies, when enemy attacks Donkey Kong, he moves randomly in different directions";
new skill3Help[] = "Chance on attack to push the target backwards a few feet";
new powerupHelp[] = "Stuns enemy for 5 seconds";

new const Float:DONKEYKONG_THICKENEDSKINHEALTH[11] = {105.0, 110.0, 120.0, 130.0, 140.0, 150.0, 160.0, 170.0, 180.0, 190.0, 200.0};
new const DONKEYKONG_BANANANADESDMG[3] = {50, 75, 100};
new const Float:DONKEYKONG_CHESTBEATPROB[3] = {0.333, 0.666, 0.75};
new const Float:DONKEYKONG_KNOCKBACKPROB[3] = {0.333, 0.666, 0.75};

new PlayerLevel[33];
new PlayerSkill1[33];
new PlayerSkill2[33];
new PlayerSkill3[33];
new PlayerPowerUp[33];

new bool:Stomped[33];

new DonkeyNadeTrial, Stomp;

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_DONKEYKONG_PLUGIN, NINTENDOMOD_DONKEYKONG_VERSION, NINTENDOMOD_DONKEYKONG_AUTHOR);
	register_cvar("NintendoMod_DonkeyKong_Version", NINTENDOMOD_DONKEYKONG_VERSION, FCVAR_SERVER|FCVAR_SPONLY);
	set_cvar_string("NintendoMod_DonkeyKong_Version", NINTENDOMOD_DONKEYKONG_VERSION);

	register_event("ResetHUD", "ResetHUD", "b");

	register_event("Damage", "DonkeyKong_Damage", "b", "2!0");
	register_forward(FM_Touch, "DonkeyKong_Climbing");
	register_event("AmmoX", "DonkeyKong_DrawGrenade", "b");
	register_event("CurWeapon", "DonkeyKong_StompWeapon","be","1=1");

	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()
{
	DonkeyNadeTrial = engfunc(EngFunc_PrecacheModel, "sprites/zbeam5.spr");
	Stomp = precache_model("sprites/white.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 DonkeyKong_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)
{
	Stomped[id] = false;
	
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	DonkeyKong_Passive(id);

	return PLUGIN_CONTINUE;
}

public DonkeyKong_Passive(id) // Passive
{
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	Nintendo_SetHealth(id, DONKEYKONG_THICKENEDSKINHEALTH[PlayerLevel[id]], true);

	return PLUGIN_CONTINUE;
}

public DonkeyKong_Damage(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	new damage = read_data(2);
	new weapon, bodypart, attacker = get_user_attacker(id, weapon, bodypart);
	new headshot = bodypart == 1 ? 1 : 0;

	if(!Nintendo_IsValidPlayer(attacker))
		return PLUGIN_HANDLED;

	if(weapon == 4 && Nintendo_HasChar(attacker, charName))
		DonkeyKong_BananaNades(id, attacker, damage, headshot);

	if(Nintendo_HasChar(id, charName))
		DonkeyKong_ChestBeat(id, attacker);
	else
		DonkeyKong_Knockback(id, attacker)

	return PLUGIN_CONTINUE;
}

public DonkeyKong_BananaNades(victim, attacker, damage, headshot) // Skill 1
{
	if(!Nintendo_Active() || !Nintendo_HasChar(attacker, charName) || !Nintendo_IsValidPlayer(victim))
		return PLUGIN_HANDLED;

	if(PlayerSkill1[attacker] > 0)
	{
		if(Nintendo_TeamKill(victim, attacker))
			Nintendo_ExtraDamage(attacker, victim, DONKEYKONG_BANANANADESDMG[PlayerSkill1[attacker] - 1], "Banana Nades", headshot);
	}

	return PLUGIN_CONTINUE;
}

public DonkeyKong_DrawGrenade(id) // Skill 1
{
	if(!Nintendo_Active() || !Nintendo_HasChar(id, charName) || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	if(PlayerSkill1[id] > 0)
	{
		new iCurrent = -1;
		while((iCurrent = engfunc(EngFunc_FindEntityByString, iCurrent, "classname", "grenade")) > 0)
		{
			new string[32]

			pev(iCurrent, pev_model, string, 31);

			if(id == pev(iCurrent, pev_owner) && equali("models/w_hegrenade.mdl", string))
			{
				new Float:glowColor[3] = {225.0, 255.0, 0.0}
				set_pev(iCurrent, pev_renderfx, kRenderFxGlowShell);
				set_pev(iCurrent, pev_rendercolor, glowColor);
				set_pev(iCurrent, pev_rendermode, kRenderTransAlpha);
				set_pev(iCurrent, pev_renderamt, 100.0);

				message_begin(MSG_BROADCAST ,SVC_TEMPENTITY)
				write_byte(22)
				write_short(iCurrent)
				write_short(DonkeyNadeTrial)
				write_byte(10)
				write_byte(10)
				write_byte(225)
				write_byte(255)
				write_byte(0)
				write_byte(255)
				message_end()
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public DonkeyKong_ChestBeat(victim, attacker)// Skill 2
{
	if(!Nintendo_Active() || !Nintendo_HasChar(victim, charName) || !Nintendo_IsValidPlayer(victim) || !Nintendo_IsValidPlayer(attacker))
		return PLUGIN_HANDLED;

	if(PlayerSkill2[victim] > 0 && victim !=  attacker)
	{
		if(Nintendo_TeamKill(victim, attacker))
		{
			new Float:randomnumber = random_float(0.0,1.0);
			if(randomnumber <= DONKEYKONG_CHESTBEATPROB[PlayerSkill2[victim] - 1])
			{
				new Float:velocity[3];
				pev(attacker, pev_velocity, velocity);
				switch(random_num(0, 3))
				{
					case 0: velocity[0] += 200.0;
					case 1: velocity[0] -= 200.0;
					case 2: velocity[1] += 200.0;
					case 3: velocity[1] -= 200.0;
				}
				set_pev(attacker, pev_velocity, {0.0, 0.0, 0.0});
				set_pev(attacker, pev_velocity, velocity);
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public DonkeyKong_Knockback(victim, attacker) // Skill 3
{
	if(!Nintendo_Active() || !Nintendo_HasChar(attacker, charName) || !Nintendo_IsValidPlayer(victim) || !Nintendo_IsValidPlayer(attacker))
		return PLUGIN_HANDLED;

	if(PlayerSkill3[attacker] > 0)
	{
		if(Nintendo_TeamKill(victim, attacker))
		{
			new Float:randomnumber = random_float(0.0,1.0);
			if(randomnumber <= DONKEYKONG_KNOCKBACKPROB[PlayerSkill3[attacker] - 1])
			{
				new origin[3], vorigin[3];

				get_user_origin(attacker, origin);
				get_user_origin(victim, vorigin);

				new Float:velocity[3];
				velocity[0] = (vorigin[0] - origin[0]) * 1.0;
				velocity[1] = (vorigin[1] - origin[1]) * 1.0;
				velocity[2] = 50.0;
				set_pev(attacker, pev_velocity, {0.0, 0.0, 0.0});
				set_pev(victim, pev_velocity, velocity);
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public DonkeyKong_Stomp()
{
	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)
	{
		if(!(pev(id, pev_flags) &FL_ONGROUND))
		{
			Nintendo_PowerUpUsed(id, 1, 30);

			new Float:velocity[3], idOrigin[3], vicOrigin[3];

			set_pev(id, pev_takedamage, 0.0);

			velocity[0] = 0.0;
			velocity[1] = 0.0;
			velocity[2] = -600.0;
			set_pev(id, pev_velocity, velocity);
			set_task(2.0, "DonkeyKong_RemoveGod", id);

			get_user_origin(id, idOrigin);

			message_begin(MSG_ONE, SVC_TEMPENTITY, idOrigin, id);
			write_byte(TE_BEAMCYLINDER);
			write_coord(idOrigin[0]);
			write_coord(idOrigin[1]);
			write_coord(idOrigin[2]-16);
			write_coord(idOrigin[0]);
			write_coord(idOrigin[1]);
			write_coord(idOrigin[2] + 500);
			write_short(Stomp);
			write_byte(0); // startframe
			write_byte(1); // framerate
			write_byte(6); // 3 life 2
			write_byte(8); // width 16
			write_byte(1); // noise
			write_byte(100); // r
			write_byte(100); // g
			write_byte(255); // b
			write_byte(192); //brightness
			write_byte(0); // speed
			message_end();

			new players[32], num, player;
			get_players(players, num);

			for(new i = 0; i <= num; i++)
			{
				player = players[i];
				if(Nintendo_IsValidPlayer(player))
				{
					if(Nintendo_TeamKill(id, player))
					{
						get_user_origin(player, vicOrigin);

						if(get_distance(vicOrigin, idOrigin) < 500.0)
						{
							new speed, parm[2], Float:velocity[3];

							speed = pev(player, pev_maxspeed);

							parm[0] = player;
							parm[1] = speed;

							velocity[0] = 0.0;
							velocity[1] = 0.0;
							velocity[2] = 100.0;

							set_pev(player, pev_velocity, velocity);
							Nintendo_SetSpeed(player, 1.0);

							Stomped[player] = true;

							message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0,0,0}, id)
							write_short(1<<14)
							write_short(1<<14)
							write_short(1<<14)
							message_end()

							set_task(4.0, "DonkeyKong_ResetSpeed", 0, parm, 2);
						}
					}
				}
			}
		}
		else
			Nintendo_PowerUpDeny(id, "You must be in the air.");
	}

	return PLUGIN_CONTINUE;
}

public DonkeyKong_StompWeapon(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	if(Stomped[id])
		Nintendo_SetSpeed(id, 1.0);

	return PLUGIN_CONTINUE;
}

public DonkeyKong_RemoveGod(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	set_pev(id, pev_takedamage, 2.0);

	return PLUGIN_CONTINUE;
}

public DonkeyKong_ResetSpeed(parm[])
{
	new id = parm[0];

	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	new Float:speed = float(parm[1]);

	Nintendo_SetSpeed(id, speed);
	Stomped[id] = false;

	return PLUGIN_CONTINUE;
}
