r4294 - trunk/data/qcsrc/server

DONOTREPLY at icculus.org DONOTREPLY at icculus.org
Tue Sep 2 14:43:29 EDT 2008


Author: div0
Date: 2008-09-02 14:43:29 -0400 (Tue, 02 Sep 2008)
New Revision: 4294

Modified:
   trunk/data/qcsrc/server/cl_weapons.qc
   trunk/data/qcsrc/server/cl_weaponsystem.qc
   trunk/data/qcsrc/server/defs.qh
   trunk/data/qcsrc/server/g_damage.qc
   trunk/data/qcsrc/server/g_world.qc
   trunk/data/qcsrc/server/miscfunctions.qc
   trunk/data/qcsrc/server/t_items.qc
   trunk/data/qcsrc/server/w_crylink.qc
   trunk/data/qcsrc/server/w_electro.qc
   trunk/data/qcsrc/server/w_grenadelauncher.qc
   trunk/data/qcsrc/server/w_hagar.qc
   trunk/data/qcsrc/server/w_laser.qc
   trunk/data/qcsrc/server/w_nex.qc
   trunk/data/qcsrc/server/w_rocketlauncher.qc
   trunk/data/qcsrc/server/w_shotgun.qc
   trunk/data/qcsrc/server/w_uzi.qc
Log:
more modular weapon system


Modified: trunk/data/qcsrc/server/cl_weapons.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weapons.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/cl_weapons.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -124,79 +124,25 @@
 };
 
 // generic weapons table
-// add new weapons here
+// TODO should they be macros instead?
 float weapon_action(float wpn, float wrequest)
 {
-	// %weaponaddpoint
-	if (wpn == WEP_LASER)
-		return w_laser(wrequest);
-	else if (wpn == WEP_SHOTGUN)
-		return w_shotgun(wrequest);
-	else if (wpn == WEP_UZI)
-		return w_uzi(wrequest);
-	else if (wpn == WEP_GRENADE_LAUNCHER)
-		return w_glauncher(wrequest);
-	else if (wpn == WEP_ELECTRO)
-		return w_electro(wrequest);
-	else if (wpn == WEP_CRYLINK)
-		return w_crylink(wrequest);
-	else if (wpn == WEP_NEX)
-		return w_nex(wrequest);
-	else if (wpn == WEP_HAGAR)
-		return w_hagar(wrequest);
-	else if (wpn == WEP_ROCKET_LAUNCHER)
-		return w_rlauncher(wrequest);
-	return FALSE;
+	return (get_weaponinfo(wpn)).weapon_func(wrequest);
 };
 
 string W_Name(float weaponid)
 {
-	// %weaponaddpoint
-	if(weaponid == WEP_LASER)             return "Laser";
-	if(weaponid == WEP_UZI)               return "Machine Gun";
-	if(weaponid == WEP_SHOTGUN)           return "Shotgun";
-	if(weaponid == WEP_GRENADE_LAUNCHER)  return "Mortar";
-	if(weaponid == WEP_ELECTRO)           return "Electro";
-	if(weaponid == WEP_NEX)               return "Nex";
-	if(weaponid == WEP_HAGAR)             return "Hagar";
-	if(weaponid == WEP_ROCKET_LAUNCHER)   return "Rocket Launcher";
-	if(weaponid == WEP_CRYLINK)           return "Crylink";
-	return "@!#%'n Tuba";
+	return (get_weaponinfo(weaponid)).message;
 }
 
 float W_WeaponBit(float wpn)
 {
-	// %weaponaddpoint
-	switch(wpn)
-	{
-		case WEP_LASER:            return WEPBIT_LASER;
-		case WEP_SHOTGUN:          return WEPBIT_SHOTGUN;
-		case WEP_UZI:              return WEPBIT_UZI;
-		case WEP_GRENADE_LAUNCHER: return WEPBIT_GRENADE_LAUNCHER;
-		case WEP_ELECTRO:          return WEPBIT_ELECTRO;
-		case WEP_CRYLINK:          return WEPBIT_CRYLINK;
-		case WEP_NEX:              return WEPBIT_NEX;
-		case WEP_HAGAR:            return WEPBIT_HAGAR;
-		case WEP_ROCKET_LAUNCHER:  return WEPBIT_ROCKET_LAUNCHER;
-		default:                   return 0;
-	}
+	return (get_weaponinfo(wpn)).weapons;
 }
 
 float W_AmmoItemCode(float wpn)
 {
-	// %weaponaddpoint
-	switch(wpn)
-	{
-		case WEP_SHOTGUN:          return IT_SHELLS;
-		case WEP_UZI:              return IT_NAILS;
-		case WEP_GRENADE_LAUNCHER: return IT_ROCKETS;
-		case WEP_ELECTRO:          return IT_CELLS;
-		case WEP_CRYLINK:          return IT_CELLS;
-		case WEP_NEX:              return IT_CELLS;
-		case WEP_HAGAR:            return IT_ROCKETS;
-		case WEP_ROCKET_LAUNCHER:  return IT_ROCKETS;
-		default:                   return 0;
-	}
+	return (get_weaponinfo(wpn)).items;
 }
 
 // think function for tossed weapons
