/* AMX MOD X
*   Matrix Mod - cmds.inl
*
* (c) Copyright 2006 by Knekter
*
* This file is provided as is (no warranties)
*/

public hook_say(id)
{
	if(!MM_is_active())
		return PLUGIN_CONTINUE;

	new message[64];
	read_args(message, 63);
	replace(message, 63, "/", "");

	if(equali(message, "changeclass"))
	{
		if(!is_user_alive(id))
			MM_MENU_show(id);
		else
			client_print(id, print_center, "[MM] You must be dead to use this command!");

		return PLUGIN_HANDLED;
	}

	return PLUGIN_CONTINUE;
}

public clcmd_xp(id, level, cid)
{
	if(!cmd_access(id, level, cid, 3))
		return PLUGIN_HANDLED;

	// Get target and amount
	new target[24], amount[5];
	read_argv(1, target, 23);
	read_argv(2, amount, 4);

	// Get player
	new player = cmd_target(id, target, 2);
	new xp = str_to_num(amount);

	if(xp > 5000)
		xp = 5000;
	else if(xp < 0)
		xp = 0;

	// Set new XP and get new level
	MM_set_pdata(player, pdata_xp, xp);
	MM_XP_getlevel(player, xp);

	// Show player info?
	if(is_user_alive(player))
		MM_UTIL_showinfo(player);

	return PLUGIN_HANDLED;
}

public clcmd_level(id, level, cid)
{
	if(!cmd_access(id, level, cid, 3))
		return PLUGIN_HANDLED;

	// Get target and level
	new target[24], level[2];
	read_argv(1, target, 23);
	read_argv(2, level, 1);

	// Get player
	new player = cmd_target(id, target, 2);
	new plevel = str_to_num(level);

	if(plevel > 8)
		plevel = 8;
	else if(plevel < 0)
		plevel = 0;

	// Set new level
	MM_set_pdata(player, pdata_level, plevel);

	new xp;

	// Calculate XP
	if(plevel == 0)
		xp = 0;
	else
		xp = g_levels[plevel];

	// Set new XP
	MM_set_pdata(player, pdata_xp, xp);

	// Show player info?
	if(is_user_alive(player))
		MM_UTIL_showinfo(player);

	return PLUGIN_HANDLED;
}

public clcmd_class(id, level, cid)
{
	if(!cmd_access(id, level, cid, 3))
		return PLUGIN_HANDLED;

	// Get target and class
	new target[24], class[2];
	read_argv(1, target, 23);
	read_argv(2, class, 1);

	// Get player
	new player = cmd_target(id, target, 2);

	if(is_user_alive(player))
	{
		console_print(id, "[MM] Target cannot be alive!");
		return PLUGIN_HANDLED;
	}

	new pclass = str_to_num(class);
	MM_set_pdata(player, pdata_class, pclass);

	return PLUGIN_HANDLED;
}

public clcmd_power(id)
{
	if(!MM_is_active())
		return PLUGIN_HANDLED;

	// User not alive?
	if(!is_user_alive(id))
	{
		client_print(id, print_center, "[MM] You must be alive to use your power!");
		return PLUGIN_HANDLED;
	}

	// Get the players class
	new class = MM_get_pdata(id, pdata_class);

	// Check if power exists / make sure user is not a human
	if(MM_get_pdata(id, pdata_power) == 0 || class == human || task_exists(id + 5667))
		return PLUGIN_HANDLED;

	MM_set_pdata(id, pdata_power, 0);

	// Get user power time
	new time = MM_get_pdata(id, pdata_time1);

	switch(class)
	{
		case neo:
		{
			set_user_godmode(id, 1);
			set_user_rendering(id, kRenderFxGlowShell, 0, 255, 0, kRenderGlow, 160);
			client_print(id, print_center, "[MM] You extend your hand and begin evading damage!");
		}

		case smith:
		{
			new rand = random_num(0, 3);

			// Change skin accordingly
			if(get_user_team(id) == 1)
				cs_set_user_model(id, g_ctmodels[rand]);
			else
				cs_set_user_model(id, g_tmodels[rand]);

			set_user_footsteps(id, 0);
			MM_set_pdata(id, pdata_disguised, 1);
			client_print(id, print_center, "[MM] You have disguised yourself. Choose your victim wisely!");
		}

		case machine: client_print(id, print_center, "[MM] Energy beam initiated!");

		case twins:
		{
			set_user_health(id, get_user_health(id) + 5);
			set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 130);
			client_print(id, print_center, "[MM] Your wounds begin to heal!");
		}
	}

	new param[2];
	param[0] = id;
	param[1] = 1;
	set_task(1.0, "handle_command", id + 3475, param, 2, "b", 5);

	MM_UTIL_showtime(id, time, true);
	MM_set_pdata(id, pdata_time1, time - 1);

	return PLUGIN_HANDLED;
}

