/*
	Description:
		* Nintendo Mod Includes

	Written By Soloist, updated by Mephisto
	Version 1.3
	Last Updated On 15/06/09

	*************************************************************************************

	Changelog
		Version 1.3
			* added stock Nintendo_FindEntByOwner
		Version 1.2
			* Fixed Nintendo_GetOrigin
		Version 1.1
			* Fixed Nintendo_SetArmor
		Version 1.0
			* Release of the plugin
*/

#define CLASS_NONE 0
#define MAXCHARS 20

new spr_blood_drop, spr_blood_spray, mdl_gib_flesh, mdl_gib_head, mdl_gib_legbone, mdl_gib_lung, mdl_gib_meat, mdl_gib_spine;

// Natives
native Nintendo_RegisterChar(charName[], passive[], passive2[], skill1[], skill2[], skill3[], powerup[], init[]);
native Nintendo_RegisterHelp(charName[], passiveHelp[], passive2Help[], skill1Help[], skill2Help[], skill3Help[], powerupHelp[]);
native Nintendo_RegisterKeyDown(charName[], keyDown[]);
native Nintendo_RegisterKeyUp(charName[], keyUp[]);
native Nintendo_GetUserChar(id, class[], len);
native Nintendo_PowerUpUsed(id, powerUpUsed, coolDownTime);
native Nintendo_PowerUpDeny(id, msg[]);
native Nintendo_ExtraDamage(attacker, victim, damage, weaponDescription[], headshot, dmgType = (1<<1), ff = -1);

// Stocks
stock Nintendo_Active()
{
	if(get_cvar_num("sv_nintendomod"))
		return true;

	return false;
}

stock Nintendo_IsValidPlayer(id, bool:alive=false)
{
	if(!id || !pev_valid(id))
		return 0
	if(!is_user_connected(id))
		return 0
	if(alive == true && !is_user_alive(id))
		return 0
	if(get_user_team(id) != 1 && get_user_team(id) != 2)
		return 0

	return 1
}

stock Nintendo_HasChar(id, charName[])
{
	new class[33];

	Nintendo_GetUserChar(id, class, 32);

	if(equali(class, charName))
		return 1;

	return 0;
}

stock Nintendo_TeamKill(victim, attacker)
{
	if(get_cvar_num("mp_friendlyfire") && get_cvar_num("nm_teamkill"))
		return true;
	else if(!get_cvar_num("mp_friendlyfire") && (get_user_team(attacker) != get_user_team(victim)))
		return true;
	else if(!get_cvar_num("mp_friendlyfire") && (get_user_team(attacker) == get_user_team(victim)))
		return false;

	return true;
}

stock Nintendo_GetMoney(id)
{
	return cs_get_user_money(id);
}

stock Nintendo_SetMoney(id, money)
{
	cs_set_user_money(id, money);
}

stock Float:Nintendo_GetArmor(id)
{
	return pev(id, pev_armorvalue);
}

stock Nintendo_SetArmor(id, Float:armor)
{
	set_pev(id, pev_armorvalue, armor);
}

stock Float:Nintendo_GetGravity(id)
{
	return pev(id, pev_gravity));
}

stock Nintendo_SetGravity(id, Float:grav = 0.0)
{
	set_pev(id, pev_gravity, grav / get_cvar_float("sv_gravity"));
}

stock Nintendo_SetVelocity(id, Float:velocity[3])
{
	set_pev(id, pev_velocity, velocity);
}

stock Nintendo_GetVelocity(id)
{
	new velocity[3];
	pev(id, pev_velocity, velocity);
	return velocity;
}

stock Nintendo_SetOrigin(id, Float:origin[3])
{
	set_pev(id, pev_origin, origin);
}

stock Nintendo_GetOrigin(id)
{
	new Float:forigin[3], origin[3];
	pev(id, pev_origin, forigin);
	origin[0] = floatround(forigin[0]);
	origin[1] = floatround(forigin[1]);
	origin[2] = floatround(forigin[2]);
	return origin;
}

stock Float:Nintendo_GetHealth(id)
{
	return pev(id, pev_health)
}

stock Nintendo_SetHealth(id, Float:health, bool:setMax)
{
	set_pev(id, pev_health, health)
	if(setMax)
		set_pev(id, pev_max_health, health)
}

stock Float:Nintendo_GetSpeed(id)
{
	return pev(id, pev_maxspeed)
}

stock Nintendo_SetSpeed(id, Float:speed = 300.0)
{
	set_pev(id, pev_maxspeed, speed);
}

