Index: effectinfo.txt
===================================================================
--- effectinfo.txt	(revision 7488)
+++ effectinfo.txt	(working copy)
@@ -3960,3 +3960,162 @@
 liquidfriction 3
 originjitter 10 10 25
 velocityjitter 656 656 912
+
+// used nowhere in code
+effect fireball
+count 6
+type smoke
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 5 5
+sizeincrease 20
+ gravity -0.06
+alpha 50 256 250
+bounce 1.5
+velocityjitter 40 40 11
+velocitymultiplier 30
+airfriction 1.2
+//slowfire
+effect fireball
+count 5
+type smoke
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 5 5
+sizeincrease 20
+ gravity -0.06
+alpha 50 256 200
+bounce 1.5
+velocityjitter 40 40 40
+velocitymultiplier 20
+airfriction 1.2
+// very slow and small fire
+effect fireball
+count 3
+type smoke
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 5 5
+sizeincrease 10
+ gravity -0.06
+alpha 50 256 200
+bounce 1.5
+velocityjitter 30 30 30
+velocitymultiplier 10
+airfriction 0.3
+//decreasing fire
+effect fireball
+count 4
+type smoke
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 20 30
+sizeincrease -10
+ gravity -0.06
+alpha 50 256 200
+bounce 1.5
+velocityjitter 10 10 10
+velocitymultiplier 15
+airfriction 0.3
+//smoke
+effect fireball
+count 1
+type alphastatic
+tex 0 8
+size 5 15
+sizeincrease 7
+color 0x000000 0x111111
+alpha 256 256 90
+//gravity -0.2
+originjitter 10 10 10
+velocitymultiplier 20
+velocityoffset 0 0 10
+airfriction 1
+//fastfire
+effect fireball
+count 5
+type smoke
+tex 48 55
+color 0x8f0d00 0xff5a00
+size 64 64
+sizeincrease -100
+ gravity -0.06
+alpha 50 256 800
+bounce 1.5
+velocityjitter 40 40 40
+velocitymultiplier 20
+airfriction 1.2
+
+// fireball
+effect fireball_laser
+countabsolute 1
+type beam
+tex 60 60
+size 1 1
+alpha 256 256 1024
+color 0xffff00 0xffff00
+sizeincrease 1
+
+// rocket explosion (bigger than mortar and hagar)
+// decal
+// used nowhere in code
+effect fireball_explode
+countabsolute 1
+type decal
+tex 8 16
+size 72 72
+alpha 256 256 0
+originjitter 40 40 40
+lightradius 500
+lightradiusfade 500
+lightcolor 4 2 0.5
+// flare effect
+effect fireball_explode
+countabsolute 1
+type static
+tex 35 37
+color 0x404040 0x404040
+size 72 72
+alpha 192 192 64
+// fire effect
+effect fireball_explode
+notunderwater
+count 256
+type static
+tex 48 55
+color 0x902010 0xFFD080
+size 16 16
+alpha 128 128 256
+bounce 1.5
+airfriction 4
+liquidfriction 4
+originjitter 8 8 8
+velocityjitter 512 512 512
+// underwater bubbles
+effect fireball_explode
+underwater
+count 64
+type bubble
+tex 62 62
+color 0x404040 0x808080
+size 3 3
+alpha 128 256 64
+gravity -0.125
+bounce 1.5
+liquidfriction 0.25
+originjitter 16 16 16
+velocityjitter 144 144 144
+// bouncing sparks
+effect fireball_explode
+notunderwater
+count 128
+type spark
+color 0x903010 0xFFD030
+size 2 2
+alpha 256 256 384
+gravity 1
+airfriction 0.2
+bounce 1.5
+liquidfriction 0.8
+velocityoffset 0 0 80
+velocityjitter 384 384 384
Index: keybinds.txt
===================================================================
--- keybinds.txt	(revision 7488)
+++ keybinds.txt	(working copy)
@@ -25,7 +25,7 @@
 "impulse 6"                             "crylink / hlac"
 "impulse 7"                             "nex / minstanex"
 "impulse 8"                             "hagar"
-"impulse 9"                             "rocket launcher"
+"impulse 9"                             "rocket launcher / fireball"
 "impulse 14"                            "porto / hook"
 ""                                      ""
 ""                                      "View"
