new const NINTENDOMOD_PLUGIN[] = "Nintendo Mod"
new const NINTENDOMOD_VERSION[] = "2.0"
new const NINTENDOMOD_AUTHOR[] = "Soloist"

// EDIT THESE TO WHAT YOU WANT THEM TO BE
//#define SAVE_METHOD 	1	//Saves XP to vault.ini (default)
//#define SAVE_METHOD 	2	//Saves XP to nintendomod nVault (DOES NOT WORK)
#define SAVE_METHOD 	3	//Saves XP to a MySQL database

#define NMADMIN 	ADMIN_LEVEL_A
// DO NOT EDIT BELOW HERE

/*
	Description
		* This is a Counter-Strike Mod, that allows you to be
		* nintendo characters. Each character has one passive,
		* that gets better as you level. Three Skills with three
		* level, that increase the power of the skill, and One
		* PowerUp that can be selected above level six. With
		* Nintendo Mod it is easy to add and remove characters.
		* Each Character has its own saved XP.

	Required Modules:
    	* fakemeta
    	* cstrike
    	* fun

	Client Commands:
		* say /changechar - Change your character
		* say /selectskills - Select your skills
		* say /resetskills - Reset your skills
		* say /playerlevels - Other players level
		* say /playerskills - Other players skill
		* say /skillsinfo - Current characters skills
		* say /characterhelp - Menu of all characters to see what they do
		* say /nintendohelp - Help menu
		* +powerup - PowerUp command

	Admin Commands:
		* amx_givexp - Add xp to player
		* amx_takexp - Takes xp from player
		* amx_givelevel - Give Levels to player
		* amx_setlevel - Sets player level
		* amx_resetxp - resets the xp

	CVARs:
		* sv_nintendomod - 1 = On, 0 = Off

	Future Plans
		* Add nVault Support
		* Add cvars for almost every value

	Written By Soloist
	Version 2.0
	Last Updated On 09/24/06

	*************************************************************************************

	Changelog
		Version 2.0
			* Fix Sql Bug
			* Allowed it to be played with DM
		Version 1.5
			* Added MySql Support
			* Added Client Command /playerlevels
			* Fix bug where plugin can load itself twice
			* Added NMADMIN for Admin access to commands
			* Sound for powerup only play on client and not all.
		Version 1.0
			* Release of the plugin
*/

#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <fakemeta>
#include <nintendomod>

new const LEVELS[10] = {100, 200, 400, 800, 1600, 3200, 6400, 12800, 25600, 51200};
new const MOTD_HEADER[] = "<html><head><style type=^"text/css^">p{color:#000000; font-size:12px;}h1{font-size:18px;}h2{font-size:16px;}body{background:#336699;margin-left:8px;margin-top:0px;}</style></head><body><p><br />";
new const MOTD_FOOTER[] = "</p></body></html>";

new AllChars[MAXCHARS][33];
new AllPassive[MAXCHARS][33];
new AllSkill1[MAXCHARS][33];
new AllSkill2[MAXCHARS][33];
new AllSkill3[MAXCHARS][33];
new AllPowerUp[MAXCHARS][33];
new AllInit[MAXCHARS][33];
new NumAllChars = 0;

new AllKeyDown[MAXCHARS][33];
new AllKeyUp[MAXCHARS][33];

new AllPassiveHelp[MAXCHARS][512];
new AllSkill1Help[MAXCHARS][512];
new AllSkill2Help[MAXCHARS][512];
new AllSkill3Help[MAXCHARS][512];
new AllPowerUpHelp[MAXCHARS][512];
new NumAllHelp = 0;

new PlayerChar[33];
new PlayerXP[MAXCHARS][33];
new PlayerLevel[MAXCHARS][33];
new PlayerSkill1[MAXCHARS][33];
new PlayerSkill2[MAXCHARS][33];
new PlayerSkill3[MAXCHARS][33];
new PlayerPowerUp[MAXCHARS][33];

new bool:PowerUpUsed[33];
new PowerUpTime[33];

new bool:ChangeChar[33];
new NewPlayerChar[33];

new bool:BetweenRounds;
new bool: FirstRound[33], GetXPNextRound[33];
new gBlockDeathMsg = 0, gInBlock = 0;

new characterMenuOffset[33];

#if SAVE_METHOD == 1 || !defined SAVE_METHOD
#include <nintendomod_vault>	//Saves XP to vault.ini (default)
#endif

#if SAVE_METHOD == 2
#include <nintendomod_nvault>	//Saves XP to nintendomod nVault (AMXX recommended)
#endif

#if SAVE_METHOD == 3
#include <nintendomod_mysql>	//Saves XP to a MySQL database
#endif

public plugin_init()
{
	if(is_plugin_loaded("Nintendo Mod") > 0)
	{
		server_print("*******************************************");
		server_print("*** You can only load Nintendo Mod once ***");
		server_print("*******************************************");
		pause("ae");
		return;
	}

	register_plugin(NINTENDOMOD_PLUGIN, NINTENDOMOD_VERSION, NINTENDOMOD_AUTHOR);
	register_cvar("NintendoMod_Version", NINTENDOMOD_VERSION, FCVAR_SERVER|FCVAR_SPONLY);
	set_cvar_string("NintendoMod_Version", NINTENDOMOD_VERSION);

	register_cvar("sv_nintendomod", "1");

	Saving_Init();

	register_menucmd(register_menuid("Choose_Character"), 1023, "ChooseCharacter");
	register_menucmd(register_menuid("Choose_Skill"), 1023, "ChooseSkill");
	register_menucmd(register_menuid("Character_Help"), 1023, "CharacterHelp");
	/*register_menucmd(register_menuid("Shop_Menu1"), 1023, "ShopMenu1");
	register_menucmd(register_menuid("Shop_Menu2"), 1023, "ShopMenu2");*/

	register_event("DeathMsg", "DeathMsg", "ae");
	register_event("ResetHUD", "ResetHUD", "b");

	register_concmd("amx_givexp", "GiveXP", NMADMIN, " - Add xp to player");
	register_concmd("amx_takexp", "TakeXP", NMADMIN, " - Takes xp from player");
	register_concmd("amx_givelevel", "GiveLevel", NMADMIN, " - Give Levels to player");
	register_concmd("amx_setlevel", "SetLevel", NMADMIN, " - Sets player level");
	register_concmd("amx_resetxp", "ResetXP", NMADMIN, " - resets the xp");

	register_clcmd("say", "HandleSay");
	register_clcmd("say_team", "HandleSay");

	register_clcmd("+powerup", "PowerUpKeyDown");
	register_clcmd("-powerup", "PowerUpKeyUp");

	register_clcmd("fullupdate", "FullUpdate");

	register_forward(FM_MessageBegin, "hook_messagebegin");
	register_forward(FM_WriteByte, "hook_writebyte");
	register_forward(FM_WriteChar, "hook_writechar")
	register_forward(FM_WriteShort, "hook_writeshort");
	register_forward(FM_WriteLong, "hook_writelong");
	register_forward(FM_WriteAngle, "hook_writeangle");
	register_forward(FM_WriteCoord, "hook_writecoord");
	register_forward(FM_WriteString, "hook_writestring");
	register_forward(FM_WriteEntity, "hook_writeent");
	register_forward(FM_MessageEnd, "hook_messageend");

	// Add menu items
	new configs[128];
	get_configsdir(configs, 127);
	server_cmd("exec %s/NintendoMod/nintendomod.cfg", configs);
}