stock Nintendo_GetDistance(ent1[3], ent2[3])
{
	return get_distance(ent1, ent2);
}

stock Nintendo_FindEntByOwner(index, const classname[], owner, jghgtype = 0)
{
    new strtype[11] = "classname", ent = index
    switch (jghgtype) {
        case 1: strtype = "target"
        case 2: strtype = "targetname"
    }

    while ((ent = engfunc(EngFunc_FindEntityByString, ent, strtype, classname)) && pev(ent, pev_owner) != owner) {}

    return ent
}

stock Nintendo_SetGlow(entity, fx = kRenderFxNone, r = 255, g = 255, b = 255, render = kRenderNormal, amount = 16)
{
	new Float:rgb[3];
	rgb[0] = float(r);
	rgb[1] = float(g);
	rgb[2] = float(b);
	set_pev(entity, pev_renderfx, fx);
	set_pev(entity, pev_rendercolor, rgb);
	set_pev(entity, pev_rendermode, render);
	set_pev(entity, pev_renderamt, float(amount));
	return 1;
}

stock Nintendo_StatusHUD(id, message[], channel)
{
	set_hudmessage(255, 208, 0, -1.0, 0.25, 0, 6.0, 2.5, 0.1, 0.5, channel)
	show_hudmessage(id, message)
}

stock Nintendo_GiveItem(id, const item[])
{
	give_item(id, item);
	/*
	if (!equal(item, "weapon_", 7) && !equal(item, "ammo_", 5) && !equal(item, "item_", 5) && !equal(item, "tf_weapon_", 10))
		return 0

	new ent = engfunc(EngFunc_FindEntityByString, index, "classname", item)
	if (!pev_valid(ent))
		return 0

	new Float:origin[3]
	pev(index, pev_origin, origin)
	set_pev(ent, pev_origin, origin)
	set_pev(ent, pev_spawnflags, pev(ent, pev_spawnflags) | SF_NORESPAWN)
	dllfunc(DLLFunc_Spawn, ent)

	new save = pev(ent, pev_solid)
	dllfunc(DLLFunc_Touch, ent, index)
	if (pev(ent, pev_solid) != save)
		return ent

	engfunc(EngFunc_RemoveEntity, ent)

	return -1*/
}

stock Nintendo_StripUserWeapons(id)
{
	strip_user_weapons(id);
	/*new ent = engfunc(EngFunc_FindEntityByString, index, "classname", "player_weaponstrip")
	if (!pev_valid(ent))
		return 0

	dllfunc(DLLFunc_Spawn, ent)
	dllfunc(DLLFunc_Use, ent, index)
	engfunc(EngFunc_RemoveEntity, ent)

	return 1*/
}

stock Nintendo_Blood(vicorigin[3], attorigin[3], HitPlace)
{
	new Offset[8][3] = {{0,0,15},{0,0,30},{0,0,20},{0,0,12},{2,2,17},{2,2,17},{2,2,5},{2,2,5}}
	new rDistance = get_distance(vicorigin, attorigin)
	new rX = (vicorigin[0] - attorigin[0]) * 300 / rDistance
	new rY = (vicorigin[1] - attorigin[1]) * 300 / rDistance
	new rZ = (vicorigin[2] - attorigin[2]) * 300 / rDistance

	message_begin(MSG_BROADCAST,SVC_TEMPENTITY)
	write_byte(101)
	write_coord(vicorigin[0] + Offset[HitPlace][0])
	write_coord(vicorigin[1] + Offset[HitPlace][1])
	write_coord(vicorigin[2] + Offset[HitPlace][2])
	write_coord(rX)
	write_coord(rY)
	write_coord(rZ)
	write_byte(70)
	write_byte(random_num(100, 200))
	message_end()
}

stock Nintendo_Bleed(vicorigin[3])
{
	// Blood spray
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_BLOODSTREAM)
	write_coord(vicorigin[0])
	write_coord(vicorigin[1])
	write_coord(vicorigin[2] + 10)
	write_coord(random_num(-50, 50)) // x
	write_coord(random_num(-50, 50)) // y
	write_coord(-10) // z
	write_byte(70) // color
	write_byte(random_num(50, 100)) // speed
	message_end()
}

stock Nintendo_Blood_Small(vicorigin[3], num)
{
	// Blood decals
	static const blood_small[7] = {190, 191, 192, 193, 194, 195, 197}

	// Small splash
	for (new j = 0; j < num; j++)
	{
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_WORLDDECAL)
		write_coord(vicorigin[0] + random_num(-100, 100))
		write_coord(vicorigin[1] + random_num(-100, 100))
		write_coord(vicorigin[2] - 36)
		write_byte(blood_small[random_num(0, 6)]) // index
		message_end()
	}
}