Index: defaultNexuiz.cfg
===================================================================
--- defaultNexuiz.cfg	(revision 7488)
+++ defaultNexuiz.cfg	(working copy)
@@ -207,6 +207,12 @@
 seta crosshair_tuba_color_blue 0.25	"crosshair color blue component to display when wielding the tuba"
 seta crosshair_tuba_color_alpha 1	"crosshair alpha value to display when wielding the tuba"
 seta crosshair_tuba_size 1	"crosshair size when wielding the tuba"
+seta crosshair_fireball ""	"crosshair to display when wielding the fireball"
+seta crosshair_fireball_color_red 0.2	"crosshair color red component to display when wielding the fireball"
+seta crosshair_fireball_color_green 1.0	"crosshair color green component to display when wielding the fireball"
+seta crosshair_fireball_color_blue 0.2	"crosshair color blue component to display when wielding the fireball"
+seta crosshair_fireball_color_alpha 1	"crosshair alpha value to display when wielding the fireball"
+seta crosshair_fireball_size 1	"crosshair size when wielding the fireball"
 fov 90
 seta cl_zoomfactor 5	"how much +zoom will zoom (1-16)"
 seta cl_zoomspeed 3.5	"how fast it will zoom (0.5-16), negative values mean instant zoom"
Index: qcsrc/server/t_items.qc
===================================================================
--- qcsrc/server/t_items.qc	(revision 7488)
+++ qcsrc/server/t_items.qc	(working copy)
@@ -1566,5 +1566,5 @@
 // we no longer have the seeker
 void spawnfunc_weapon_seeker()
 {
-	spawnfunc_weapon_rocketlauncher();
+	spawnfunc_weapon_fireball();
 }
Index: qcsrc/server/progs.src
===================================================================
--- qcsrc/server/progs.src	(revision 7488)
+++ qcsrc/server/progs.src	(working copy)
@@ -107,6 +107,7 @@
 w_hlac.qc
 w_campingrifle.qc
 w_tuba.qc
+w_fireball.qc
 
 t_items.qc
 cl_weapons.qc
Index: qcsrc/server/constants.qh
===================================================================
--- qcsrc/server/constants.qh	(revision 7488)
+++ qcsrc/server/constants.qh	(working copy)
@@ -1,5 +1,5 @@
 string CVAR_CHECK_DEFAULT = "40fd98ae84e7814d9494ef3cef6fb162";
-string CVAR_CHECK_WEAPONS = "a7ca57b891d66754b856e24e5c1745e3";
+string CVAR_CHECK_WEAPONS = "9f900dc5cb77ea0899635cab3a5fdd77";
 
 float	FALSE					= 0;
 float	TRUE					= 1;