public plugin_precache()
{
	engfunc(EngFunc_PrecacheSound, "nintendomod/powerup.wav");
	engfunc(EngFunc_PrecacheSound, "nintendomod/powerupfail.wav");
	engfunc(EngFunc_PrecacheSound, "nintendomod/powerupdeny.wav");
}

public plugin_cfg()
{
	set_task(1.0, "TimerAll", 0, "", 0, "b");
}

public plugin_modules()
{
	require_module("cstrike");
	require_module("fun");
	require_module("fakemeta");
	require_module("vault");
}

public plugin_natives()
{
	register_native("Nintendo_RegisterChar", "native_RegisterChar");
	register_native("Nintendo_RegisterHelp", "native_RegisterHelp");
	register_native("Nintendo_RegisterKeyDown", "native_RegisterKeyDown");
	register_native("Nintendo_RegisterKeyUp", "native_RegisterKeyUp");
	register_native("Nintendo_GetUserChar", "native_GetUserChar");
	register_native("Nintendo_PowerUpUsed", "native_PowerUpUsed");
	register_native("Nintendo_PowerUpDeny", "native_PowerUpDeny");
	register_native("Nintendo_ExtraDamage", "native_ExtraDamage");
}

public plugin_log()
{
	new logdata0[128], logdata1[64], logdata2[64], logdata3[64];
	new name[32], id;

	//Get the args from the log data
	read_logargv(0,logdata0,127);
	read_logargv(1,logdata1,63);
	read_logargv(2,logdata2,63);
	read_logargv(3,logdata3,63);

	if(get_playersnum() > 1)
	{
		//Individual Events
		if(equal(logdata1,"triggered"))
		{
			//Get the username and id out
			parse_loguser(logdata0, name, 31);
			id = get_user_index(name);

			//Hostage Events
			if(equal(logdata2,"Rescued_A_Hostage"))
				AddXP(id, 10);
			else if(equal(logdata2,"Killed_A_Hostage"))
				AddXP(id, -10);
			//Bomb Events
			else if(equal(logdata2,"Planted_The_Bomb"))
				AddXP(id, 10);
			else if(equal(logdata2,"Defused_The_Bomb"))
				AddXP(id, 15);
		}

		//Team Events
		else if(equal(logdata3,"All_Hostages_Rescued"))
			AddXP(id, 15);
		else if(equal(logdata3,"Target_Bombed"))
			AddXP(id, 15);

		ShowHUD(id);
	}
}
// Client Connects and Disconnects
public client_connect(id)
{
	InitPlayer(id);
}

public client_putinserver(id)
{
	LoadXP(id);
	InitAllCharacter(id);
}

public client_disconnect(id)
{
	SaveXPAll(id);
	InitPlayer(id);
	remove_task(id);
}

public RoundStart()
{
	if(!Nintendo_Active())
		return PLUGIN_HANDLED;

	BetweenRounds = false;

	return PLUGIN_CONTINUE;
}

public RoundEnd()
{
	if(!Nintendo_Active())
		return PLUGIN_HANDLED;

	BetweenRounds = true;

	return PLUGIN_CONTINUE;
}
// Init Player
public InitPlayer(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	PlayerChar[id] = CLASS_NONE;
	ChangeChar[id] = false;
	FirstRound[id] = true;
	GetXPNextRound[id] = false;

	for(new i = 1; i < MAXCHARS; i++)
	{
		PlayerLevel[id][i] = 0;
		PlayerXP[id][i] = 0;
		PlayerSkill1[id][i] = 0;
		PlayerSkill2[id][i] = 0;
		PlayerSkill3[id][i] = 0;
		PlayerPowerUp[id][i] = 0;
	}

	return PLUGIN_CONTINUE;
}

public InitAllCharacter(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	for(new i = 0; i < NumAllChars; i++)
		server_cmd("%s %d %d %d %d %d %d %d", AllInit[i], id, 0, PlayerLevel[id][i], PlayerSkill1[id][i], PlayerSkill2[id][i], PlayerSkill3[id][i], PlayerPowerUp[id][i]);

	return PLUGIN_CONTINUE;
}

public InitCharacter(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];

	server_cmd("%s %d %d %d %d %d %d %d", AllInit[player], id, 0, PlayerLevel[id][player], PlayerSkill1[id][player], PlayerSkill2[id][player], PlayerSkill3[id][player], PlayerPowerUp[id][player]);

	return PLUGIN_CONTINUE;
}

public InitLevel(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];

	server_cmd("%s %d %d %d", AllInit[player], id, 1, PlayerLevel[id][player]);

	return PLUGIN_CONTINUE;
}

public InitSkill(id, index, value)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];

	server_cmd("%s %d %d %d", AllInit[player], id, index, value);

	return PLUGIN_CONTINUE;
}
// HUD
public ShowHUD(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	new HUD[251]
	format(HUD, 250, "[Nintendo Mod] Character: %s - Level: %i - XP: %i", AllChars[PlayerChar[id]], PlayerLevel[id][PlayerChar[id]], PlayerXP[id][PlayerChar[id]]);

	message_begin(MSG_ONE, get_user_msgid("StatusText"), {0,0,0}, id);
	write_byte(0);
	write_string(HUD);
	message_end();

	set_task(1.0, "ShowHUD", id);

	return PLUGIN_CONTINUE;
}

public ResetHUD(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	if(ChangeChar[id] == true)
	{
		SaveXP(id);

		ChangeChar[id] = false;
		PlayerChar[id] = NewPlayerChar[id];

		new tmp[55]
		format(tmp, 54, "You have choosen %s", AllChars[NewPlayerChar[id]]);
		Nintendo_StatusHUD(id, tmp);
		InitCharacter(id);

		ShowHUD(id);
	}

	if(PlayerPowerUp[id][PlayerChar[id]] == 1)
	{
		PowerUpUsed[id] = true;
		PowerUpTime[id] = 10;
	}

	if(PlayerChar[id] == CLASS_NONE)
		ShowCharacter(id, 1);

	new skillsused = PlayerSkill1[id][PlayerChar[id]] + PlayerSkill2[id][PlayerChar[id]] + PlayerSkill3[id][PlayerChar[id]] + PlayerPowerUp[id][PlayerChar[id]]
	if(skillsused < PlayerLevel[id][PlayerChar[id]])
		ShowSkill(id);

	return PLUGIN_CONTINUE;
}

