#include "napalm.qh"

#ifdef SVQC
void napalm_damage(entity this, float dist, float damage, float edgedamage, float burntime)
{
	if (damage < 0)
		return;

	float d;
	RandomSelection_Init();
	for (entity e = WarpZone_FindRadius(this.origin, dist, true); e; e = e.chain)
		if (e.takedamage == DAMAGE_AIM
		&& (this.realowner != e || autocvar_g_nades_napalm_selfdamage)
		&& (!IS_PLAYER(e) || !this.realowner || DIFF_TEAM(e, this))
		&& !STAT(FROZEN, e))
		{
			vector p = e.origin;
			p.x += e.mins.x + random() * (e.maxs.x - e.mins.x);
			p.y += e.mins.y + random() * (e.maxs.y - e.mins.y);
			p.z += e.mins.z + random() * (e.maxs.z - e.mins.z);
			d = vlen(WarpZone_UnTransformOrigin(e, this.origin) - p);
			if (d < dist)
			{
				e.fireball_impactvec = p;
				RandomSelection_AddEnt(e, 1 / (1 + d), !StatusEffects_active(STATUSEFFECT_Burning, e));
			}
		}
	if (RandomSelection_chosen_ent)
	{
		d = vlen(WarpZone_UnTransformOrigin(RandomSelection_chosen_ent, this.origin) - RandomSelection_chosen_ent.fireball_impactvec);
		d = damage + (edgedamage - damage) * (d / dist);
		Fire_AddDamage(RandomSelection_chosen_ent, this.realowner, d * burntime, burntime, this.projectiledeathtype);
		//trailparticles(this, particleeffectnum(EFFECT_FIREBALL_LASER), this.origin, RandomSelection_chosen_ent.fireball_impactvec);
		Send_Effect(EFFECT_FIREBALL_LASER, this.origin, RandomSelection_chosen_ent.fireball_impactvec - this.origin, 1);
	}
}

void napalm_ball_think(entity this)
{
	if ((round_handler_IsActive() && !round_handler_IsRoundStarted())
	|| time > this.pushltime)
	{
		delete(this);
		return;
	}

	vector midpoint = (this.absmin + this.absmax) * 0.5;
	if (pointcontents(midpoint) == CONTENT_WATER)
	{
		this.velocity *= 0.5;

		if (pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
			this.velocity.z = 200;
	}

	this.angles = vectoangles(this.velocity);

	napalm_damage(this, autocvar_g_nades_napalm_ball_radius, autocvar_g_nades_napalm_ball_damage,
	              autocvar_g_nades_napalm_ball_damage, autocvar_g_nades_napalm_burntime);

	this.nextthink = time + 0.1;
}

void nade_napalm_ball(entity this)
{
	spamsound(this, CH_SHOTS, SND_NADE_NAPALM_FIRE, VOL_BASE, ATTEN_NORM);

	entity proj = new(grenade);
	proj.owner = this.owner;
	proj.realowner = this.realowner;
	proj.team = this.owner.team;
	proj.bot_dodge = true;
	proj.bot_dodgerating = autocvar_g_nades_napalm_ball_damage;
	set_movetype(proj, MOVETYPE_BOUNCE);
	proj.projectiledeathtype = DEATH_NADE_NAPALM.m_id;
	PROJECTILE_MAKETRIGGER(proj);
	setmodel(proj, MDL_Null);
	proj.scale = 1;//0.5;
	setsize(proj, '-4 -4 -4', '4 4 4');
	setorigin(proj, this.origin);
	setthink(proj, napalm_ball_think);
	proj.nextthink = time;
	proj.damageforcescale = autocvar_g_nades_napalm_ball_damageforcescale;
	proj.effects = EF_LOWPRECISION | EF_FLAME;

	vector kick;
	kick.x = autocvar_g_nades_napalm_ball_spread * crandom();
	kick.y = autocvar_g_nades_napalm_ball_spread * crandom();
	kick.z = autocvar_g_nades_napalm_ball_spread * (random() * 0.5 + 0.5);
	proj.velocity = kick;

	proj.pushltime = time + autocvar_g_nades_napalm_ball_lifetime;

	proj.angles = vectoangles(proj.velocity);
	proj.flags = FL_PROJECTILE;
	IL_PUSH(g_projectiles, proj);
	IL_PUSH(g_bot_dodge, proj);
	proj.missile_flags = MIF_SPLASH | MIF_PROXY | MIF_ARC;

	//CSQCProjectile(proj, true, PROJECTILE_NAPALM_FIRE, true);
}

void napalm_fountain_think(entity this)
{
	if ((round_handler_IsActive() && !round_handler_IsRoundStarted())
	|| time >= this.ltime)
	{
		delete(this);
		return;
	}

	vector midpoint = (this.absmin + this.absmax) * 0.5;
	if (pointcontents(midpoint) == CONTENT_WATER)
	{
		this.velocity *= 0.5;

		if (pointcontents(midpoint + '0 0 16') == CONTENT_WATER)
			this.velocity.z = 200;

		UpdateCSQCProjectile(this);
	}

	napalm_damage(this, autocvar_g_nades_napalm_fountain_radius, autocvar_g_nades_napalm_fountain_damage,
	              autocvar_g_nades_napalm_fountain_edgedamage, autocvar_g_nades_napalm_burntime);

	this.nextthink = time + 0.1;
	if (time >= this.nade_special_time)
	{
		this.nade_special_time = time + autocvar_g_nades_napalm_fountain_delay;
		nade_napalm_ball(this);
	}
}

void nade_napalm_boom(entity this)
{
	for (int c = 0; c < autocvar_g_nades_napalm_ball_count; ++c)
		nade_napalm_ball(this);

	entity fountain = new(nade_napalm_fountain);
	fountain.owner = this.owner;
	fountain.realowner = this.realowner;
	fountain.origin = this.origin;
	fountain.flags = FL_PROJECTILE;
	IL_PUSH(g_projectiles, fountain);
	IL_PUSH(g_bot_dodge, fountain);
	setorigin(fountain, fountain.origin);
	setthink(fountain, napalm_fountain_think);
	fountain.nextthink = time;
	fountain.ltime = time + autocvar_g_nades_napalm_fountain_lifetime;
	fountain.pushltime = fountain.ltime;
	fountain.team = this.team;
	set_movetype(fountain, MOVETYPE_TOSS);
	fountain.projectiledeathtype = DEATH_NADE_NAPALM.m_id;
	fountain.bot_dodge = true;
	fountain.bot_dodgerating = autocvar_g_nades_napalm_fountain_damage;
	fountain.nade_special_time = time;
	setsize(fountain, '-16 -16 -16', '16 16 16');
	CSQCProjectile(fountain, true, PROJECTILE_NAPALM_FOUNTAIN, true);
}
#endif // SVQC
#ifdef MENUQC
METHOD(NapalmNade, describe, string(NapalmNade this))
{
	TC(NapalmNade, this);
	PAGE_TEXT_INIT();
	PAR(_("The %s detonates after a short delay, spreading fiery napalm globs around in a fountain. "
	      "The napalm fire balls burn for a while, and damage players who get too close."), COLORED_NAME(this));
	return PAGE_TEXT;
}
#endif // MENUQC