Index: qcsrc/server/w_fireball.qc
===================================================================
--- qcsrc/server/w_fireball.qc	(revision 0)
+++ qcsrc/server/w_fireball.qc	(revision 0)
@@ -0,0 +1,244 @@
+
+void W_Fireball_Explode (void)
+{
+	entity e;
+
+	self.event_damage = SUB_Null;
+
+	// 1. radius damage
+	RadiusDamage (self, self.owner, cvar("g_balance_fireball_primary_damage"), cvar("g_balance_fireball_primary_edgedamage"), cvar("g_balance_fireball_primary_radius"), world, cvar("g_balance_fireball_primary_force"), self.projectiledeathtype, other);
+
+	// 2. bfg effect
+	FOR_EACH_PLAYER(e)
+	{
+		if(e == self.owner)
+			continue;
+		// can we see fireball?
+		traceline(e.origin + e.view_ofs, self.origin, MOVE_NORMAL, e);
+		if(trace_startsolid || trace_fraction != 1)
+			continue;
+		// can we see player who shot fireball?
+		traceline(e.origin + e.view_ofs, self.owner.origin + self.owner.view_ofs, MOVE_NORMAL, e);
+		if(trace_ent != self.owner)
+		if(trace_startsolid || trace_fraction != 1)
+			continue;
+		Damage(e, self, self.owner, cvar("g_balance_fireball_primary_bfgdamage"), self.projectiledeathtype | HITTYPE_BOUNCE | HITTYPE_SPLASH, self.origin, cvar("g_balance_fireball_primary_bfgforce") * normalize(e.origin - self.owner.origin));
+	}
+
+	remove (self);
+}
+
+void W_Fireball_TouchExplode (void)
+{
+	PROJECTILE_TOUCH;
+	W_Fireball_Explode ();
+}
+
+void W_Fireball_Damage (entity inflictor, entity attacker, float damage, float deathtype, vector hitloc, vector force)
+{
+	if(self.health <= 0)
+		return;
+	self.health = self.health - damage;
+	if (self.health <= 0)
+		self.think = W_Fireball_Explode;
+}
+
+void W_Fireball_Think()
+{
+	entity e;
+
+	if(time > self.pushltime)
+		W_Fireball_Explode();
+	self.nextthink = time;
+
+	RandomSelection_Init();
+	for(e = findradius(self.origin, cvar("g_balance_fireball_primary_laserradius")); e; e = e.chain) if(e != self) if(e != self.owner) if(e.takedamage)
+		RandomSelection_Add(e, 0, string_null, 1 / (1 + vlen(self.origin - e.origin - e.view_ofs)), 0);
+	if(RandomSelection_chosen_ent)
+	{
+		Damage(RandomSelection_chosen_ent, self, self.owner, cvar("g_balance_fireball_primary_laserdamage") * frametime, self.projectiledeathtype | HITTYPE_BOUNCE, self.origin, cvar("g_balance_fireball_primary_laserforce") * frametime * normalize(RandomSelection_chosen_ent.origin + RandomSelection_chosen_ent.view_ofs - self.origin));
+		trailparticles(self, particleeffectnum("fireball_laser"), self.origin, RandomSelection_chosen_ent.origin + RandomSelection_chosen_ent.view_ofs);
+	}
+}
+
+void W_Fireball_Attack()
+{
+	local entity proj;
+
+	W_SetupShot_ProjectileSize (self, '-8 -8 -8', '8 8 8', FALSE, 2, "weapons/fireball_fire.wav", cvar("g_balance_fireball_primary_damage"));
+
+	pointparticles(particleeffectnum("fireball_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+
+	proj = spawn ();
+	proj.classname = "plasma_prim";
+	proj.owner = self;
+	proj.bot_dodge = TRUE;
+	proj.bot_dodgerating = cvar("g_balance_fireball_primary_damage");
+	proj.pushltime = time + cvar("g_balance_fireball_primary_lifetime");
+	proj.use = W_Fireball_Explode;
+	proj.think = W_Fireball_Think;
+	proj.nextthink = time;
+	PROJECTILE_MAKETRIGGER(proj);
+	proj.projectiledeathtype = WEP_FIREBALL;
+	setorigin(proj, w_shotorg);
+
+	if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+		self.ammo_rockets = self.ammo_rockets - cvar("g_balance_fireball_primary_ammo");
+
+	proj.movetype = MOVETYPE_FLY;
+	proj.velocity = w_shotdir * cvar("g_balance_fireball_primary_speed");
+	W_SetupProjectileVelocity(proj);
+	proj.angles = vectoangles(proj.velocity);
+	proj.touch = W_Fireball_TouchExplode;
+	setsize(proj, '-8 -8 -8', '8 8 8');
+	proj.flags = FL_PROJECTILE;
+
+	CSQCProjectile(proj, TRUE, PROJECTILE_FIREBALL, TRUE);
+}
+
+void Fireball_Flac_Explode ()
+{
+	self.event_damage = SUB_Null;
+	RadiusDamage (self, self.owner, cvar("g_balance_fireball_secondary_damage"), cvar("g_balance_fireball_secondary_edgedamage"), cvar("g_balance_fireball_secondary_radius"), world, cvar("g_balance_fireball_secondary_force"), self.projectiledeathtype, other);
+	remove (self);
+}
+
+void Fireball_Flac_Touch()
+{
+	PROJECTILE_TOUCH;
+	Fireball_Flac_Explode();
+}
+
+void W_Fireball_Attack2()
+{
+	local entity missile;
+	vector f_diff;
+	float c;
+
+	if not(self.items & IT_UNLIMITED_WEAPON_AMMO)
+		self.ammo_rockets = self.ammo_rockets - cvar("g_balance_fireball_secondary_ammo");
+
+	c = mod(self.bulletcounter, 4);
+	switch(c)
+	{
+		case 0:
+			f_diff = '-1.25 -3.75 0';
+			break;
+		case 1:
+			f_diff = '+1.25 -3.75 0';
+			break;
+		case 2:
+			f_diff = '-1.25 +3.75 0';
+			break;
+		case 3:
+		default:
+			f_diff = '+1.25 +3.75 0';
+			break;
+	}
+	W_SetupShot_ProjectileSize (self, '-2 -2 -2', '2 2 2', FALSE, 2, "weapons/flac_fire.wav", cvar("g_balance_fireball_secondary_damage"));
+	w_shotorg += f_diff;
+
+	pointparticles(particleeffectnum("hagar_muzzleflash"), w_shotorg, w_shotdir * 1000, 1);
+
+	missile = spawn ();
+	missile.owner = missile.realowner = self;
+	missile.classname = "missile";
+	missile.bot_dodge = TRUE;
+	missile.bot_dodgerating = cvar("g_balance_fireball_secondary_damage");
+	missile.touch = Fireball_Flac_Explode;
+	missile.use = Fireball_Flac_Explode;
+	missile.think = Fireball_Flac_Explode;
+	missile.nextthink = time + cvar("g_balance_fireball_secondary_lifetime") + cvar("g_balance_fireball_secondary_lifetime_rand");
+	missile.solid = SOLID_BBOX;
+	setorigin (missile, w_shotorg);
+	setsize (missile, '-2 -2 -2', '2 2 2');
+	missile.projectiledeathtype = WEP_FIREBALL | HITTYPE_SECONDARY;
+
+	missile.movetype = MOVETYPE_FLY;
+	w_shotdir = w_shotdir + '0 0 0.3';
+	missile.velocity    = (w_shotdir  + randomvec() * cvar("g_balance_fireball_secondary_spread")) * cvar("g_balance_fireball_secondary_speed");
+
+	W_SetupProjectileVelocity(missile);
+
+	missile.angles = vectoangles (missile.velocity);
+	missile.flags = FL_PROJECTILE;
+
+	CSQCProjectile(missile, TRUE, PROJECTILE_FIREBALL_FLAC, TRUE);
+}
+
+void spawnfunc_weapon_fireball (void)
+{
+	weapon_defaultspawnfunc(WEP_FIREBALL);
+}
+
+float w_fireball(float req)
+{
+	if (req == WR_AIM)
+	{
+	}
+	else if (req == WR_THINK)
+	{
+		if (self.BUTTON_ATCK)
+		if (weapon_prepareattack(0, cvar("g_balance_fireball_primary_refire")))
+		{
+			W_Fireball_Attack();
+			weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_fireball_primary_animtime"), w_ready);
+		}
+		if (self.BUTTON_ATCK2)
+		if (weapon_prepareattack(1, cvar("g_balance_fireball_secondary_refire")))
+		{
+			W_Fireball_Attack2();
+			weapon_thinkf(WFRAME_FIRE2, cvar("g_balance_fireball_secondary_animtime"), w_ready);
+		}
+	}
+	else if (req == WR_PRECACHE)
+	{
+		precache_model ("models/weapons/g_fireball.md3");
+		precache_model ("models/weapons/v_fireball.md3");
+		precache_model ("models/weapons/h_fireball.dpm");
+		precache_sound ("weapons/flac_fire.wav");
+		precache_sound ("weapons/fireball_fire.wav");
+	}
+	else if (req == WR_SETUP)
+		weapon_setup(WEP_FIREBALL);
+	else if (req == WR_CHECKAMMO1)
+		return self.ammo_rockets >= cvar("g_balance_fireball_primary_ammo");
+	else if (req == WR_CHECKAMMO2)
+		return self.ammo_rockets >= cvar("g_balance_fireball_secondary_ammo");
+	else if (req == WR_SUICIDEMESSAGE)
+	{
+		if(w_deathtype & HITTYPE_SECONDARY)
+			w_deathtypestring = "ate his own flac";
+		else
+			w_deathtypestring = "should have used a smaller gun";
+	}
+	else if (req == WR_KILLMESSAGE)
+	{
+		if(w_deathtype & HITTYPE_SECONDARY)
+		{
+			if(w_deathtype & HITTYPE_SPLASH) // unchecked: BOUNCE
+				w_deathtypestring = "got too close to #'s flac";
+			else // unchecked: BOUNCE
+				w_deathtypestring = "ran into #'s flac";
+		}
+		else
+		{
+			if(w_deathtype & HITTYPE_BOUNCE)
+			{
+				if(w_deathtype & HITTYPE_SPLASH) // BFG effect
+				{
+					w_deathtypestring = "could not hide from #'s fireball";
+				}
+				else // laser
+				{
+					w_deathtypestring = "saw the pretty lights of #'s fireball";
+				}
+			}
+			else if(w_deathtype & HITTYPE_SPLASH)
+				w_deathtypestring = "got too close to #'s fireball";
+			else
+				w_deathtypestring = "tasted #'s fireball";
+		}
+	}
+	return TRUE;
+};
Index: qcsrc/common/constants.qh
===================================================================
--- qcsrc/common/constants.qh	(revision 7488)
+++ qcsrc/common/constants.qh	(working copy)
@@ -404,6 +404,8 @@
 float PROJECTILE_HAGAR_BOUNCING = 17;
 float PROJECTILE_BULLET_GLOWING = 18;
 float PROJECTILE_CRYLINK_BOUNCING = 19;
+float PROJECTILE_FIREBALL = 20;
+float PROJECTILE_FIREBALL_FLAC = 21;
 
 float SPECIES_HUMAN        =  0;
 float SPECIES_ROBOT_SHINY  =  1;
Index: qcsrc/common/items.qc
===================================================================
--- qcsrc/common/items.qc	(revision 7488)
+++ qcsrc/common/items.qc	(working copy)
@@ -117,6 +117,7 @@
 	register_weapon(WEP_HLAC,             w_hlac,         IT_CELLS,         6,  1, 0, WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID,  "hlac",         "hlac",            "Heavy Laser Assault Cannon");
 	register_weapon(WEP_TUBA,             w_tuba,         0,                1, -1, 0, WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID,  "tuba",         "tuba",            "@!#%'n Tuba");
 	register_weapon(WEP_CAMPINGRIFLE,     w_campingrifle, IT_NAILS,         3,  1, 0, WEP_TYPE_HITSCAN, BOT_PICKUP_RATING_MID,  "campingrifle", "campingrifle",    "Rifle");
+	register_weapon(WEP_FIREBALL,         w_fireball,     IT_ROCKETS,       9,  1, 0, WEP_TYPE_SPLASH, BOT_PICKUP_RATING_MID,  "fireball", "fireball",    "Fireball");
 
 	register_weapons_done();
 }
Index: qcsrc/common/items.qh
===================================================================
--- qcsrc/common/items.qh	(revision 7488)
+++ qcsrc/common/items.qh	(working copy)
@@ -16,8 +16,9 @@
 float WEP_HLAC			    = 13; float WEPBIT_HLAC		        = 4096;
 float WEP_TUBA        	    = 14; float WEPBIT_TUBA             = 8192;
 float WEP_CAMPINGRIFLE	    = 15; float WEPBIT_CAMPINGRIFLE     = 16384;
-float WEP_LAST				= 15; float WEPBIT_ALL              = 32767;
-float WEP_COUNT             = 16;
+float WEP_FIREBALL          = 16; float WEPBIT_FIREBALL		    = 32768;
+float WEP_LAST				= 16; float WEPBIT_ALL              = 65535;
+float WEP_COUNT             = 17;
 
 float BOT_PICKUP_RATING_LOW	= 2500;
 float BOT_PICKUP_RATING_MID	= 5000;
Index: qcsrc/client/damage.qc
===================================================================
--- qcsrc/client/damage.qc	(revision 7488)
+++ qcsrc/client/damage.qc	(working copy)
@@ -236,6 +236,28 @@
 				break;
 			case WEP_TUBA:
 				break;
+			case WEP_FIREBALL:
+				if(secondary)
+				{
+					pointparticles(particleeffectnum("flac_explode"), org2, '0 0 0', 1);
+					if(!issilent)
+					{
+						if (r<0.15)
+							sound(self, CHAN_PROJECTILE, "weapons/flacexp1.wav", 1, ATTN_NORM);
+						else if (r<0.7)
+							sound(self, CHAN_PROJECTILE, "weapons/flacexp2.wav", 1, ATTN_NORM);
+						else
+							sound(self, CHAN_PROJECTILE, "weapons/flacexp3.wav", 1, ATTN_NORM);
+					}
+				}
+				else
+				{
+					org2 = org + backoff * 16;
+					pointparticles(particleeffectnum("fireball_explode"), org2, '0 0 0', 1);
+					if(!issilent)
+						sound(self, CHAN_PROJECTILE, "weapons/fireball_impact.wav", VOL_BASE, ATTN_NORM);
+				}
+				break;
 			default:
 				dprint("Unhandled damage of weapon ", ftos(hitwep), "\n");
 				break;
@@ -253,6 +275,9 @@
 	precache_sound("weapons/hagexp1.wav");
 	precache_sound("weapons/hagexp2.wav");
 	precache_sound("weapons/hagexp3.wav");
+	precache_sound("weapons/flacexp1.wav");
+	precache_sound("weapons/flacexp2.wav");
+	precache_sound("weapons/flacexp3.wav");
 	precache_sound("weapons/hookbomb_impact.wav");
 	precache_sound("weapons/laserimpact.wav");
 	precache_sound("weapons/neximpact.wav");
@@ -260,4 +285,5 @@
 	precache_sound("weapons/ric2.wav");
 	precache_sound("weapons/ric3.wav");
 	precache_sound("weapons/rocket_impact.wav");
+	precache_sound("weapons/fireball_impact.wav");
 }