public DeathMsg()
{
	if(!Nintendo_Active())
		return PLUGIN_HANDLED;

	new attacker = read_data(1);
	new victim = read_data(2);
	new headshot  = read_data(3);

	if(attacker && victim && attacker != victim)
	{
		if(get_user_team(attacker) == get_user_team(victim))
			AddXP(attacker, -10);
		else
		{
			if(headshot)
				AddXP(attacker, 15);
			else
				AddXP(attacker, 10);
		}
	}

	return PLUGIN_CONTINUE
}
// Choosing Character
public ShowCharacter(id, menuOffset)
{
	if(!Nintendo_Active() || !is_user_connected(id) || (get_user_team(id) != 1 && get_user_team(id) != 2))
		return PLUGIN_HANDLED;

	characterMenuOffset[id] = 0;

	new charMenu[1801];
	new charKeys;

	if(menuOffset <= 0 || menuOffset > NumAllChars)
		menuOffset = 1;

	characterMenuOffset[id] = menuOffset;

	new len = format(charMenu, 1800, "\rNintendo Mod\r^n");
	len += format(charMenu[len], 1800-len, "\y%-25s %s^n^n", "Character", "XP");

	for(new x = menuOffset; x < menuOffset + 8; x++)
	{
		if(equali(AllChars[x], ""))
		{
			len += format(charMenu[len], 1800-len, "^n");
			continue;
		}

		if(PlayerChar[id] == x)
			len += format(charMenu[len], 1800-len, "\d%d. %-20s %d^n", x-menuOffset+1, AllChars[x], PlayerXP[id][x]);
		else
			len += format(charMenu[len], 1800-len, "\r%d. \w%-20s %d^n", x-menuOffset+1, AllChars[x], PlayerXP[id][x]);

		charKeys |= (1<<x-menuOffset);
	}

	if(NumAllChars > 8)
	{
		len += format(charMenu[len], 1800-len, "^n\r9. \wMore Characters^n");
		charKeys |= (1<<8);
	}
	else
		len += format(charMenu[len], 1800-len, "^n^n");

	// Cancel
	len += format(charMenu[len], 1800-len, "\r0. \wCancel");
	charKeys |= (1<<9);

	show_menu(id, charKeys, charMenu, 15, "Choose_Character");

	return PLUGIN_HANDLED;
}

public ChooseCharacter(id, key)
{
	if(key == 8)
	{
		ShowCharacter(id, characterMenuOffset[id] + 8);
		return PLUGIN_HANDLED;
	}
	if(key == 9)
	{
		characterMenuOffset[id] = 0;
		return PLUGIN_HANDLED;
	}

	key += characterMenuOffset[id];

	if(PlayerChar[id] == key)
	{
		if(ChangeChar[id] == true)
		{
			ChangeChar[id] = false;
			return PLUGIN_HANDLED;
		}
		return PLUGIN_HANDLED;
	}

	ChangeChar[id] = true;
	NewPlayerChar[id] = key;

	new tmp[55]
	format(tmp, 54, "You will change to %s next round", AllChars[key]);
	Nintendo_StatusHUD(id, tmp);

	return PLUGIN_CONTINUE;
}
// Choosing Skills
public ShowSkill(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];

	new skillMenu[1801];
	new powerKeys;

	new len = format(skillMenu, 1800, "\rNintendo Mod^n");
	len += format(skillMenu[len], 1800-len, "\y%s Menu^n", AllChars[player]);
	len += format(skillMenu[len], 1800-len, "\yPassive: %s^n", AllPassive[player]);

	if(PlayerSkill1[id][player]  < 3)
	{
		len += format(skillMenu[len], 1800-len, "^n\r1. \w%s - Level %d", AllSkill1[player], PlayerSkill1[id][player]);
		powerKeys |= MENU_KEY_1;
	}
	if(PlayerSkill2[id][player]  < 3)
	{
		len += format(skillMenu[len], 1800-len, "^n\r2. \w%s - Level %d", AllSkill2[player], PlayerSkill2[id][player]);
		powerKeys |= MENU_KEY_2;
	}
	if(PlayerSkill3[id][player]  < 3)
	{
		len += format(skillMenu[len], 1800-len, "^n\r3. \w%s - Level %d", AllSkill3[player], PlayerSkill3[id][player]);
		powerKeys |= MENU_KEY_3;
	}
	if(PlayerLevel[id][player]  >= 6 && PlayerPowerUp[id][player] != 1)
	{
		len += format(skillMenu[len], 1800-len, "^n\r4. \wPower Up: %s", AllPowerUp[player]);
		powerKeys |= MENU_KEY_4;
	}

	len += format(skillMenu[len], 1800-len, "^n^n\r0. \wExit");
	powerKeys |= MENU_KEY_0;

	show_menu(id, powerKeys, skillMenu, 15, "Choose_Skill");

	return PLUGIN_CONTINUE;
}