public clcmd_ultimate(id)
{
	if(!MM_is_active())
		return PLUGIN_HANDLED;

	// User not alive?
	if(!is_user_alive(id))
	{
		client_print(id, print_center, "[MM] You must be alive to use your ultimate!");
		return PLUGIN_HANDLED;
	}

	// Get the players class and level
	new class = MM_get_pdata(id, pdata_class);
	new level = MM_get_pdata(id, pdata_level);

	// Check if power exists / make sure user is not a human and at req. level
	if(MM_get_pdata(id, pdata_ultimate) == 0 || class == human || task_exists(id + 3475) || level < 5)
		return PLUGIN_HANDLED;

	MM_set_pdata(id, pdata_ultimate, 0);

	// Get user power time
	new time = MM_get_pdata(id, pdata_time2);

	switch(class)
	{
		case neo:
		{
			// If bullet time is on give ultimate back
			if(g_bullettime == true)
			{
				MM_set_pdata(id, pdata_ultimate, 1);
				client_print(id, print_center, "[MM] Your mind seems to already see enemy fire?");
				return PLUGIN_HANDLED;
			}

			g_bullettime = true;

			// Get all alive players
			new players[32], num, p, pid;
			get_players(players, num, "a");

			// Loop through and set properties
			for(p = 0; p < num; p++)
			{
				pid = players[p];
				set_user_hitzones(pid, 0, 0);
				set_user_hitzones(0, pid, 0);

				if(pid != id)
					set_user_maxspeed(pid, 240.0);
			}
		}

		case smith:
		{
			// Check to see if he has saved an origin
			if(g_origin[id][0] == 0 && g_origin[id][1] == 0 && g_origin[id][2] == 0)
			{
				get_user_origin(id, g_origin[id], 0);
				client_print(id, print_center, "[MM] You focus hard and remember your current location!");
				return PLUGIN_HANDLED;
			}

			// Reset ultimate and set origin
			MM_set_pdata(id, pdata_ultimate, 1);
			set_user_origin(id, g_origin[id]);
			return PLUGIN_HANDLED;
		}

		case machine:
		{
			// Create the rocket
			MM_ENT_create(id, ent_rocket, -1);
			return PLUGIN_HANDLED;
		}

		case twins:
		{
			// Set hitzones, noclip and transparency
			set_user_hitzones(0, id, 0);
			set_user_noclip(id, 1);
			set_user_rendering(id, kRenderFxNone, 0, 0, 0, kRenderNormal, 130);
			client_print(id, print_center, "[MM] You slowly fade into the walls ready to strike!");
		}
	}

	new param[2];
	param[0] = id;
	param[1] = 2;
	set_task(1.0, "handle_command", id + 5667, param, 2, "b", 5);

	MM_UTIL_showtime(id, time, true);
	MM_set_pdata(id, pdata_time2, time - 1);

	return PLUGIN_HANDLED;
}

public handle_command(param[2])
{
	new id = param[0];
	new type = param[1];

	// Get user class
	new class = MM_get_pdata(id, pdata_class);

	// For matrix power?
	if(type == 1)
	{
		// Get and show time
		new time = MM_get_pdata(id, pdata_time1);
		MM_UTIL_showtime(id, time, false);

		// Times up?
		if(time < 0)
		{
			switch(class)
			{
				case neo:
				{
					set_user_godmode(id, 0);
					set_user_rendering(id);
				}

				case smith:
				{
					cs_reset_user_model(id);
					set_user_footsteps(id, 1);
				}

				case twins: set_user_rendering(id);
			}
		}
		else
		{
			if(class == twins)
				set_user_health(id, get_user_health(id) + 5);

			// Decrease time and show it
			time--;
			MM_set_pdata(id, pdata_time1, time);
		}
	}
	else if(type == 2)
	{
		// Get and show time
		new time = MM_get_pdata(id, pdata_time2);
		MM_UTIL_showtime(id, time, false);

		// Times up?
		if(time < 0)
		{
			switch(class)
			{
				case neo:
				{
					// Turn bullet time off
					g_bullettime = false;
					new players[32], num, p, pid;
					get_players(players, num);

					// Reset player properties
					for(p = 0; p < num; p++)
					{
						pid = players[p];
						set_user_hitzones(pid, 0, 255);
						set_user_hitzones(0, pid, 255);
						set_user_maxspeed(pid, 320.0);
					}
				}

				case twins:
				{
					// Remove no clip
					set_user_hitzones(0, id, 255);
					set_user_noclip(id, 0);
					set_user_rendering(id);

					get_user_origin(id, g_origin[id], 0);
					g_origin[id][2] += 5;

					// Check if user is stuck in wall
					set_task(0.3, "hook_stuck", id);
				}
			}
		}
		else
		{
			time--;
			MM_set_pdata(id, pdata_time2, time);
		}
	}
}

public hook_stuck(id)
{
	new origin[3];
	get_user_origin(id, origin, 0);

	if(origin[0] == g_origin[id][0] && origin[1] == g_origin[id][1] && origin[2] == g_origin[id][2])
		MM_kill(id, id, "", 0);

	client_print(id, print_center, "[MM] You lost your concentration and materialized in a wall!");
}