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

stock MM_ENT_create(id, type, weapon)
{
	// Create the entity
	new ent = create_entity("info_target");
	if(ent > 0)
	{
		// Get player origin
		new iorigin[3], Float:forigin[3];
		get_user_origin(id, iorigin, 0);
		IVecFVec(iorigin, forigin);

		new weapname[32], Float:angles[3], Float:velocity[3];

		switch(type)
		{
			// Create a matrix bullet
			case ent_bullet:
			{
				get_weaponname(weapon, weapname, 31);
				replace(weapname, 31, "weapon_", "");

				entity_set_string(ent, EV_SZ_classname, "bullet");
				entity_set_string(ent, EV_SZ_targetname, weapname);
				entity_set_model(ent, "models/shell.mdl");

				velocity_by_aim(id, ((weapon == CSW_AWP) ? 5000 : 800), velocity);
				vector_to_angle(velocity, angles);

				entity_set_size(ent, Float:{-1.0, -1.0, -1.0}, Float:{1.0, 1.0, 1.0});
			}

			// Create a matrix rocket
			case ent_rocket:
			{
				entity_set_string(ent, EV_SZ_classname, "rocket");
				entity_set_model(ent, "models/rpgrocket.mdl");

				velocity_by_aim(id, 2000, velocity);
				vector_to_angle(velocity, angles);

				entity_set_size(ent, Float:{-2.0, -2.0, -2.0}, Float:{2.0, 2.0, 2.0});
			}
		}

		// Set entity properties
		entity_set_int(ent, EV_INT_movetype, MOVETYPE_FLY);
		entity_set_int(ent, EV_INT_solid, SOLID_BBOX);
		entity_set_edict(ent, EV_ENT_owner, id);

		// Set origin and emit sound
		entity_set_origin(ent, forigin);

		if(type == ent_rocket)
			emit_sound(ent, CHAN_WEAPON, "weapons/rocketfire1.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM);

		// Set angles and velocity
		entity_set_vector(ent, EV_VEC_angles, angles);
		entity_set_vector(ent, EV_VEC_velocity, velocity);

		// Make color trail
		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(22);			// TE_BEAMFOLLOW
		write_short(ent);		// Entity to follow
		write_short(g_sprites[type]);	// Sprite
		write_byte(10);			// Life

		if(type == ent_rocket)
			write_byte(5);		// Line width
		else
			write_byte(2);

		write_byte(g_colors[type][0]);	// Red
		write_byte(g_colors[type][1]);	// Green
		write_byte(g_colors[type][2]);	// Blue
		write_byte(120);		// Brightness
		message_end();
	}

	return 0;
}

public pfn_touch(ptr, ptd)
{
	if(!MM_is_active())
		return PLUGIN_CONTINUE;

	// Make sure entity is valid
	if(ptr > 0 && is_valid_ent(ptr))
	{
		new ptoucher[32], ptouched[32];
		entity_get_string(ptr, EV_SZ_classname, ptoucher, 31);

		// Make sure entity is valid
		if(ptd > 0 && is_valid_ent(ptd))
			entity_get_string(ptd, EV_SZ_classname, ptouched, 31);

		// Get owner of entity
		new owner = entity_get_edict(ptr, EV_ENT_owner);

		// If matrix bullet
		if(equal(ptoucher, "bullet"))
		{
			if(equal(ptouched, "player") && get_user_godmode(ptd) == 0)
			{
				new target[32];
				entity_get_string(ptr, EV_SZ_targetname, target, 31);

				// Calculate damage
				new damage = random_num(15, 25);

				if(equal(target, "scout") || equal(target, "sg550") || equal(target, "g3sg1"))
					damage = random_num(45, 75);
				else if(equal(target, "awp"))
					damage = random_num(85, 100);

				new team1 = get_user_team(owner), team2 = get_user_team(ptd);

				// Follow friendly fire rules
				if(team1 != team2 || (team1 == team2 && get_cvar_num("mp_friendlyfire") == 1))
				{
					if(damage >= get_user_health(ptd))
						MM_kill(owner, ptd, target, 0);
					else
						MM_damage(owner, ptd, target, damage, DMG_BULLET);
				}
			}

			remove_entity(ptr);
		}
		else if(equal(ptoucher, "rocket"))
		{
			new Float:hitorigin[3];
			entity_get_vector(ptr, EV_VEC_origin, hitorigin);

			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(3);					// TE_EXPLOSION
			write_coord(floatround(hitorigin[0]));		// X
			write_coord(floatround(hitorigin[1]));		// Y
			write_coord(floatround(hitorigin[2] + 5));	// Z
			write_short(g_sprites[ent_explode]);		// Sprite
			write_byte(random_num(0, 20) + 20);		// Scale
			write_byte(12);					// Framerate
			write_byte(0);					// Flags
			message_end();

			message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
			write_byte(5);					// TE_SMOKE
			write_coord(floatround(hitorigin[0]));		// X
			write_coord(floatround(hitorigin[1]));		// Y
			write_coord(floatround(hitorigin[2]) + 15);	// Z
			write_short(g_sprites[ent_smoke]);		// Sprite
			write_byte(60);					// Scale
			write_byte(10);					// Framerate
			message_end();

			new players[32], porigin[3], horigin[3];
			new num, p, victim, distance, damage, team1, team2;

			// Get all players that are alive
			get_players(players, num, "a");

			for(p = 0; p < num; p++)
			{
				victim = players[p];

				// Be sure they don't have godmode
				if(get_user_godmode(victim) == 0)
				{
					get_user_origin(victim, porigin, 0);
					FVecIVec(hitorigin, horigin);

					// Calculate distance
					distance = get_distance(porigin, horigin);

					// Victim in range?
					if(distance <= 250)
					{
						message_begin(MSG_ONE, get_user_msgid("ScreenShake"), {0, 0, 0}, victim);
						write_short(1<<14);	// Amount
						write_short(1<<14);	// Duration
						write_short(1<<14);	// Frequency
						message_end();

						// Calculate damage
						damage = 150 - floatround(floatmul(150.0, floatdiv(float(distance), 250.0)));

						team1 = get_user_team(owner);
						team2 = get_user_team(victim);

						// Follow friendly fire rules
						if(team1 != team2 || (team1 == team2 && owner == victim) || (team1 == team2 && get_cvar_num("mp_friendlyfire") == 1))
						{
							if(damage >= get_user_health(victim))
								MM_kill(owner, victim, "rocket", 0);
							else
								MM_damage(owner, victim, "rocket", damage, DMG_BLAST);
						}
					}
				}
			}

			remove_entity(ptr);
		}
	}

	return PLUGIN_CONTINUE;
}

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

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

	// Check if power is on
	if(task_exists(id + 3475) && class == smith)
	{
		if(get_user_button(id) & IN_ATTACK)
			MM_remove_tasks(id);
	}
	else if(task_exists(id + 5667) && class == machine)
	{
		new porigin[3], horigin[3];
		get_user_origin(id, porigin, 2);
		get_user_origin(id, horigin, 3);

		message_begin(MSG_BROADCAST, SVC_TEMPENTITY);
		write_byte(0);			// TE_BEAMPOINTS
		write_coord(porigin[0]);	// Start X
		write_coord(porigin[1]);	// Start Y
		write_coord(porigin[2]);	// Start Z
		write_coord(horigin[0]);	// End X
		write_coord(horigin[1]);	// End Y
		write_coord(horigin[2]);	// End Z
		write_short(g_sprites[0]);	// Sprite
		write_byte(1);			// Start frame
		write_byte(10);			// Frame rate
		write_byte(1);			// Life
		write_byte(3);			// Line width
		write_byte(0);			// Noise
		write_byte(255);		// Red
		write_byte(0);			// Green
		write_byte(0);			// Blue
		write_byte(150);		// Brightness
		write_byte(10);			// Scroll speed
		message_end();

		new victim, body;

		// Get distance, victim and body part hit
		new Float:distance = get_user_aiming(id, victim, body);

		// If he is hitting somone
		if(distance > 0.0)
		{
			// Slow them down
			set_user_maxspeed(id, 200.0);

			// Lower their armor
			new armor = get_user_armor(victim) - 1;
			if(armor > 0)
				set_user_armor(victim, armor);
		}
	}

	return PLUGIN_CONTINUE;
}