@@ -228,7 +174,7 @@
 		return;
 	if (g_nixnex)
 		return;
-	if (!cvar("g_pickup_weapons"))
+	if (!cvar("g_pickup_items"))
 		return;
 
 	e = self;
@@ -250,7 +196,9 @@
 	}
 	Item_SpawnByWeaponCode(w);
 	if(startitem_failed)
+	{
 		goto leave;
+	}
 	if(doreduce)
 	{
 		ammo = min(e.ammofield, wep.ammofield);
@@ -464,3 +412,16 @@
 	}
 }
 
+void RegisterWeapons()
+{
+	// %weaponaddpoint
+	register_weapon(WEP_LASER, w_laser, 0, "laser", "laser", "Laser");
+	register_weapon(WEP_SHOTGUN, w_shotgun, IT_SHELLS, "shotgun", "shotgun", "Shotgun");
+	register_weapon(WEP_UZI, w_uzi, IT_NAILS, "uzi", "uzi", "Machine Gun");
+	register_weapon(WEP_GRENADE_LAUNCHER, w_glauncher, IT_ROCKETS, "gl", "grenadelauncher", "Mortar");
+	register_weapon(WEP_ELECTRO, w_electro, IT_CELLS, "electro", "electro", "Electro");
+	register_weapon(WEP_CRYLINK, w_crylink, IT_CELLS, "crylink", "crylink", "Crylink");
+	register_weapon(WEP_NEX, w_nex, IT_CELLS, "nex", "nex", "Nex");
+	register_weapon(WEP_HAGAR, w_hagar, IT_ROCKETS, "hagar", "hagar", "Hagar");
+	register_weapon(WEP_ROCKET_LAUNCHER, w_rlauncher, IT_ROCKETS, "rl", "rocketlauncher", "Rocket Launcher");
+}

Modified: trunk/data/qcsrc/server/cl_weaponsystem.qc
===================================================================
--- trunk/data/qcsrc/server/cl_weaponsystem.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/cl_weaponsystem.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -385,14 +385,16 @@
 };
 
 // Setup weapon for client (after this raise frame will be launched)
-void weapon_setup(float windex, string wname, float hudammo)
+void weapon_setup(float windex, string wname)
 {
-	self.items = self.items - (self.items & (IT_SHELLS | IT_NAILS | IT_ROCKETS | IT_CELLS));
-	self.items = self.items | hudammo;
+	entity e;
+	e = get_weaponinfo(windex);
+	self.items = self.items - (self.items & IT_AMMO);
+	self.items = self.items | e.items;
 
 	// the two weapon entities will notice this has changed and update their models
 	self.weapon = windex;
-	self.weaponname = wname;
+	self.weaponname = e.mdl;
 };
 
 // perform weapon to attack (weaponstate and attack_finished check is here)
@@ -576,3 +578,47 @@
 
 	missile.velocity = W_CalculateProjectileVelocity(missile.owner.velocity, missile.velocity);
 }
+
+
+// WEAPON PLUGIN SYSTEM
+entity weapon_info[24];
+entity dummy_weapon_info;
+.float(float) weapon_func;
+void register_weapon(float id, float(float) func, float ammotype, string modelname, string shortname, string name)
+{
+	entity e;
+	weapon_info[id - 1] = e = spawn();
+	e.classname = "weapon_info";
+	e.weapon = id;
+	e.weapons = power2of(id - 1);
+	e.netname = shortname;
+	e.message = name;
+	e.items = ammotype;
+	e.weapon_func = func;
+	e.mdl = modelname;
+	e.model = strzone(strcat("models/weapons/g_", modelname, ".md3"));
+}
+float w_null(float dummy)
+{
+	return 0;
+}
+void register_dummy_weapon()
+{
+	dummy_weapon_info = spawn();
+	dummy_weapon_info.classname = "weapon_info";
+	dummy_weapon_info.weapon = 0;
+	dummy_weapon_info.weapons = 0;
+	dummy_weapon_info.netname = "@!#%'n Tuba";
+	dummy_weapon_info.items = 0;
+	dummy_weapon_info.weapon_func = w_null;
+	dummy_weapon_info.mdl = "";
+	dummy_weapon_info.model = "";
+}
+entity get_weaponinfo(float id)
+{
+	entity w;
+	w = weapon_info[id - 1];
+	if(w)
+		return w;
+	return dummy_weapon_info;
+}

Modified: trunk/data/qcsrc/server/defs.qh
===================================================================
--- trunk/data/qcsrc/server/defs.qh	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/defs.qh	2008-09-02 18:43:29 UTC (rev 4294)
@@ -196,13 +196,20 @@
 float WS_READY			= 4; // idle frame
 
 // weapon requests