public ChooseSkill(id, key)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];
	new tmp[55];

	switch(key)
	{
		case 0:
		{
			PlayerSkill1[id][player]++;
			format(tmp, 54, "You have selected %s", AllSkill1[player]);
			Nintendo_StatusHUD(id, tmp);
			InitSkill(id, 2, PlayerSkill1[id][player]);
		}
		case 1:
		{
			PlayerSkill2[id][player]++;
			format(tmp, 54, "You have selected %s", AllSkill2[player]);
			Nintendo_StatusHUD(id, tmp);
			InitSkill(id, 3, PlayerSkill2[id][player]);
		}
		case 2:
		{
			PlayerSkill3[id][player]++;
			format(tmp, 54, "You have selected %s",  AllSkill3[player]);
			Nintendo_StatusHUD(id, tmp);
			InitSkill(id, 4, PlayerSkill3[id][player]);
		}
		case 3:
		{
			PlayerPowerUp[id][player] = 1;
			format(tmp, 54, "You have selected %s", AllPowerUp[player]);
			Nintendo_StatusHUD(id, tmp);
			InitSkill(id, 5, PlayerPowerUp[id][player]);
		}
		case 9: return PLUGIN_HANDLED;
	}

	new skillsused = PlayerSkill1[id][player] + PlayerSkill2[id][player] + PlayerSkill3[id][player] + PlayerPowerUp[id][player]
	if(skillsused < PlayerLevel[id][player])
		ShowSkill(id);

	SaveXP(id);

	return PLUGIN_CONTINUE;
}
// Adding XP
public AddXP(id, xp)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];

	PlayerXP[id][player] += xp;

	new oldLevel = PlayerLevel[id][player];

	if(PlayerXP[id][player] < LEVELS[0])
		PlayerLevel[id][player] = 0;
	else if(PlayerXP[id][player] >= LEVELS[0] && PlayerXP[id][player] < LEVELS[1])
		PlayerLevel[id][player] = 1;
	else if(PlayerXP[id][player] >= LEVELS[1] && PlayerXP[id][player] < LEVELS[2])
		PlayerLevel[id][player] = 2;
	else if(PlayerXP[id][player] >= LEVELS[2] && PlayerXP[id][player] < LEVELS[3])
		PlayerLevel[id][player] = 3;
	else if(PlayerXP[id][player] >= LEVELS[3] && PlayerXP[id][player] < LEVELS[4])
		PlayerLevel[id][player] = 4;
	else if(PlayerXP[id][player] >= LEVELS[4] && PlayerXP[id][player] < LEVELS[5])
		PlayerLevel[id][player] = 5;
	else if(PlayerXP[id][player] >= LEVELS[5] && PlayerXP[id][player] < LEVELS[6])
		PlayerLevel[id][player] = 6;
	else if(PlayerXP[id][player] >= LEVELS[6] && PlayerXP[id][player] < LEVELS[7])
		PlayerLevel[id][player] = 7;
	else if(PlayerXP[id][player] >= LEVELS[7] && PlayerXP[id][player] < LEVELS[8])
		PlayerLevel[id][player] = 8;
	else if(PlayerXP[id][player] >= LEVELS[8] && PlayerXP[id][player] < LEVELS[9])
		PlayerLevel[id][player] = 9;
	else if(PlayerXP[id][player] >= LEVELS[9])
		PlayerLevel[id][player] = 10;

	if(oldLevel != PlayerLevel[id][player])
		InitLevel(id);

	new skillsused = PlayerSkill1[id][player] + PlayerSkill2[id][player] + PlayerSkill3[id][player] + PlayerPowerUp[id][player]
	if(skillsused < PlayerLevel[id][player])
		ShowSkill(id);
	else if(skillsused > PlayerLevel[id][player])
		SkillsOver(id);

	return PLUGIN_CONTINUE;
}

public SkillsOver(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id))
		return PLUGIN_HANDLED;

	new player = PlayerChar[id];

	new skillsused = PlayerSkill1[id][player] + PlayerSkill2[id][player] + PlayerSkill3[id][player] + PlayerPowerUp[id][player]
	if(skillsused <= PlayerLevel[id][player])
		return PLUGIN_HANDLED;

	if(PlayerLevel[id][player] < 6)
	{
		if(PlayerPowerUp[id][player])
			PlayerPowerUp[id][player] = 0;
	}
	else if(PlayerSkill1[id][player] > 0)
		PlayerSkill1[id][player]--;

	else if(PlayerSkill2[id][player] > 0)
		PlayerSkill2[id][player]--;

	else if(PlayerSkill3[id][player] > 0)
		PlayerSkill3[id][player]--;

	skillsused = PlayerSkill1[id][player] + PlayerSkill2[id][player] + PlayerSkill3[id][player] + PlayerPowerUp[id][player];
	if(skillsused < PlayerLevel[id][player])
		ShowSkill(id);
	else if(skillsused > PlayerLevel[id][player])
		SkillsOver(id);

	return PLUGIN_CONTINUE;
}
// Client Commands
public TimerAll()
{
	if(!Nintendo_Active())
		return PLUGIN_HANDLED;

	PowerUpTimer();

	return PLUGIN_CONTINUE;
}

public PowerUpTimer()
{
	if(!Nintendo_Active())
		return PLUGIN_HANDLED;

	new players[32], num, id;
	get_players(players, num);
	for(new i = 0; i <= num; i++)
	{
		id = players[i];
		if(Nintendo_IsValidPlayer(id))
		{
			if(PowerUpTime[id] > 0 && PlayerPowerUp[id][PlayerChar[id]])
				PowerUpTime[id]--;
			else if(PowerUpTime[id] == 0 && PlayerPowerUp[id][PlayerChar[id]])
			{
				if(!PowerUpUsed[id])
					continue;

				PowerUpUsed[id] = false;
				Nintendo_StatusHUD(id, "PowerUp Ready.");
				client_cmd(id, "play nintendomod/powerup.wav")
			}
		}
	}

	return PLUGIN_CONTINUE;
}

public PowerUpKeyDown(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id) || BetweenRounds)
		return PLUGIN_HANDLED;

	if(!PowerUpUsed[id] && PowerUpTime[id] == 0 && PlayerPowerUp[id][PlayerChar[id]])
	{
		if(!equali(AllKeyDown[PlayerChar[id]], ""))
			server_cmd("%s %d", AllKeyDown[PlayerChar[id]], id);
	}
	else if(PowerUpUsed[id] && PowerUpTime[id] > 0 && PlayerPowerUp[id][PlayerChar[id]])
	{
		new temp[55];
		format(temp, 54, "PowerUp not ready.^n(%d seconds remaining)", PowerUpTime[id]);
		Nintendo_StatusHUD(id, temp);
		client_cmd(id, "play nintendomod/powerupfail.wav");
	}
	else if(PlayerPowerUp[id][PlayerChar[id]] == 0)
	{
		Nintendo_StatusHUD(id, "PowerUp not available.");
		client_cmd(id, "play nintendomod/powerupfail.wav");
	}

	return PLUGIN_CONTINUE;
}

public PowerUpKeyUp(id)
{
	if(!Nintendo_Active() || !Nintendo_IsValidPlayer(id) || BetweenRounds)
		return PLUGIN_HANDLED;

	if(!PowerUpUsed[id] && PowerUpTime[id] == 0 && PlayerPowerUp[id][PlayerChar[id]] == 1)
	{
		if(!equali(AllKeyUp[PlayerChar[id]], ""))
			server_cmd("%s %d", AllKeyUp[PlayerChar[id]], id);
	}

	return PLUGIN_CONTINUE;
}

public HandleSay(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_CONTINUE;

	new say[31];
	read_argv(1, say, 30);
	remove_quotes(say);

	if(equali(say, "/changechar") || equali(say, "changechar"))
		ShowCharacter(id, 0);
	else if(equali(say, "/selectskills") || equali(say, "selectskills"))
		SelectSkills(id);
	else if(equali(say, "/resetskills") || equali(say, "resetskills"))
		ResetSkills(id);
	else if(equali(say, "/playerlevels") || equali(say, "playerlevels"))
		PlayerLevels(id);
	else if(equali(say, "/playerskills") || equali(say, "playerskills"))
		PlayerSkills(id);
	else if(equali(say, "/skillsinfo") || equali(say, "skillsinfo"))
		SkillsInfo(id);
	else if(equali(say, "/characterhelp") || equali(say, "characterhelp"))
		ShowCharacterHelp(id, 0);
	else if(equali(say, "/help") || equali(say, "help") || equali(say, "/nintendohelp") || equali(say, "nintendohelp"))
		PlayerHelp(id);
	/*else if(equali(say, "/shopmenu1") || equali(say, "shopmenu1"))
		ShowShopMenu1(id);
	else if(equali(say, "/shopmenu2") || equali(say, "shopmenu2"))
		ShowShopMenu2(id);*/
	else
		return PLUGIN_CONTINUE;

	return PLUGIN_HANDLED;
}