Index: qcsrc/client/projectile.qc
===================================================================
--- qcsrc/client/projectile.qc	(revision 7488)
+++ qcsrc/client/projectile.qc	(working copy)
@@ -1,5 +1,6 @@
 .float spawntime;
 .vector trail_oldorigin;
+.float trail_oldtime;
 
 void SUB_Null()
 {
@@ -20,8 +21,11 @@
 void Projectile_DrawTrail(vector to)
 {
 	vector from;
+	float t0;
 	from = self.trail_oldorigin;
+	t0 = self.trail_oldtime;
 	self.trail_oldorigin = to;
+	self.trail_oldtime = time;
 	switch(self.cnt)
 	{
 		case PROJECTILE_ROCKET:
@@ -61,10 +65,15 @@
 		case PROJECTILE_BULLET_GLOWING:
 			trailparticles(self, particleeffectnum("tr_bullet"), from, to);
 			break;
+		case PROJECTILE_FIREBALL_FLAC:
+			trailparticles(self, particleeffectnum("TR_VORESPIKE"), from, to);
+			break;
+		case PROJECTILE_FIREBALL:
+			pointparticles(particleeffectnum("fireball"), (from + to) * 0.5 + randomvec() * 4, randomvec() * 1.5, (time - t0) * 300);
+			break;
 		default:
 			break;
 	}
-
 }
 
 void Projectile_Draw()
@@ -136,7 +145,10 @@
 		if(drawn)
 			Projectile_DrawTrail(trailorigin);
 		else
+		{
 			self.trail_oldorigin = trailorigin;
+			self.trail_oldtime = time;
+		}
 	}
 
 	if(!drawn)