-float WR_SETUP		  = 1; // setup weapon data
-float WR_THINK		  = 2; // logic to run every frame
-float WR_CHECKAMMO1	  = 3; // checks ammo for weapon
-float WR_CHECKAMMO2	  = 4; // checks ammo for weapon
-float WR_AIM		  = 5; // runs bot aiming code for this weapon
-float WR_PRECACHE	  = 6; // precaches models/sounds used by this weapon
+float WR_SETUP		    = 1; // setup weapon data
+float WR_THINK		    = 2; // logic to run every frame
+float WR_CHECKAMMO1	    = 3; // checks ammo for weapon
+float WR_CHECKAMMO2	    = 4; // checks ammo for weapon
+float WR_AIM		    = 5; // runs bot aiming code for this weapon
+float WR_PRECACHE	    = 6; // precaches models/sounds used by this weapon
+float WR_SUICIDEMESSAGE = 7; // sets w_deathtypestring or leaves it alone
+float WR_KILLMESSAGE    = 8; // sets w_deathtypestring or leaves it alone
+float WR_SPAWNFUNC      = 9; // calls the spawn function (which just needs to call weapon_defaultspawnfunc)
 
+void weapon_defaultspawnfunc(float wpn, float weight);
+
+string w_deathtypestring;
+
 void(entity client, string s) centerprint_builtin = #73;
 .vector dest1, dest2;
 