stock Nintendo_Blood_Large(vicorigin[3], num)
{
	// Blood decals
	static const blood_large[2] = {204, 205}

	// Large splash
	for (new i = 0; i < num; i++)
	{
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_WORLDDECAL)
		write_coord(vicorigin[0] + random_num(-50, 50))
		write_coord(vicorigin[1] + random_num(-50, 50))
		write_coord(vicorigin[2] - 36)
		write_byte(blood_large[random_num(0, 1)]) // index
		message_end()
	}
}

stock Nintendo_Gib_Explode(vicorigin[3], attorigin[3])
{
	new flesh[3]
	flesh[0] = mdl_gib_flesh
	flesh[1] = mdl_gib_meat
	flesh[2] = mdl_gib_legbone
	new rDistance = get_distance(vicorigin, attorigin)
	new rX = (vicorigin[0] - attorigin[0]) * 150 / rDistance
	new rY = (vicorigin[1] - attorigin[1]) * 150 / rDistance
	new rZ = (vicorigin[2] - attorigin[2]) * 150/rDistance
	// Gib explosion
	// Head
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_MODEL)
	write_coord(vicorigin[0])
	write_coord(vicorigin[1])
	write_coord(vicorigin[2] + 30)
	write_coord(rX + random_num(-20, 20))
	write_coord(rY + random_num(-20, 20))
	write_coord(rZ + random_num(-20, 20))
	write_angle(random_num(0, 360))
	write_short(mdl_gib_head)
	write_byte(0) // bounce
	write_byte(500) // life
	message_end()

	// Spine
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_MODEL)
	write_coord(vicorigin[0])
	write_coord(vicorigin[1])
	write_coord(vicorigin[2] + 20)
	write_coord(rX + random_num(-20, 20))
	write_coord(rY + random_num(-20, 20))
	write_coord(rZ + random_num(-20, 20))
	write_angle(random_num(0, 360))
	write_short(mdl_gib_spine)
	write_byte(0) // bounce
	write_byte(500) // life
	message_end()

	// Lung
	for(new i = 0; i < random_num(1, 2); i++)
	{
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_MODEL)
		write_coord(vicorigin[0])
		write_coord(vicorigin[1])
		write_coord(vicorigin[2] + 10)
		write_coord(rX + random_num(-20, 20))
		write_coord(rY + random_num(-20, 20))
		write_coord(rZ + random_num(-20, 20))
		write_angle(random_num(0, 360))
		write_short(mdl_gib_lung)
		write_byte(0) // bounce
		write_byte(500) // life
		message_end()
	}

	// Parts, 5 times
	for(new i = 0; i < 5; i++)
	{
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
		write_byte(TE_MODEL)
		write_coord(vicorigin[0])
		write_coord(vicorigin[1])
		write_coord(vicorigin[2])
		write_coord(rX +random_num(-20, 20))
		write_coord(rY +random_num(-20, 20))
		write_coord(rZ +random_num(-20, 20))
		write_angle(random_num(0, 360))
		write_short(flesh[random_num(0, 2)])
		write_byte(0) // bounce
		write_byte(500) // life
		message_end()
	}

	// Blood
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_BLOODSPRITE)
	write_coord(vicorigin[0])
	write_coord(vicorigin[1])
	write_coord(vicorigin[2] + 20)
	write_short(spr_blood_spray)
	write_short(spr_blood_drop)
	write_byte(248) // color index
	write_byte(10) // size
	message_end()
}

stock Nintendo_Headshot(vicorigin[3])
{
	message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
	write_byte(TE_BLOODSPRITE)
	write_coord(vicorigin[0])
	write_coord(vicorigin[1])
	write_coord(vicorigin[2] + 30)
	write_short(spr_blood_spray)
	write_short(spr_blood_drop)
	write_byte(248) // color index
	write_byte(10) // size
	message_end()
}

stock Nintendo_ScreenFade(id, duration, holdtime, fadetype, red, green, blue, alpha){

	message_begin(MSG_ONE,get_user_msgid("ScreenFade"),{0,0,0},id)			
	write_short( duration )			// fade lasts this long duration
	write_short( holdtime )			// fade lasts this long hold time
	write_short( fadetype )			// fade type (in / out)
	write_byte( red )				// fade red
	write_byte( green )				// fade green
	write_byte( blue )				// fade blue
	write_byte( alpha )				// fade alpha
	message_end()
}