public PlayerLevels(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new name[32], buffer[1501], temp[512];
	new len = 1500, n = 0;

	n += copy(buffer[n], len-n, MOTD_HEADER);

	for(new team = 1; team <= 2; team++)
	{
		if(team == 1)
			n += copy(buffer[n], len-n, "<h1>Terrorist:</h1>");
		else
			n += copy(buffer[n], len-n, "<h1>Counter-Terrorist:</h1>");

		new players[32], num, id;
		get_players(players, num);
		for(new i = 0; i <= num; i++)
		{
			id = players[i];
			if(is_user_connected(id))
			{
				if(get_user_team(id) == team)
				{
					get_user_name(id, name, 31);
					format(temp, 511, "%s: Character: %s - Level: %d - XP: %d<br />", name, AllChars[PlayerChar[id]], PlayerLevel[id][PlayerChar[id]], PlayerXP[id][PlayerChar[id]]);
					n += copy(buffer[n], len-n, temp);
				}
			}
		}
	}

	n += copy(buffer[n],len-n, MOTD_FOOTER);

	show_motd(id, buffer, "Nintendo Mod Characters");

	return PLUGIN_CONTINUE;
}

public PlayerSkills(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new name[32], buffer[1501], temp[512];
	new len = 1500, n = 0;

	n += copy(buffer[n], len-n, MOTD_HEADER);

	for(new team = 1; team <= 2; team++)
	{
		if(team == 1)
			n += copy(buffer[n], len-n, "<h1>Terrorist:</h1>");
		else
			n += copy(buffer[n], len-n, "<h1>Counter-Terrorist:</h1>");

		new players[32], num, id;
		get_players(players, num);
		for(new i = 0; i <= num; i++)
		{
			id = players[i];
			if(is_user_connected(id))
			{
				if(get_user_team(id) == team)
				{
					get_user_name(id, name, 31);
					format(temp, 511, "%s: %s: %d - %s: %d - %s: %d - %s: %d<br />", name, AllSkill1[PlayerChar[id]], PlayerSkill1[id][PlayerChar[id]], AllSkill2[PlayerChar[id]], PlayerSkill2[id][PlayerChar[id]], AllSkill3[PlayerChar[id]], PlayerSkill3[id][PlayerChar[id]], AllPowerUp[PlayerChar[id]], PlayerPowerUp[id][PlayerChar[id]]);
					n += copy(buffer[n], len-n, temp);
				}
			}
		}
	}

	n += copy(buffer[n],len-n, MOTD_FOOTER);

	show_motd(id, buffer, "Nintendo Mod Characters");

	return PLUGIN_CONTINUE;
}

public SelectSkills(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new skillsused = PlayerSkill1[id][PlayerChar[id]] + PlayerSkill2[id][PlayerChar[id]] + PlayerSkill3[id][PlayerChar[id]] + PlayerPowerUp[id][PlayerChar[id]]
	if(skillsused < PlayerLevel[id][PlayerChar[id]])
		ShowSkill(id);

	return PLUGIN_CONTINUE;
}

public ResetSkills(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	PlayerSkill1[id][PlayerChar[id]] = 0;
	PlayerSkill2[id][PlayerChar[id]] = 0;
	PlayerSkill3[id][PlayerChar[id]] = 0;
	PlayerPowerUp[id][PlayerChar[id]] = 0;

	InitCharacter(id);

	ShowSkill(id);

	ShowHUD(id);
	Nintendo_StatusHUD(id, "Your skills have been reset");

	return PLUGIN_CONTINUE;
}