Modified: trunk/data/qcsrc/server/g_damage.qc
===================================================================
--- trunk/data/qcsrc/server/g_damage.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/g_damage.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -143,6 +143,7 @@
 void Obituary (entity attacker, entity targ, float deathtype)
 {
 	string	s, a;
+	float p;
 
 	if (targ.classname == "player" || targ.classname == "corpse")
 	{
@@ -202,13 +203,12 @@
 				if (targ.killcount > 2)
 					bprint ("^1",s,"^1 ended it all with a ",ftos(targ.killcount)," scoring spree\n");
 			} else {
-				// %weaponaddpoint
-				if (deathtype == WEP_GRENADE_LAUNCHER)
-					bprint ("^1",s, "^1 detonated\n");
-				else if (deathtype == WEP_ELECTRO)
-					bprint ("^1",s, "^1 played with plasma\n");
-				else if (deathtype == WEP_ROCKET_LAUNCHER)
-					bprint ("^1",s, "^1 exploded\n");
+				if(deathtype >= WEP_FIRST && deathtype <= WEP_LAST)
+				{
+					w_deathtypestring = "couldn't resist the urge to self-destruct";
+					weapon_action(deathtype, WR_SUICIDEMESSAGE);
+					bprint("^1", s, "^1 ", w_deathtypestring, "\n");
+				}
 				else if (deathtype == DEATH_KILL)
 					bprint ("^1",s, "^1 couldn't take it anymore\n");
 				else if (deathtype == DEATH_ROT)
@@ -283,25 +283,16 @@
 				if(sv_gentle) {
 					bprint ("^1",s, "^1 needs a restart thanks to ", a, "\n");
 				} else {
-					// %weaponaddpoint
-					if (deathtype == WEP_LASER)
-						bprint ("^1",s, "^1 was blasted by ", a, "\n");
-					else if (deathtype == WEP_UZI)
-						bprint ("^1",s, "^1 was riddled full of holes by ", a, "\n");
-					else if (deathtype == WEP_SHOTGUN)
-						bprint ("^1",s, "^1 was gunned by ", a, "\n");
-					else if (deathtype == WEP_GRENADE_LAUNCHER)
-						bprint ("^1", s, "^1 was blasted by ", a, "\n");
-					else if (deathtype == WEP_ELECTRO)
-						bprint ("^1",s, "^1 was blasted by ", a, "\n");
-					else if (deathtype == WEP_CRYLINK)
-						bprint ("^1",s, "^1 was blasted by ", a, "\n");
-					else if (deathtype == WEP_NEX)
-						bprint ("^1",s, "^1 has been vaporized by ", a, "\n");
-					else if (deathtype == WEP_HAGAR)
-						bprint ("^1",s, "^1 was pummeled by ", a, "\n");
-					else if (deathtype == WEP_ROCKET_LAUNCHER)
-						bprint ("^1",s, "^1 was blasted by ", a, "\n");
+					if(deathtype >= WEP_FIRST && deathtype <= WEP_LAST)
+					{
+						w_deathtypestring = "was blasted by";
+						weapon_action(deathtype, WR_SUICIDEMESSAGE);
+						p = strstrofs(w_deathtypestring, "|", 0);
+						if(p < 0)
+							bprint("^1", s, "^1 ", w_deathtypestring, " ", a, "\n");
+						else
+							bprint("^1", s, "^1 ", substring(w_deathtypestring, 0, p), a, "^1", substring(w_deathtypestring, p+1, strlen(w_deathtypestring) - (p+1)), "\n");
+					}
 					else if (deathtype == DEATH_TELEFRAG)
 						bprint ("^1",s, "^1 was telefragged by ", a, "\n");
 					else if (deathtype == DEATH_DROWN)

Modified: trunk/data/qcsrc/server/g_world.qc
===================================================================
--- trunk/data/qcsrc/server/g_world.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/g_world.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -157,6 +157,7 @@
 }
 
 float world_already_spawned;
+void RegisterWeapons();
 void spawnfunc_worldspawn (void)
 {
 	float fd, l;
@@ -237,6 +238,8 @@
 	// 63 testing
 	lightstyle(63, "a");
 
+	RegisterWeapons();
+
 	if(cvar("g_campaign"))
 		CampaignPreInit();
 

Modified: trunk/data/qcsrc/server/miscfunctions.qc
===================================================================
--- trunk/data/qcsrc/server/miscfunctions.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/miscfunctions.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -706,8 +706,13 @@
 float start_health;
 float start_armorvalue;
 
+entity get_weaponinfo(float w);
+
 void readlevelcvars(void)
 {
+	entity e;
+	float i;
+
 	sv_cheats = cvar("sv_cheats");
 	sv_gentle = cvar("sv_gentle");
 	sv_foginterval = cvar("sv_foginterval");
@@ -827,61 +832,18 @@
 			start_ammo_cells = cvar("g_pickup_cells_max");
 		}
 
-		// %weaponaddpoint (except for superweapons)
-		if (cvar("g_start_weapon_laser") || g_lms)
+		for(i = WEP_FIRST; i <= WEP_LAST; ++i)
 		{
-			start_weapons = start_weapons | WEPBIT_LASER;
-			start_switchweapon = WEP_LASER;
-			weapon_action(start_switchweapon, WR_PRECACHE);
+			e = get_weaponinfo(i);
+			if(!(e.weapon))
+				continue;
+			if((e.items != IT_SUPERWEAPON && (g_lms || g_tourney)) || cvar(strcat("g_start_weapon_", e.netname)))
+			{
+				start_weapons |= e.weapons;
+				start_switchweapon = e.weapon;
+				weapon_action(e.weapon, WR_PRECACHE);
+			}
 		}
-		if (cvar("g_start_weapon_shotgun") || g_lms)
-		{
-			start_weapons = start_weapons | WEPBIT_SHOTGUN;
-			start_switchweapon = WEP_SHOTGUN;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_uzi") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_UZI;
-			start_switchweapon = WEP_UZI;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_grenadelauncher") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_GRENADE_LAUNCHER;
-			start_switchweapon = WEP_GRENADE_LAUNCHER;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_electro") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_ELECTRO;
-			start_switchweapon = WEP_ELECTRO;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_crylink") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_CRYLINK;
-			start_switchweapon = WEP_CRYLINK;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_nex") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_NEX;
-			start_switchweapon = WEP_NEX;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_hagar") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_HAGAR;
-			start_switchweapon = WEP_HAGAR;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
-		if (cvar("g_start_weapon_rocketlauncher") || g_lms || g_tourney)
-		{
-			start_weapons = start_weapons | WEPBIT_ROCKET_LAUNCHER;
-			start_switchweapon = WEP_ROCKET_LAUNCHER;
-			weapon_action(start_switchweapon, WR_PRECACHE);
-		}
 	}
 }
 
@@ -1262,3 +1224,82 @@
 
 .float nottargeted;
 #define IFTARGETED if(!self.nottargeted && self.targetname != "")
+
+float power2of(float e)
+{
+	return pow(2, e);
+}
+float log2of(float x)
+{
+	// NOTE: generated code
+	if(x > 2048)
+		if(x > 131072)
+			if(x > 1048576)
+				if(x > 4194304)
+					return 23;
+				else
+					if(x > 2097152)
+						return 22;
+					else
+						return 21;
+			else
+				if(x > 524288)
+					return 20;
+				else
+					if(x > 262144)
+						return 19;
+					else
+						return 18;
+		else
+			if(x > 16384)
+				if(x > 65536)
+					return 17;
+				else
+					if(x > 32768)
+						return 16;
+					else
+						return 15;
+			else
+				if(x > 8192)
+					return 14;
+				else
+					if(x > 4096)
+						return 13;
+					else
+						return 12;
+	else
+		if(x > 32)
+			if(x > 256)
+				if(x > 1024)
+					return 11;
+				else
+					if(x > 512)
+						return 10;
+					else
+						return 9;
+			else
+				if(x > 128)
+					return 8;
+				else
+					if(x > 64)
+						return 7;
+					else
+						return 6;
+		else
+			if(x > 4)
+				if(x > 16)
+					return 5;
+				else
+					if(x > 8)
+						return 4;
+					else
+						return 3;
+			else
+				if(x > 2)
+					return 2;
+				else
+					if(x > 1)
+						return 1;
+					else
+						return 0;
+}

Modified: trunk/data/qcsrc/server/t_items.qc
===================================================================
--- trunk/data/qcsrc/server/t_items.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/t_items.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -1,4 +1,39 @@
+floatfield Item_CounterField(float it)
+{
+	switch(it)
+	{
+		case IT_SHELLS:      return ammo_shells;
+		case IT_NAILS:       return ammo_nails;
+		case IT_ROCKETS:     return ammo_rockets;
+		case IT_CELLS:       return ammo_cells;
+		case IT_5HP:         return health;
+		case IT_25HP:        return health;
+		case IT_HEALTH:      return health;
+		case IT_ARMOR_SHARD: return armorvalue;
+		case IT_ARMOR:       return armorvalue;
+		// add more things here (health, armor)
+		default:             error("requested item has no counter field");
+	}
+}
 
+string Item_CounterFieldName(float it)
+{
+	switch(it)
+	{
+		case IT_SHELLS:      return "shells";
+		case IT_NAILS:       return "nails";
+		case IT_ROCKETS:     return "rockets";
+		case IT_CELLS:       return "cells";
+		// add more things here (health, armor)
+		default:             error("requested item has no counter field name");
+	}
+}
+
+void Item_SpawnByWeaponCode(float it)
+{
+	weapon_action(it, WR_SPAWNFUNC);
+}
+
 .float max_armorvalue;
 
 void Item_Respawn (void)
@@ -14,10 +49,12 @@
 
 void Item_Touch (void)
 {
-	local entity oldself;
-	local float _switchweapon;
-	local float pickedup;
-	local float it;
+	entity oldself;
+	float _switchweapon;
+	float pickedup;
+	float it;
+	float i;
+	entity e;
 
 	// remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky)
 	if (((trace_dpstartcontents | trace_dphitcontents) & DPCONTENTS_NODROP) || (trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT))
@@ -135,15 +172,12 @@
 		if ((it = self.weapons - (self.weapons & other.weapons)))
 		{
 			pickedup = TRUE;
-			// %weaponaddpoint
-			if (it & WEPBIT_UZI)                W_GiveWeapon (other, WEP_UZI, self.netname);
-			if (it & WEPBIT_SHOTGUN)            W_GiveWeapon (other, WEP_SHOTGUN, self.netname);
-			if (it & WEPBIT_GRENADE_LAUNCHER)   W_GiveWeapon (other, WEP_GRENADE_LAUNCHER, self.netname);
-			if (it & WEPBIT_ELECTRO)            W_GiveWeapon (other, WEP_ELECTRO, self.netname);
-			if (it & WEPBIT_NEX)                W_GiveWeapon (other, WEP_NEX, self.netname);
-			if (it & WEPBIT_HAGAR)              W_GiveWeapon (other, WEP_HAGAR, self.netname);
-			if (it & WEPBIT_ROCKET_LAUNCHER)    W_GiveWeapon (other, WEP_ROCKET_LAUNCHER, self.netname);
-			if (it & WEPBIT_CRYLINK)            W_GiveWeapon (other, WEP_CRYLINK, self.netname);
+			for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+			{
+				e = get_weaponinfo(i);
+				if(it & e.weapons)
+					W_GiveWeapon (other, e.weapon, self.netname);
+			}
 		}
 
 		if (self.strength_finished)
@@ -508,23 +542,34 @@
 
 float weaponswapping;
 
+void weapon_defaultspawnfunc(float wpn, float weight)
+{
+	entity e;
+	var .float ammofield;
+	e = get_weaponinfo(wpn);
+
+	if(e.items)
+	{
+		ammofield = Item_CounterField(e.items);
+		if(!self.ammofield)
+			self.ammofield = cvar(strcat("g_pickup_", Item_CounterFieldName(e.items)));
+	}
+
+	StartItem (e.model, "weapons/weaponpickup.wav", 15, e.message, 0, e.weapons, FL_WEAPON, weapon_pickupevalfunc, weight);
+	if (self.modelindex) // don't precache if self was removed
+		weapon_action(e.weapon, WR_PRECACHE);
+}
+
 void spawnfunc_weapon_shotgun (void);
 void spawnfunc_weapon_uzi (void) {
 	if(!weaponswapping)
 	if(q3acompat_machineshotgunswap)
 	if(self.classname != "droppedweapon")
 	{
-		weaponswapping = TRUE;
-		spawnfunc_weapon_shotgun();
-		weaponswapping = FALSE;
+		weapon_defaultspawnfunc(WEP_SHOTGUN, 2500);
 		return;
 	}
-
-	if(!self.ammo_nails)
-		self.ammo_nails = cvar("g_pickup_nails");
-	StartItem ("models/weapons/g_uzi.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_UZI), 0, WEPBIT_UZI, FL_WEAPON, weapon_pickupevalfunc, 5000);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_UZI, WR_PRECACHE);
+	weapon_defaultspawnfunc(WEP_UZI, 5000);
 }
 
 void spawnfunc_weapon_shotgun (void) {
@@ -532,46 +577,12 @@
 	if(q3acompat_machineshotgunswap)
 	if(self.classname != "droppedweapon")
 	{
-		weaponswapping = TRUE;
-		spawnfunc_weapon_uzi();
-		weaponswapping = FALSE;
+		weapon_defaultspawnfunc(WEP_UZI, 5000);
 		return;
 	}
-
-	if(!self.ammo_shells)
-		self.ammo_shells = cvar("g_pickup_shells");
-	StartItem ("models/weapons/g_shotgun.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_SHOTGUN), 0, WEPBIT_SHOTGUN, FL_WEAPON, weapon_pickupevalfunc, 2500);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_SHOTGUN, WR_PRECACHE);
+	weapon_defaultspawnfunc(WEP_SHOTGUN, 2500);
 }
 
-void spawnfunc_weapon_grenadelauncher (void)
-{
-	if(!self.ammo_rockets)
-		self.ammo_rockets = cvar("g_pickup_rockets");
-	StartItem ("models/weapons/g_gl.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_GRENADE_LAUNCHER), 0, WEPBIT_GRENADE_LAUNCHER, FL_WEAPON, weapon_pickupevalfunc, 5000);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_GRENADE_LAUNCHER, WR_PRECACHE);
-}
-
-void spawnfunc_weapon_electro (void)
-{
-	if(!self.ammo_cells)
-		self.ammo_cells = cvar("g_pickup_cells");
-	StartItem ("models/weapons/g_electro.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_ELECTRO), 0, WEPBIT_ELECTRO, FL_WEAPON, weapon_pickupevalfunc, 5000);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_ELECTRO, WR_PRECACHE);
-}
-
-void spawnfunc_weapon_crylink (void)
-{
-	if(!self.ammo_cells)
-		self.ammo_cells = cvar("g_pickup_cells");
-	StartItem ("models/weapons/g_crylink.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_CRYLINK), 0, WEPBIT_CRYLINK, FL_WEAPON, weapon_pickupevalfunc, 2500);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_CRYLINK, WR_PRECACHE);
-}
-
 void spawnfunc_weapon_nex (void)
 {
 	float nextime;
@@ -582,27 +593,9 @@
 		self.nextthink = time + cvar("sys_ticrate");
 		return;
 	}
-	if(!self.ammo_cells)
-		self.ammo_cells = cvar("g_pickup_cells");
-	nextime = cvar("g_balance_nex_respawntime_modifier");
-	if(nextime)
-		nextime = 15 * nextime;
-	else
-		nextime = 15;
-	StartItem ("models/weapons/g_nex.md3", "weapons/weaponpickup.wav", nextime, W_Name(WEP_NEX), 0, WEPBIT_NEX, FL_WEAPON, weapon_pickupevalfunc, 10000);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_NEX, WR_PRECACHE);
+	weapon_defaultspawnfunc(WEP_NEX, 10000);
 }
 
-void spawnfunc_weapon_hagar (void)
-{
-	if(!self.ammo_rockets)
-		self.ammo_rockets = cvar("g_pickup_rockets");
-	StartItem ("models/weapons/g_hagar.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_HAGAR), 0, WEPBIT_HAGAR, FL_WEAPON, weapon_pickupevalfunc, 5000);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_HAGAR, WR_PRECACHE);
-}
-
 void spawnfunc_weapon_rocketlauncher (void)
 {
 	if (g_minstagib)
@@ -612,11 +605,7 @@
 		self.nextthink = time + cvar("sys_ticrate");
 		return;
 	}
-	if(!self.ammo_rockets)
-		self.ammo_rockets = g_pickup_rockets;
-	StartItem ("models/weapons/g_rl.md3", "weapons/weaponpickup.wav", 15, W_Name(WEP_ROCKET_LAUNCHER), 0, WEPBIT_ROCKET_LAUNCHER, FL_WEAPON, weapon_pickupevalfunc, 10000);
-	if (self.modelindex) // don't precache if self was removed
-		weapon_action(WEP_ROCKET_LAUNCHER, WR_PRECACHE);
+	weapon_defaultspawnfunc(WEP_ROCKET_LAUNCHER, 10000);
 }
 
 void spawnfunc_item_rockets (void) {
@@ -811,39 +800,3 @@
 	self.use = func_wall_use;
 }
 
-floatfield Item_CounterField(float it)
-{
-	switch(it)
-	{
-		case IT_SHELLS:      return ammo_shells;
-		case IT_NAILS:       return ammo_nails;
-		case IT_ROCKETS:     return ammo_rockets;
-		case IT_CELLS:       return ammo_cells;
-		case IT_5HP:         return health;
-		case IT_25HP:        return health;
-		case IT_HEALTH:      return health;
-		case IT_ARMOR_SHARD: return armorvalue;
-		case IT_ARMOR:       return armorvalue;
-		// add more things here (health, armor)
-		default:             error("requested item has no counter field");
-	}
-}
-
-void Item_SpawnByWeaponCode(float it)
-{
-	// %weaponaddpoint
-	switch(it)
-	{
-		case WEP_SHOTGUN:          spawnfunc_weapon_shotgun(); break;
-		case WEP_UZI:              spawnfunc_weapon_uzi(); break;
-		case WEP_GRENADE_LAUNCHER: spawnfunc_weapon_grenadelauncher(); break;
-		case WEP_ELECTRO:          spawnfunc_weapon_electro(); break;
-		case WEP_CRYLINK:          spawnfunc_weapon_crylink(); break;
-		case WEP_NEX:              spawnfunc_weapon_nex(); break;
-		case WEP_HAGAR:            spawnfunc_weapon_hagar(); break;
-		case WEP_ROCKET_LAUNCHER:  spawnfunc_weapon_rocketlauncher(); break;
-		// add all other item spawn functions here
-		default:
-			error("requested item can't be spawned");
-	}
-}

Modified: trunk/data/qcsrc/server/w_crylink.qc
===================================================================
--- trunk/data/qcsrc/server/w_crylink.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_crylink.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -195,6 +195,11 @@
 }
 */
 
+void spawnfunc_weapon_crylink (void)
+{
+	weapon_defaultspawnfunc(WEP_CRYLINK, 5000);
+}
+
 float w_crylink(float req)
 {
 	if (req == WR_AIM)
@@ -229,10 +234,14 @@
 		precache_sound ("weapons/crylink_fire.wav");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_CRYLINK, "crylink", IT_CELLS);
+		weapon_setup(WEP_CRYLINK, "crylink");
 	else if (req == WR_CHECKAMMO1)
 		return self.ammo_cells >= cvar("g_balance_crylink_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_cells >= cvar("g_balance_crylink_secondary_ammo");
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_crylink();
+	// else if (req == WR_SUICIDEMESSAGE) // TODO
+	// else if (req == WR_KILLMESSAGE) // TODO
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_electro.qc
===================================================================
--- trunk/data/qcsrc/server/w_electro.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_electro.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -164,6 +164,11 @@
 	//sound (proj, CHAN_PROJECTILE, "weapons/electro_fly.wav", VOL_BASE, ATTN_NORM);
 }
 
+void spawnfunc_weapon_electro (void)
+{
+	weapon_defaultspawnfunc(WEP_ELECTRO, 5000);
+}
+
 .float bot_secondary_electromooth;
 float w_electro(float req)
 {
@@ -220,10 +225,15 @@
 		precache_sound ("weapons/electro_impact_combo.wav");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_ELECTRO, "electro", IT_CELLS);
+		weapon_setup(WEP_ELECTRO, "electro");
 	else if (req == WR_CHECKAMMO1)
 		return self.ammo_cells >= cvar("g_balance_electro_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_cells >= cvar("g_balance_electro_secondary_ammo");
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "played with plasma";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_electro();
+	// else if (req == WR_KILLMESSAGE) // TODO
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_grenadelauncher.qc
===================================================================
--- trunk/data/qcsrc/server/w_grenadelauncher.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_grenadelauncher.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -188,6 +188,11 @@
 #endif
 }
 
+void spawnfunc_weapon_grenadelauncher (void)
+{
+	weapon_defaultspawnfunc(WEP_GRENADE_LAUNCHER, 5000);
+}
+
 .float bot_secondary_grenademooth;
 float w_glauncher(float req)
 {
@@ -243,10 +248,16 @@
 		precache_sound ("weapons/grenade_impact.wav");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_GRENADE_LAUNCHER, "gl", IT_ROCKETS);
+		weapon_setup(WEP_GRENADE_LAUNCHER, "gl");
 	else if (req == WR_CHECKAMMO1)
 		return self.ammo_rockets >= cvar("g_balance_grenadelauncher_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_rockets >= cvar("g_balance_grenadelauncher_secondary_ammo");
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "detonated";
+	else if (req == WR_KILLMESSAGE)
+		w_deathtypestring = "was blasted by";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_grenadelauncher();
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_hagar.qc
===================================================================
--- trunk/data/qcsrc/server/w_hagar.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_hagar.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -156,6 +156,11 @@
 	missile.flags = FL_PROJECTILE;
 }
 
+void spawnfunc_weapon_hagar (void)
+{
+	weapon_defaultspawnfunc(WEP_HAGAR, 5000);
+}
+
 float w_hagar(float req)
 {
 	if (req == WR_AIM)
@@ -193,10 +198,15 @@
 		precache_sound ("weapons/hagexp3.wav");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_HAGAR, "hagar", IT_ROCKETS);
+		weapon_setup(WEP_HAGAR, "hagar");
 	else if (req == WR_CHECKAMMO1)
 		return self.ammo_rockets >= cvar("g_balance_hagar_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_rockets >= cvar("g_balance_hagar_secondary_ammo");
+	// else if (req == WR_SUICIDEMESSAGE) // TODO
+	else if (req == WR_KILLMESSAGE)
+		w_deathtypestring = "was pummeled by";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_hagar();
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_laser.qc
===================================================================
--- trunk/data/qcsrc/server/w_laser.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_laser.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -128,10 +128,18 @@
 		precache_sound ("weapons/laserimpact.wav");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_LASER, "laser", 0);
+		weapon_setup(WEP_LASER, "laser");
 	else if (req == WR_CHECKAMMO1)
 		return TRUE;
 	else if (req == WR_CHECKAMMO2)
 		return TRUE;
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "did the impossible";
+	// else if (req == WR_KILLMESSAGE) // TODO
+	else if (req == WR_SPAWNFUNC)
+	{
+		remove(self); // cannot spawn this
+		self = world;
+	}
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_nex.qc
===================================================================
--- trunk/data/qcsrc/server/w_nex.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_nex.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -119,6 +119,8 @@
 	self.minstagib_nextthink = time + 1;
 }
 
+void spawnfunc_weapon_nex (void); // defined in t_items.qc
+
 float w_nex(float req)
 {
 	if (req == WR_AIM)
@@ -168,7 +170,7 @@
 			w_laser(WR_PRECACHE);
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_NEX, "nex", IT_CELLS);
+		weapon_setup(WEP_NEX, "nex");
 	else if (req == WR_CHECKAMMO1)
 	{
 		if (g_minstagib)
@@ -178,5 +180,11 @@
 	}
 	else if (req == WR_CHECKAMMO2)
 		return FALSE;
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "did the impossible";
+	else if (req == WR_KILLMESSAGE)
+		w_deathtypestring = "has been vaporized by";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_nex();
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_rocketlauncher.qc
===================================================================
--- trunk/data/qcsrc/server/w_rocketlauncher.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_rocketlauncher.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -283,6 +283,8 @@
 	flash.effects = flash2.effects = EF_ADDITIVE | EF_FULLBRIGHT | EF_LOWPRECISION;
 }
 
+void spawnfunc_weapon_rocketlauncher (void); // defined in t_items.qc
+
 float w_rlauncher(float req)
 {
 	if (req == WR_AIM)
@@ -418,7 +420,7 @@
 			precache_model ("models/laser_dot.mdl"); // rocket launcher
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_ROCKET_LAUNCHER, "rl", IT_ROCKETS);
+		weapon_setup(WEP_ROCKET_LAUNCHER, "rl");
 	else if (req == WR_CHECKAMMO1)
 	{
 		// don't switch while guiding a missile
@@ -428,5 +430,11 @@
 	}
 	else if (req == WR_CHECKAMMO2)
 		return FALSE;
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "exploded";
+	else if (req == WR_KILLMESSAGE)
+		w_deathtypestring = "almost dodged #'s rocket";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_rocketlauncher();
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_shotgun.qc
===================================================================
--- trunk/data/qcsrc/server/w_shotgun.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_shotgun.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -95,6 +95,8 @@
 	weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_shotgun_secondary_animtime"), shotgun_fire2_03);
 }
 
+void spawnfunc_weapon_shotgun(); // defined in t_items.qc
+
 float w_shotgun(float req)
 {
 	if (req == WR_AIM)
@@ -134,10 +136,16 @@
 			precache_model ("models/casing_shell.mdl");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_SHOTGUN, "shotgun", IT_SHELLS);
+		weapon_setup(WEP_SHOTGUN, "shotgun");
 	else if (req == WR_CHECKAMMO1)
 		return self.ammo_shells >= cvar("g_balance_shotgun_primary_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_shells >= cvar("g_balance_shotgun_secondary_ammo") * 3;
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "did the impossible";
+	else if (req == WR_KILLMESSAGE)
+		w_deathtypestring = "was gunned by";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_shotgun();
 	return TRUE;
 };

Modified: trunk/data/qcsrc/server/w_uzi.qc
===================================================================
--- trunk/data/qcsrc/server/w_uzi.qc	2008-09-02 16:46:41 UTC (rev 4293)
+++ trunk/data/qcsrc/server/w_uzi.qc	2008-09-02 18:43:29 UTC (rev 4294)
@@ -100,6 +100,8 @@
 		weapon_thinkf(WFRAME_FIRE1, cvar("g_balance_uzi_sustained_refire"), w_ready);
 };
 
+void spawnfunc_weapon_machinegun(); // defined in t_items.qc
+
 float w_uzi(float req)
 {
 	if (req == WR_AIM)
@@ -142,10 +144,16 @@
 			precache_model ("models/casing_bronze.mdl");
 	}
 	else if (req == WR_SETUP)
-		weapon_setup(WEP_UZI, "uzi", IT_NAILS);
+		weapon_setup(WEP_UZI, "uzi");
 	else if (req == WR_CHECKAMMO1)
 		return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
 	else if (req == WR_CHECKAMMO2)
 		return self.ammo_nails >= cvar("g_balance_uzi_first_ammo");
+	else if (req == WR_SUICIDEMESSAGE)
+		w_deathtypestring = "did the impossible";
+	else if (req == WR_KILLMESSAGE)
+		w_deathtypestring = "was riddled full of holes by";
+	else if (req == WR_SPAWNFUNC)
+		spawnfunc_weapon_machinegun();
 	return TRUE;
 };




More information about the nexuiz-commits mailing list