@@ -268,6 +280,8 @@
 			case PROJECTILE_HOOKBOMB: setmodel(self, "models/grenademodel.md3"); break;
 			case PROJECTILE_HAGAR: setmodel(self, "models/hagarmissile.mdl"); self.scale = 0.4; break;
 			case PROJECTILE_HAGAR_BOUNCING: setmodel(self, "models/hagarmissile.mdl"); self.scale = 0.4; break;
+			case PROJECTILE_FIREBALL: self.model = ""; self.modelindex = 0; break; // particle effect is good enough
+			case PROJECTILE_FIREBALL_FLAC: setmodel(self, "models/hagarmissile.mdl"); self.scale = 0.4; break;
 			default:
 				error("Received invalid CSQC projectile, can't work with this!");
 				break;
@@ -324,6 +338,11 @@
 				self.move_movetype = MOVETYPE_BOUNCE;
 				self.move_touch = SUB_Null;
 				break;
+			case PROJECTILE_FIREBALL:
+				loopsound(self, CHAN_PROJECTILE, "weapons/fireball_fly.wav", VOL_BASE, ATTN_NORM);
+				self.mins = '-8 -8 -8';
+				self.maxs = '8 8 8';
+				break;
 			default:
 				break;
 		}
@@ -364,4 +383,5 @@
 	precache_model("models/tracer.mdl");
 	precache_sound("weapons/electro_fly.wav");
 	precache_sound("weapons/rocket_fly.wav");