public SkillsInfo(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new buffer[1501], temp[512];
	new len = 1500, n = 0;

	n += copy(buffer[n], len-n, MOTD_HEADER);

	format(temp, 511, "<h1>%s Help</h1>", AllChars[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllPassive[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllPassiveHelp[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllSkill1[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllSkill1Help[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllSkill2[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllSkill2Help[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllSkill3[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllSkill3Help[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllPowerUp[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllPowerUpHelp[PlayerChar[id]]);
	n += copy(buffer[n], len-n, temp);

	n += copy(buffer[n], len-n, MOTD_FOOTER);

	show_motd(id, buffer, "Nintendo Mod Character Help");

	return PLUGIN_CONTINUE;
}

public ShowCharacterHelp(id, menuOffset)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	characterMenuOffset[id] = 0;

	new charMenu[1801];
	new charKeys;

	if(menuOffset <= 0 || menuOffset > NumAllChars)
		menuOffset = 1;

	characterMenuOffset[id] = menuOffset;

	new len = format(charMenu, 1800, "\rNintendo Mod\r^n");
	len += format(charMenu[len], 1800-len, "\yCharacter Help^n^n");

	for(new x = menuOffset; x < menuOffset + 8; x++)
	{
		if(equali(AllChars[x], ""))
		{
			len += format(charMenu[len], 1801-len, "^n");
			continue;
		}

		len += format(charMenu[len], 1801-len, "\r%d. \w%s^n", x-menuOffset+1, AllChars[x]);

		charKeys |= (1<<x-menuOffset);
	}

	if(NumAllChars > 8)
	{
		len += format(charMenu[len], 1801-len, "^n\r9. \wMore Characters^n");
		charKeys |= (1<<8);
	}
	else
		len += format(charMenu[len], 1801-len, "^n^n");

	// Cancel
	len += format(charMenu[len], 511-len, "\r0. \wCancel");
	charKeys |= (1<<9);

	show_menu(id, charKeys, charMenu, 15, "Character_Help");

	return PLUGIN_HANDLED;
}

public CharacterHelp(id, key)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	if(key == 8)
	{
		ShowCharacterHelp(id, characterMenuOffset[id] + 8);
		return PLUGIN_HANDLED;
	}
	else if(key == 9)
	{
		characterMenuOffset[id] = 0;
		return PLUGIN_HANDLED;
	}

	key += characterMenuOffset[id];

	new buffer[1501], temp[512];
	new len = 1500, n = 0;

	n += copy(buffer[n], len-n, MOTD_HEADER);

	format(temp, 511, "<h1>%s Help</h1>", AllChars[key]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllPassive[key]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllPassiveHelp[key]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllSkill1[key]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllSkill1Help[key]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllSkill2[key]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllSkill2Help[key]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllSkill3[key]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllSkill3Help[key]);
	n += copy(buffer[n], len-n, temp);

	format(temp, 511, "<h2>%s:</h2>", AllPowerUp[key]);
	n += copy(buffer[n], len-n, temp);
	format(temp, 511, "&nbsp&nbsp&nbsp&nbsp %s<br />", AllPowerUpHelp[key]);
	n += copy(buffer[n], len-n, temp);

	n += copy(buffer[n], len-n, MOTD_FOOTER);

	show_motd(id, buffer, "Nintendo Mod Character Help");

	return PLUGIN_CONTINUE;
}

public PlayerHelp(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new buffer[1501];
	new len = 1500, n = 0;

	n += copy(buffer[n], len-n, MOTD_HEADER);

	n += copy(buffer[n], len-n, "<h2>Selecting a Character:</h2>");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp Every character has 1 Passive, 3 Skills, and 1 PowerUp<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp As you level you can select a new skills<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp Once you reach level 6 you can select the powers<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp All skills except the PowerUp are automatic.<br /><br />");

	n += copy(buffer[n], len-n, "<h2>How to use PowerUp:</h2>");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbspEvery Character has a powerup<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbspUsage: bind ^"key^" +powerup<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbspExample: bind z +powerup<br /><br />");

	n += copy(buffer[n], len-n, "<h2>Available Say Commands:</h2>");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /nintendohelp - This help menu<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /changechar - Allows you to change your character<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /selectskills - Allows you to select a skill<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /resetskills - Resets your skills<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /playerlevels - Shows you what level other players are<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /playerskills - Shows you what skills other players have<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /skillsinfo - Current characters skills help<br />");
	n += copy(buffer[n], len-n, "&nbsp&nbsp&nbsp&nbsp say /characterhelp - Character skills help menu<br />");

	n += copy(buffer[n], len-n, "<h2>Official Site: http://nintendomod.soloistsmodcentral.com/</h2><br />");

	n += copy(buffer[n], len-n, MOTD_FOOTER);

	show_motd(id, buffer, "Nintendo Mod Help");

	return PLUGIN_CONTINUE;
}
// ShopMenus
public ShowShopMenu1(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new shopMenu1[1801], shopKeys;

	new len = format(shopMenu1, 1800, "\rNintendo Mod^n");
	len += format(shopMenu1[len], 1800-len, "\yShop Menu1^n");

	len += format(shopMenu1[len], 1800-len, "^n\r1. \wFeather                  $1500");
	len += format(shopMenu1[len], 1800-len, "^n\r2. \wMushroom                 $1500");
	len += format(shopMenu1[len], 1800-len, "^n\r3. \wShrinking Mushroom       $2000");
	len += format(shopMenu1[len], 1800-len, "^n\r4. \wStar                     $2500");
	len += format(shopMenu1[len], 1800-len, "^n\r5. \wFireball                 $3000");
	len += format(shopMenu1[len], 1800-len, "^n\r6. \wEgg                      $3000");
	len += format(shopMenu1[len], 1800-len, "^n\r7. \wGhost                    $4000");
	len += format(shopMenu1[len], 1800-len, "^n\r8. \wLightning                $5000");

	len += format(shopMenu1[len], 1800-len, "^n^n\r0. \wExit");
	shopKeys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_0;

	show_menu(id, shopKeys, shopMenu1, 15, "Shop_Menu1");

	return PLUGIN_CONTINUE;
}

/*public ShopMenu1(id, key)
{
	if(!Nintendo_Active() || !is_user_connected(id) || key == 9)
		return PLUGIN_HANDLED;

	switch(key)
	{
		case 0:
		{
			if(cs_get_user_money(id) < 1500)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Feather");
		}
		case 1:
		{
			if(cs_get_user_money(id) < 1500)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Mushroom");

		}
		case 2:
		{
			if(cs_get_user_money(id) < 2000)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Shrinking Mushroom");

		}
		case 3:
		{
			if(cs_get_user_money(id) < 2500)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Star");

		}
		case 4:
		{
			if(cs_get_user_money(id) < 3000)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Fireball");

		}
		case 5:
		{
			if(cs_get_user_money(id) < 3000)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Egg");

		}

		case 6:
		{
			if(cs_get_user_money(id) < 4000)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Ghost");

		}
		case 7:
		{
			if(cs_get_user_money(id) < 5000)
			{
				Nintendo_StatusHUD(id, "You don't have enough money");
				return PLUGIN_HANDLED;
			}
			Nintendo_StatusHUD(id, "You just bought a Lightning");

		}

	}

	return PLUGIN_CONTINUE;
}

public ShowShopMenu2(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	client_print(id, print_chat, "Shop Menu2 is not done yet");

	new shopMenu2[1801], shopKeys;

	new len = format(shopMenu2, 1800, "\rNintendo Mod^n");
	len += format(shopMenu2[len], 1800-len, "\yShop Menu2^n");

	len += format(shopMenu2[len], 1800-len, "^n\r1. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r2. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r3. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r4. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r5. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r6. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r7. \w ");
	len += format(shopMenu2[len], 1800-len, "^n\r8. \w ");

	len += format(shopMenu2[len], 1800-len, "^n^n\r0. \wExit");
	shopKeys = MENU_KEY_1|MENU_KEY_2|MENU_KEY_3|MENU_KEY_4|MENU_KEY_5|MENU_KEY_6|MENU_KEY_7|MENU_KEY_8|MENU_KEY_0;

	show_menu(id, shopKeys, shopMenu2, 15, "Shop_Menu2");

	return PLUGIN_CONTINUE;
}

public ShopMenu2(id)
{
	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;



	return PLUGIN_CONTINUE;
}*/
// Admin Commands
public GiveXP(id, level, cid)
{
	if(!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED;

	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new target[33], sXP[33];

	read_argv(1, target, 32);
	read_argv(2, sXP, 32);

	new player = Nintendo_FindTarget(id, target);
	new iXP = str_to_num(sXP);

	AddXP(player, iXP);

	new idName[54], playerName[54]
	get_user_name(id, idName, 53);
	get_user_name(player, playerName, 53);
	client_print(0, print_chat, "[Nintendo Mod] %s just gave %s %d xp", idName, playerName, iXP);

	SaveXP(player);
	ShowHUD(player);

	return PLUGIN_CONTINUE;
}

public TakeXP(id, level, cid)
{
	if(!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED;

	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new target[33], sXP[33];

	read_argv(1, target, 32)
	read_argv(2, sXP, 32);

	new player = Nintendo_FindTarget(id, target);
	new iXP = str_to_num(sXP) * -1;

	AddXP(player, iXP);

	new idName[54], playerName[54]
	get_user_name(id, idName, 53);
	get_user_name(player, playerName, 53);
	client_print(0, print_chat, "[Nintendo Mod] %s just took %d xp from %s ", idName, iXP, playerName);

	SaveXP(player);
	ShowHUD(player);

	return PLUGIN_CONTINUE;
}

public GiveLevel(id, level, cid)
{
	if(!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED;

	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new target[33], sLevel[33];

	read_argv(1, target, 32)
	read_argv(2, sLevel, 32);

	new player = Nintendo_FindTarget(id, target);
	new iLevel = str_to_num(sLevel) + PlayerLevel[id][PlayerChar[id]];

	PlayerXP[id][PlayerChar[id]] = LEVELS[iLevel-1];
	PlayerLevel[id][PlayerChar[id]] = iLevel;

	new idName[54], playerName[54]
	get_user_name(id, idName, 53);
	get_user_name(player, playerName, 53);
	client_print(0, print_chat, "[Nintendo Mod] %s just gave %d levels to %s", idName, iLevel, playerName);

	SaveXP(player);
	ShowHUD(player);

	return PLUGIN_CONTINUE;
}

public SetLevel(id, level, cid)
{
	if(!cmd_access(id, level, cid, 2))
		return PLUGIN_HANDLED;

	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new target[33], sLevel[33];

	read_argv(1, target, 32)
	read_argv(2, sLevel, 32);

	new player = Nintendo_FindTarget(id, target);
	new iLevel = str_to_num(sLevel);

	PlayerXP[id][PlayerChar[id]] = LEVELS[iLevel-1];
	PlayerLevel[id][PlayerChar[id]] = iLevel;

	new idName[54], playerName[54]
	get_user_name(id, idName, 53);
	get_user_name(player, playerName, 53);
	client_print(0, print_chat, "[Nintendo Mod] %s just set %s level to %d", idName, playerName, iLevel);

	SaveXP(player);
	ShowHUD(player);

	return PLUGIN_CONTINUE;
}

public ResetXP(id, level, cid)
{
	if(!cmd_access(id, level, cid, 1))
		return PLUGIN_HANDLED;

	if(!Nintendo_Active() || !is_user_connected(id))
		return PLUGIN_HANDLED;

	new target[32];

	read_argv(1, target, 32)

	new player = Nintendo_FindTarget(id, target);

	PlayerChar[player] = CLASS_NONE;

	for(new i = 1; i < MAXCHARS; i++)
	{
		PlayerLevel[player][i] = 0;
		PlayerXP[player][i] = 0;
		PlayerSkill1[player][i] = 0;
		PlayerSkill2[player][i] = 0;
		PlayerSkill3[player][i] = 0;
		PlayerPowerUp[player][i] = 0;
	}

	new idName[54], playerName[54]
	get_user_name(id, idName, 53);
	get_user_name(player, playerName, 53);
	client_print(0, print_chat, "[Nintendo Mod] %s just reset all of %s xp", idName, playerName);

	ResetXPAll(player);
	ShowHUD(player);

	return PLUGIN_CONTINUE;
}

// Natives
public native_RegisterChar(id, numParms)
{ // name, passive, skill1, skill2, skill3, powerup, init
	if(numParms != 7)
		return log_error(10, "Bad native parameters");

	if(NumAllChars == 0)
	{
		copy(AllChars[NumAllChars], 32, "None");
		copy(AllPassive[NumAllChars], 32, "None");
		copy(AllSkill1[NumAllChars], 32, "None");
		copy(AllSkill2[NumAllChars], 32, "None");
		copy(AllSkill3[NumAllChars], 32, "None");
		copy(AllPowerUp[NumAllChars], 32, "None");
		copy(AllInit[NumAllChars], 32, "None");
	}

	NumAllChars++;

	new name[33], passive[33], skill1[33], skill2[33], skill3[33], powerup[33], init[33];

	get_string(1, name, 32);
	get_string(2, passive, 32);
	get_string(3, skill1, 32);
	get_string(4, skill2, 32);
	get_string(5, skill3, 32);
	get_string(6, powerup, 32);
	get_string(7, init, 32);

	copy(AllChars[NumAllChars], 32, name);
	copy(AllPassive[NumAllChars], 32, passive);
	copy(AllSkill1[NumAllChars], 32, skill1);
	copy(AllSkill2[NumAllChars], 32, skill2);
	copy(AllSkill3[NumAllChars], 32, skill3);
	copy(AllPowerUp[NumAllChars], 32, powerup);
	copy(AllInit[NumAllChars], 32, init);

	return PLUGIN_CONTINUE;
}

public native_RegisterHelp(id, numParms)
{ // charName, passiveHelp, skill1Help, skill2Help, skill3Help, powerupHelp
	if(numParms != 6)
		return log_error(10, "Bad native parameters");

	if(NumAllChars == 0)
	{
		copy(AllPassiveHelp[NumAllChars], 32, "None");
		copy(AllSkill1Help[NumAllChars], 32, "None");
		copy(AllSkill2Help[NumAllChars], 32, "None");
		copy(AllSkill3Help[NumAllChars], 32, "None");
		copy(AllPowerUpHelp[NumAllChars], 32, "None");
	}

	NumAllHelp++;

	new charName[33], passiveHelp[512], skill1Help[512], skill2Help[512], skill3Help[512], powerupHelp[512];

	get_string(1, charName, 32);
	get_string(2, passiveHelp, 511);
	get_string(3, skill1Help, 511);
	get_string(4, skill2Help, 511);
	get_string(5, skill3Help, 511);
	get_string(6, powerupHelp, 511);

	for(new i = 0; i <= NumAllChars; i++)
	{
		if(equali(charName, AllChars[i]))
		{
			copy(AllPassiveHelp[NumAllHelp], 511, passiveHelp);
			copy(AllSkill1Help[NumAllHelp], 511, skill1Help);
			copy(AllSkill2Help[NumAllHelp], 511, skill2Help);
			copy(AllSkill3Help[NumAllHelp], 511, skill3Help);
			copy(AllPowerUpHelp[NumAllHelp], 511, powerupHelp);
		}
	}

	return PLUGIN_CONTINUE;
}

public native_RegisterKeyDown(id, numParms)
{ // CharName, KeyDown
	if(numParms != 2)
		return log_error(10, "Bad native parameters");

	new charName[33], keyDown[33];

	get_string(1, charName, 32);
	get_string(2, keyDown, 32);

	for(new i = 0; i <= NumAllChars; i++)
	{
		if(equali(charName, AllChars[i]))
			copy(AllKeyDown[i], 32, keyDown);
	}

	return PLUGIN_CONTINUE;
}
public native_RegisterKeyUp(id, numParms)
{ // CharName, KeyUp
	if(numParms != 1)
		return log_error(10, "Bad native parameters");

	new charName[33], keyUp[33];

	get_string(1, charName, 32);
	get_string(2, keyUp, 32);

	for(new i = 0; i <= NumAllChars; i++)
	{
		if(equali(charName, AllChars[i]))
			copy(AllKeyUp[i], 32, keyUp);
	}

	return PLUGIN_CONTINUE;
}

public native_GetUserChar(id, numParms)
{ // id, class[], len
	if(numParms != 3)
		return log_error(10, "Bad native parameters");

	new player = get_param(1);

	if(!is_user_connected(player))
		return PLUGIN_HANDLED;

	set_string(2, AllChars[PlayerChar[player]], get_param(3));

	return PLUGIN_CONTINUE;
}

public native_PowerUpUsed(id, numParms)
{ // id, powerUpUsed, coolDownTime
	if(numParms != 3)
		return log_error(10, "Bad native parameters");

	new id = get_param(1);
	new powerUpUsed = get_param(2);
	new coolDownTime = get_param(3);

	if(powerUpUsed == 1)
	{
		PowerUpUsed[id] = true;
		PowerUpTime[id] = coolDownTime;
	}

	return PLUGIN_CONTINUE;
}

public native_PowerUpDeny(id, numParms)
{ // id, msg[]
	if(numParms != 2)
		return log_error(10, "Bad native parameters");

	new id = get_param(1);
	new msg[55];
	get_string(2, msg, 54);

	client_cmd(id, "play nintendomod/powerupdeny.wav");
	Nintendo_StatusHUD(id, msg);

	return PLUGIN_CONTINUE;
}

public native_ExtraDamage(id, numParms)
{ // attacker, victim, damage, weaponDescription[], headshot, dmgType = DMG_BULLET, ff = -1
	if(numParms != 7)
		return log_error(10, "Bad native parameters");

	new attacker = get_param(1);
	new victim = get_param(2);
	new damage = get_param(3);
	new weaponDescription[32];
	get_string(4, weaponDescription, 31);
	new headshot = get_param(5);
	new dmgType = get_param(6);
	new FFon = get_param(7);
	if(FFon == -1) FFon = get_cvar_num("mp_friendlyfire");
	if(!is_user_alive(victim) || !is_user_connected(attacker)) return PLUGIN_HANDLED;
	if(pev(victim, pev_takedamage) == 0.0) return PLUGIN_HANDLED;
	if(damage <= 0) return PLUGIN_HANDLED;

	new Float:flNewDamage = float(damage) * 0.2;
	new Float:flArmor = (float(damage) - flNewDamage) * 0.5;
	new armortype = pev(victim, pev_armortype);
	new plrArmor = pev(victim, pev_armorvalue);

	if(flArmor > float(plrArmor))
	{
		flArmor = float(plrArmor);
		flArmor *= 2;
		flNewDamage = float(damage) - flArmor;
		plrArmor = 0;
	}
	else
		plrArmor = floatround(plrArmor - flArmor);

	new userHealth = pev(victim, pev_health);
	if(userHealth - damage <= 0 )
	{
		new bool:kill = false;
		new Float:frags;
		pev(attacker, pev_frags, frags);

		if(victim == attacker)
			kill = true;
		else if(FFon && get_user_team(victim) == get_user_team(attacker))
		{
			kill = true;
			set_pev(attacker, pev_frags, floatsub(frags, 1.0));
			client_print(attacker, print_center, "You killed a teammate");
			new money = cs_get_user_money(attacker);
			if(money != 0) cs_set_user_money(attacker, money - 150, 1);
		}
		else if(get_user_team(victim) != get_user_team(attacker))
		{
			kill = true;
			set_pev(attacker, pev_frags, floatadd(frags, 1.0));
			new money = cs_get_user_money(attacker);
			if(money < 16000) cs_set_user_money(attacker, money + 300, 1);
		}

		if(!kill) return PLUGIN_HANDLED;

		AddXP(attacker, 15);

		gBlockDeathMsg = 1;
		user_kill(victim, 1);

		message_begin(MSG_ALL, get_user_msgid("DeathMsg"));
		write_byte(attacker);
		write_byte(victim);
		write_byte(headshot);
		write_string(weaponDescription);
		message_end();

		message_begin(MSG_ALL, get_user_msgid("ScoreInfo"));
		write_byte(attacker);
		write_short(get_user_frags(attacker));
		write_short(get_user_deaths(attacker));
		write_short(0);
		write_short(get_user_team(attacker));
		message_end();

		message_begin(MSG_ALL, get_user_msgid("ScoreInfo"));
		write_byte(victim);
		write_short(get_user_frags(victim));
		write_short(get_user_deaths(victim));
		write_short(0);
		write_short(get_user_team(victim));
		message_end();

	}
	else
	{
		new bool:hurt = false;
		if(victim == attacker)
			hurt = true;
		else if(FFon && get_user_team(victim) == get_user_team(attacker))
		{
			hurt = true;
			new name[33];
			get_user_name(attacker,name,32);
			client_print(0,print_chat,"%s attacked a teammate",name);
		}
		else if(get_user_team(victim) != get_user_team(attacker))
			hurt = true;

		if(!hurt)
			return 0;

		if(userHealth - damage > 0)
		{
			set_pev(victim, pev_health, float(userHealth - damage));
			set_pev(victim, pev_armorvalue, plrArmor);
			set_pev(victim, pev_armortype, armortype);
		}
		else
		{
			gBlockDeathMsg = 1;
			user_kill(victim, 1);
		}

		new aOrigin[3];
		pev(attacker, pev_origin, aOrigin);

		message_begin(MSG_ONE, get_user_msgid("Damage"), {0, 0, 0}, victim);
		write_byte(0);
		write_byte(damage);
		write_long(dmgType);
		write_coord(aOrigin[0]);
		write_coord(aOrigin[1]);
		write_coord(aOrigin[2]);
		message_end();
	}

	return PLUGIN_CONTINUE;
}
// Blocks fullupdate command
public FullUpdate(id)
{
	//This blocks "fullupdate" from resetting the HUD and doing bad things to heroes
	return PLUGIN_HANDLED
}
// Message Blocks
public hook_messagebegin(msg_dest, msg_type, Float:origin[3], ed)
{
	if(gBlockDeathMsg && msg_type == get_user_msgid("DeathMsg"))
	{
		gInBlock = 1;
		return FMRES_SUPERCEDE;
	}
	return FMRES_IGNORED
}
public hook_writebyte(value) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writechar(value) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writeshort(value) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writelong(value) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writeangle(value) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writecoord(Float:value) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writestring(sz[]) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_writeent(ent) { return (gInBlock ? FMRES_SUPERCEDE : FMRES_IGNORED); }
public hook_messageend()
{
	if (gInBlock)
	{
		gInBlock = 0;
		gBlockDeathMsg = 0;
		return FMRES_SUPERCEDE;
	}
	return FMRES_IGNORED;
}