+	precache_sound("weapons/fireball_fly.wav");
 }
Index: qcsrc/client/View.qc
===================================================================
--- qcsrc/client/View.qc	(revision 7488)
+++ qcsrc/client/View.qc	(working copy)
@@ -267,6 +267,10 @@
 			mi = '-3 -3 -3';
 			ma = '3 3 3';
 			break;
+		case WEP_FIREBALL: // projectile has a size!
+			mi = '-8 -8 -8';
+			ma = '8 8 8';
+			break;
 		case WEP_ELECTRO: // projectile has a size!
 			mi = '0 0 -3';
 			ma = '0 0 -3';
Index: gfx/crosshairfireball.tga
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: gfx/crosshairfireball.tga
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: weaponsHavoc.cfg
===================================================================
--- weaponsHavoc.cfg	(revision 7488)
+++ weaponsHavoc.cfg	(working copy)
@@ -1,4 +1,4 @@
-set cvar_check_weapons a7ca57b891d66754b856e24e5c1745e3
+set cvar_check_weapons 9f900dc5cb77ea0899635cab3a5fdd77
 
 // NOTE: this only replaces weapons on the map
 // use g_start_weapon_* to also replace the on-startup weapons!
@@ -19,6 +19,7 @@
 set g_weaponreplace_hlac ""
 set g_weaponreplace_campingrifle ""
 set g_weaponreplace_tuba ""
+set g_weaponreplace_fireball ""
 
 
 set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
@@ -36,6 +37,7 @@
 set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_weapon_campingrifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_ammo_shells 60
 set g_start_ammo_nails 0
 set g_start_ammo_rockets 0
@@ -362,3 +364,29 @@
 set g_balance_tuba_edgedamage 0
 set g_balance_tuba_radius 200
 set g_balance_tuba_force 200
+
+set g_balance_fireball_primary_radius 300
+set g_balance_fireball_primary_damage 70
+set g_balance_fireball_primary_edgedamage 30
+set g_balance_fireball_primary_force 1000
+set g_balance_fireball_primary_bfgdamage 50
+set g_balance_fireball_primary_bfgforce 500
+set g_balance_fireball_primary_laserradius 400
+set g_balance_fireball_primary_laserdamage 50
+set g_balance_fireball_primary_laserforce 1000
+set g_balance_fireball_primary_speed 200
+set g_balance_fireball_primary_lifetime 30
+set g_balance_fireball_primary_refire 5
+set g_balance_fireball_primary_animtime 0.3
+set g_balance_fireball_primary_ammo 25
+set g_balance_fireball_secondary_lifetime 0.1
+set g_balance_fireball_secondary_lifetime_rand 0.05
+set g_balance_fireball_secondary_speed 3000
+set g_balance_fireball_secondary_spread 0.4
+set g_balance_fireball_secondary_damage 15
+set g_balance_fireball_secondary_edgedamage 10
+set g_balance_fireball_secondary_radius 100
+set g_balance_fireball_secondary_force 50
+set g_balance_fireball_secondary_refire 0.1
+set g_balance_fireball_secondary_animtime 0.1
+set g_balance_fireball_secondary_ammo 0.5
Index: models/sprites/make-sprites.sh
===================================================================
--- models/sprites/make-sprites.sh	(revision 7488)
+++ models/sprites/make-sprites.sh	(working copy)
@@ -183,7 +183,7 @@
 sprite wpn-porto          "Port-O-Launch" 808080 000000 0.0 # grey
 sprite wpn-minstanex      "Minstanex"     80ffff 000000 0.0 # bright cyan
 sprite wpn-hookgun        "Hook"          008000 000000 0.0 # dark green
-sprite wpn-seeker         "Seeker"        ff8000 000000 0.0 # orange
+sprite wpn-fireball       "Fireball"      ff8000 000000 0.0 # orange
 sprite wpn-hlac           "HLAC"          00ff00 000000 0.0 # green
 sprite wpn-campingrifle   "Rifle"         80ff00 000000 0.0 # orange
 
Index: models/sprites/wpn-fireball_frame0.tga
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: models/sprites/wpn-fireball_frame0.tga
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: models/weapons/h_fireball.dpm.framegroups
===================================================================
--- models/weapons/h_fireball.dpm.framegroups	(revision 0)
+++ models/weapons/h_fireball.dpm.framegroups	(revision 0)
@@ -0,0 +1,4 @@
+1 8 20 0 // fire
+9 5 20 0 // fire2
+15 200 20 1 // idle
+215 40 20 0 // reload
Index: models/weapons/v_fireball.md3
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: models/weapons/v_fireball.md3
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: models/weapons/g_fireball.md3
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: models/weapons/g_fireball.md3
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: models/weapons/h_fireball.dpm
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream

Property changes on: models/weapons/h_fireball.dpm
___________________________________________________________________
Added: svn:mime-type
   + application/octet-stream

Index: weapons.cfg
===================================================================
--- weapons.cfg	(revision 7488)
+++ weapons.cfg	(working copy)
@@ -3,7 +3,7 @@
 //
 // And... don't forget to edit weaponsHavoc.cfg too.
 
-set cvar_check_weapons a7ca57b891d66754b856e24e5c1745e3
+set cvar_check_weapons 9f900dc5cb77ea0899635cab3a5fdd77
 
 // NOTE: this only replaces weapons on the map
 // use g_start_weapon_* to also replace the on-startup weapons!
@@ -24,6 +24,7 @@
 set g_weaponreplace_hlac ""
 set g_weaponreplace_campingrifle ""
 set g_weaponreplace_tuba ""
+set g_weaponreplace_fireball ""
 
 
 set g_start_weapon_laser -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
@@ -41,6 +42,7 @@
 set g_start_weapon_hlac -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_weapon_campingrifle -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_weapon_tuba -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
+set g_start_weapon_fireball -1 "0 = never provide the weapon, 1 = always provide the weapon, -1 = game mode default"
 set g_start_ammo_shells 40
 set g_start_ammo_nails 0
 set g_start_ammo_rockets 0
@@ -367,3 +369,29 @@
 set g_balance_tuba_edgedamage 0
 set g_balance_tuba_radius 200
 set g_balance_tuba_force 200
+
+set g_balance_fireball_primary_radius 300
+set g_balance_fireball_primary_damage 70
+set g_balance_fireball_primary_edgedamage 30
+set g_balance_fireball_primary_force 1000
+set g_balance_fireball_primary_bfgdamage 50
+set g_balance_fireball_primary_bfgforce 500
+set g_balance_fireball_primary_laserradius 400
+set g_balance_fireball_primary_laserdamage 50
+set g_balance_fireball_primary_laserforce 1000
+set g_balance_fireball_primary_speed 200
+set g_balance_fireball_primary_lifetime 30
+set g_balance_fireball_primary_refire 5
+set g_balance_fireball_primary_animtime 0.3
+set g_balance_fireball_primary_ammo 25
+set g_balance_fireball_secondary_lifetime 0.1
+set g_balance_fireball_secondary_lifetime_rand 0.05
+set g_balance_fireball_secondary_speed 3000
+set g_balance_fireball_secondary_spread 0.4
+set g_balance_fireball_secondary_damage 15
+set g_balance_fireball_secondary_edgedamage 10
+set g_balance_fireball_secondary_radius 100
+set g_balance_fireball_secondary_force 50
+set g_balance_fireball_secondary_refire 0.1
+set g_balance_fireball_secondary_animtime 0.1
+set g_balance_fireball_secondary_ammo 0.5
