Push down spawning logic from spawnfuncs to dedicated spawning functions
authorTimePath <andrew.hardaker1995@gmail.com>
Sun, 8 Oct 2017 09:30:52 +0000 (20:30 +1100)
committerTimePath <andrew.hardaker1995@gmail.com>
Sun, 8 Oct 2017 09:30:52 +0000 (20:30 +1100)
68 files changed:
qcsrc/common/items/item.qh
qcsrc/common/items/item/ammo.qc
qcsrc/common/items/item/ammo.qh
qcsrc/common/items/item/armor.qh
qcsrc/common/items/item/health.qh
qcsrc/common/items/item/jetpack.qc
qcsrc/common/items/item/jetpack.qh
qcsrc/common/items/item/powerup.qh
qcsrc/common/mutators/mutator/instagib/items.qh
qcsrc/common/mutators/mutator/instagib/sv_instagib.qc
qcsrc/common/mutators/mutator/instagib/sv_instagib.qh
qcsrc/common/mutators/mutator/overkill/hmg.qc
qcsrc/common/mutators/mutator/overkill/hmg.qh
qcsrc/common/mutators/mutator/overkill/rpc.qc
qcsrc/common/mutators/mutator/overkill/rpc.qh
qcsrc/common/mutators/mutator/overkill/sv_overkill.qc
qcsrc/common/mutators/mutator/random_items/_mod.qh
qcsrc/common/t_items.qc
qcsrc/common/weapons/weapon.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/arc.qh
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/blaster.qh
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/crylink.qh
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/devastator.qh
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/electro.qh
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/fireball.qh
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hagar.qh
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hlac.qh
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/hook.qh
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/machinegun.qh
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/minelayer.qh
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/mortar.qh
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/porto.qh
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/rifle.qh
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/seeker.qh
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shockwave.qh
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/shotgun.qh
qcsrc/common/weapons/weapon/tuba.qc
qcsrc/common/weapons/weapon/tuba.qh
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vaporizer.qh
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/common/weapons/weapon/vortex.qh
qcsrc/server/compat/quake.qc
qcsrc/server/compat/quake2.qc
qcsrc/server/compat/quake3.qc
qcsrc/server/compat/wop.qc
qcsrc/server/items.qc
qcsrc/server/items.qh
qcsrc/server/miscfunctions.qc
qcsrc/server/weapons/spawning.qc
qcsrc/server/weapons/weaponsystem.qh

index c302ae4..d5b25c4 100644 (file)
@@ -45,11 +45,26 @@ const int IT_PICKUPMASK                     = IT_UNLIMITED_AMMO | IT_JETPACK | IT_FU
 #ifdef SVQC
 .float  strength_finished = _STAT(STRENGTH_FINISHED);
 .float  invincible_finished = _STAT(INVINCIBLE_FINISHED);
+
+#define SPAWNFUNC_ITEM(name, item) \
+    spawnfunc(name) { StartItem(this, item); }
+
+#else
+
+#define SPAWNFUNC_ITEM(name, item)
+
 #endif
 
+enum {
+    ITEM_FLAG_MUTATORBLOCKED = BIT(0)
+};
+
 #define ITEM_HANDLE(signal, ...) __Item_Send_##signal(__VA_ARGS__)
 CLASS(GameItem, Object)
     ATTRIB(GameItem, m_id, int, 0);
+    /** the canonical spawnfunc name */
+    ATTRIB(GameItem, m_canonical_spawnfunc, string);
+    METHOD(GameItem, m_spawnfunc_hookreplace, GameItem(GameItem this, entity e)) { return this; }
     ATTRIB(GameItem, m_name, string);
     ATTRIB(GameItem, m_icon, string);
     ATTRIB(GameItem, m_color, vector, '1 1 1');
index d7e0dcc..38a0a02 100644 (file)
@@ -1 +1,23 @@
 #include "ammo.qh"
+
+#ifdef SVQC
+
+METHOD(Bullets, m_spawnfunc_hookreplace, GameItem(Bullets this, entity e))
+{
+       if (autocvar_sv_q3acompat_machineshotgunswap && e.classname != "droppedweapon")
+       {
+               return ITEM_Shells;
+       }
+       return this;
+}
+
+METHOD(Shells, m_spawnfunc_hookreplace, GameItem(Shells this, entity e))
+{
+       if (autocvar_sv_q3acompat_machineshotgunswap && e.classname != "droppedweapon")
+       {
+               return ITEM_Bullets;
+       }
+       return this;
+}
+
+#endif
index b3361d2..b9b6fc1 100644 (file)
@@ -31,7 +31,12 @@ void ammo_bullets_init(entity item)
         item.ammo_nails = g_pickup_nails;
 }
 #endif
-REGISTER_ITEM(Bullets, Ammo) {
+
+CLASS(Bullets, Ammo)
+ENDCLASS(Bullets)
+
+REGISTER_ITEM(Bullets, Bullets) {
+    this.m_canonical_spawnfunc = "item_bullets";
 #ifdef GAMEQC
     this.m_model    =   MDL_Bullets_ITEM;
 #endif
@@ -45,6 +50,8 @@ REGISTER_ITEM(Bullets, Ammo) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_bullets, ITEM_Bullets)
+
 #ifdef GAMEQC
 MODEL(Cells_ITEM, Item_Model("a_cells.md3"));
 #endif
@@ -58,6 +65,7 @@ void ammo_cells_init(entity item)
 }
 #endif
 REGISTER_ITEM(Cells, Ammo) {
+    this.m_canonical_spawnfunc = "item_cells";
 #ifdef GAMEQC
     this.m_model    =   MDL_Cells_ITEM;
 #endif
@@ -71,6 +79,8 @@ REGISTER_ITEM(Cells, Ammo) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_cells, ITEM_Cells)
+
 #ifdef GAMEQC
 MODEL(Plasma_ITEM, Item_Model("a_cells.md3"));
 #endif
@@ -84,6 +94,7 @@ void ammo_plasma_init(entity item)
 }
 #endif
 REGISTER_ITEM(Plasma, Ammo) {
+    this.m_canonical_spawnfunc = "item_plasma";
 #ifdef GAMEQC
     this.m_model    =   MDL_Plasma_ITEM;
 #endif
@@ -97,6 +108,8 @@ REGISTER_ITEM(Plasma, Ammo) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_plasma, ITEM_Plasma)
+
 #ifdef GAMEQC
 MODEL(Rockets_ITEM, Item_Model("a_rockets.md3"));
 #endif
@@ -110,6 +123,7 @@ void ammo_rockets_init(entity item)
 }
 #endif
 REGISTER_ITEM(Rockets, Ammo) {
+    this.m_canonical_spawnfunc = "item_rockets";
 #ifdef GAMEQC
     this.m_model    =   MDL_Rockets_ITEM;
 #endif
@@ -123,6 +137,8 @@ REGISTER_ITEM(Rockets, Ammo) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_rockets, ITEM_Rockets)
+
 #ifdef GAMEQC
 MODEL(Shells_ITEM, Item_Model("a_shells.md3"));
 #endif
@@ -135,7 +151,12 @@ void ammo_shells_init(entity item)
         item.ammo_shells = g_pickup_shells;
 }
 #endif
-REGISTER_ITEM(Shells, Ammo) {
+
+CLASS(Shells, Ammo)
+ENDCLASS(Shells)
+
+REGISTER_ITEM(Shells, Shells) {
+    this.m_canonical_spawnfunc = "item_shells";
 #ifdef GAMEQC
     this.m_model    =   MDL_Shells_ITEM;
 #endif
@@ -148,3 +169,5 @@ REGISTER_ITEM(Shells, Ammo) {
     this.m_iteminit =   ammo_shells_init;
 #endif
 }
+
+SPAWNFUNC_ITEM(item_shells, ITEM_Shells)
index 0258cf8..9a9326c 100644 (file)
@@ -32,6 +32,7 @@ void item_armorsmall_init(entity item)
 #endif
 
 REGISTER_ITEM(ArmorSmall, Armor) {
+    this.m_canonical_spawnfunc = "item_armor_small";
 #ifdef GAMEQC
     this.m_model                =   MDL_ArmorSmall_ITEM;
     this.m_sound                =   SND_ArmorSmall;
@@ -48,6 +49,8 @@ REGISTER_ITEM(ArmorSmall, Armor) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_armor_small, ITEM_ArmorSmall)
+
 #ifdef GAMEQC
 MODEL(ArmorMedium_ITEM, Item_Model("item_armor_medium.md3"));
 SOUND(ArmorMedium, Item_Sound("armor10"));
@@ -66,6 +69,7 @@ void item_armormedium_init(entity item)
 #endif
 
 REGISTER_ITEM(ArmorMedium, Armor) {
+    this.m_canonical_spawnfunc = "item_armor_medium";
 #ifdef GAMEQC
     this.m_model                =   MDL_ArmorMedium_ITEM;
     this.m_sound                =   SND_ArmorMedium;
@@ -82,6 +86,8 @@ REGISTER_ITEM(ArmorMedium, Armor) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_armor_medium, ITEM_ArmorMedium)
+
 #ifdef GAMEQC
 MODEL(ArmorBig_ITEM, Item_Model("item_armor_big.md3"));
 SOUND(ArmorBig, Item_Sound("armor17_5"));
@@ -100,6 +106,7 @@ void item_armorbig_init(entity item)
 #endif
 
 REGISTER_ITEM(ArmorBig, Armor) {
+    this.m_canonical_spawnfunc = "item_armor_big";
 #ifdef GAMEQC
     this.m_model                =   MDL_ArmorBig_ITEM;
     this.m_sound                =   SND_ArmorBig;
@@ -118,6 +125,8 @@ REGISTER_ITEM(ArmorBig, Armor) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_armor_big, ITEM_ArmorBig)
+
 #ifdef GAMEQC
 MODEL(ArmorMega_ITEM, Item_Model("item_armor_large.md3"));
 SOUND(ArmorMega, Item_Sound("armor25"));
@@ -136,6 +145,7 @@ void item_armormega_init(entity item)
 #endif
 
 REGISTER_ITEM(ArmorMega, Armor) {
+    this.m_canonical_spawnfunc = "item_armor_mega";
 #ifdef GAMEQC
     this.m_model                =   MDL_ArmorMega_ITEM;
     this.m_sound                =   SND_ArmorMega;
@@ -155,3 +165,5 @@ REGISTER_ITEM(ArmorMega, Armor) {
     this.m_iteminit             =   item_armormega_init;
 #endif
 }
+
+SPAWNFUNC_ITEM(item_armor_mega, ITEM_ArmorMega)
index cad5a37..3ffb572 100644 (file)
@@ -32,6 +32,7 @@ void item_healthsmall_init(entity item)
 #endif
 
 REGISTER_ITEM(HealthSmall, Health) {
+    this.m_canonical_spawnfunc = "item_health_small";
 #ifdef GAMEQC
     this.m_model                =   MDL_HealthSmall_ITEM;
     this.m_sound                =   SND_HealthSmall;
@@ -48,6 +49,8 @@ REGISTER_ITEM(HealthSmall, Health) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_health_small, ITEM_HealthSmall)
+
 #ifdef GAMEQC
 MODEL(HealthMedium_ITEM, Item_Model("g_h25.md3"));
 SOUND(HealthMedium, Item_Sound("mediumhealth"));
@@ -66,6 +69,7 @@ void item_healthmedium_init(entity item)
 #endif
 
 REGISTER_ITEM(HealthMedium, Health) {
+    this.m_canonical_spawnfunc = "item_health_medium";
 #ifdef GAMEQC
     this.m_model                =   MDL_HealthMedium_ITEM;
     this.m_sound                =   SND_HealthMedium;
@@ -82,6 +86,8 @@ REGISTER_ITEM(HealthMedium, Health) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_health_medium, ITEM_HealthMedium)
+
 #ifdef GAMEQC
 MODEL(HealthBig_ITEM, Item_Model("g_h50.md3"));
 SOUND(HealthBig, Item_Sound("mediumhealth"));
@@ -100,6 +106,7 @@ void item_healthbig_init(entity item)
 #endif
 
 REGISTER_ITEM(HealthBig, Health) {
+    this.m_canonical_spawnfunc = "item_health_big";
 #ifdef GAMEQC
     this.m_model                =   MDL_HealthBig_ITEM;
     this.m_sound                =   SND_HealthBig;
@@ -118,6 +125,8 @@ REGISTER_ITEM(HealthBig, Health) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_health_big, ITEM_HealthBig)
+
 #ifdef GAMEQC
 MODEL(HealthMega_ITEM, Item_Model("g_h100.md3"));
 SOUND(HealthMega, Item_Sound("megahealth"));
@@ -136,6 +145,7 @@ void item_healthmega_init(entity item)
 #endif
 
 REGISTER_ITEM(HealthMega, Health) {
+    this.m_canonical_spawnfunc = "item_health_mega";
 #ifdef GAMEQC
     this.m_model                =   MDL_HealthMega_ITEM;
     this.m_sound                =   SND_HealthMega;
@@ -155,3 +165,5 @@ REGISTER_ITEM(HealthMega, Health) {
     this.m_iteminit             =   item_healthmega_init;
 #endif
 }
+
+SPAWNFUNC_ITEM(item_health_mega, ITEM_HealthMega)
index ec09d5c..11b9d92 100644 (file)
@@ -1 +1,23 @@
 #include "jetpack.qh"
+
+#ifdef SVQC
+
+METHOD(Jetpack, m_spawnfunc_hookreplace, GameItem(Jetpack this, entity e))
+{
+       if(start_items & ITEM_Jetpack.m_itemid)
+       {
+               return ITEM_JetpackFuel;
+       }
+       return this;
+}
+
+METHOD(JetpackRegen, m_spawnfunc_hookreplace, GameItem(JetpackRegen this, entity e))
+{
+       if (start_items & ITEM_JetpackRegen.m_itemid)
+       {
+               return ITEM_JetpackFuel;
+       }
+       return this;
+}
+
+#endif
index a6d1c8d..389a11a 100644 (file)
@@ -23,7 +23,12 @@ void powerup_jetpack_init(entity item)
         item.ammo_fuel = g_pickup_fuel_jetpack;
 }
 #endif
+
+CLASS(Jetpack, Powerup)
+ENDCLASS(Jetpack)
+
 REGISTER_ITEM(Jetpack, Powerup) {
+    this.m_canonical_spawnfunc = "item_jetpack";
 #ifdef GAMEQC
     this.m_model                =   MDL_Jetpack_ITEM;
     this.m_itemid               =   IT_JETPACK;
@@ -41,6 +46,8 @@ REGISTER_ITEM(Jetpack, Powerup) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_jetpack, ITEM_Jetpack)
+
 #ifdef GAMEQC
 MODEL(JetpackFuel_ITEM, Item_Model("g_fuel.md3"));
 #endif
@@ -54,6 +61,7 @@ void ammo_fuel_init(entity item)
 }
 #endif
 REGISTER_ITEM(JetpackFuel, Ammo) {
+    this.m_canonical_spawnfunc = "item_fuel";
 #ifdef GAMEQC
     this.m_model    =   MDL_JetpackFuel_ITEM;
 #endif
@@ -67,11 +75,17 @@ REGISTER_ITEM(JetpackFuel, Ammo) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_fuel, ITEM_JetpackFuel)
+
 #ifdef GAMEQC
 MODEL(JetpackRegen_ITEM, Item_Model("g_fuelregen.md3"));
 #endif
 
-REGISTER_ITEM(JetpackRegen, Powerup) {
+CLASS(JetpackRegen, Powerup)
+ENDCLASS(JetpackRegen)
+
+REGISTER_ITEM(JetpackRegen, JetpackRegen) {
+    this.m_canonical_spawnfunc = "item_fuel_regen";
 #ifdef GAMEQC
     this.m_model                =   MDL_JetpackRegen_ITEM;
 #endif
@@ -87,3 +101,5 @@ REGISTER_ITEM(JetpackRegen, Powerup) {
     this.m_pickupevalfunc       =   ammo_pickupevalfunc;
 #endif
 }
+
+SPAWNFUNC_ITEM(item_fuel_regen, ITEM_JetpackRegen)
index 41b658c..fa14bda 100644 (file)
@@ -31,6 +31,7 @@ void powerup_strength_init(entity item)
 }
 #endif
 REGISTER_ITEM(Strength, Powerup) {
+    this.m_canonical_spawnfunc = "item_strength";
 #ifdef GAMEQC
     this.m_model            =   MDL_Strength_ITEM;
     this.m_sound            =   SND_Strength;
@@ -49,6 +50,8 @@ REGISTER_ITEM(Strength, Powerup) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_strength, ITEM_Strength)
+
 #ifdef GAMEQC
 MODEL(Shield_ITEM, Item_Model("g_invincible.md3"));
 SOUND(Shield, Item_Sound("powerup_shield"));
@@ -63,6 +66,7 @@ void powerup_shield_init(entity item)
 }
 #endif
 REGISTER_ITEM(Shield, Powerup) {
+    this.m_canonical_spawnfunc = "item_invincible";
 #ifdef GAMEQC
     this.m_model            =   MDL_Shield_ITEM;
     this.m_sound            =   SND_Shield;
@@ -80,3 +84,5 @@ REGISTER_ITEM(Shield, Powerup) {
     this.m_iteminit         =   powerup_shield_init;
 #endif
 }
+
+SPAWNFUNC_ITEM(item_invincible, ITEM_Shield)
index a8f4c6d..34ab625 100644 (file)
@@ -23,6 +23,8 @@ void ammo_vaporizercells_init(entity item)
 }
 #endif
 REGISTER_ITEM(VaporizerCells, Ammo) {
+    this.m_canonical_spawnfunc = "item_vaporizer_cells";
+    this.spawnflags = ITEM_FLAG_MUTATORBLOCKED;
 #ifdef GAMEQC
     this.m_model                =   MDL_VaporizerCells_ITEM;
     this.m_sound                =   SND_VaporizerCells;
@@ -39,6 +41,9 @@ REGISTER_ITEM(VaporizerCells, Ammo) {
 #endif
 }
 
+SPAWNFUNC_ITEM(item_vaporizer_cells, ITEM_VaporizerCells)
+SPAWNFUNC_ITEM(item_minst_cells, ITEM_VaporizerCells)
+
 #ifdef GAMEQC
 MODEL(ExtraLife_ITEM, Item_Model("g_h100.md3"));
 SOUND(ExtraLife, Item_Sound("megahealth"));
index 5a4f7d9..8716264 100644 (file)
@@ -17,17 +17,16 @@ float autocvar_g_instagib_speed_highspeed;
 
 #include <common/items/_mod.qh>
 
-REGISTER_MUTATOR(mutator_instagib, autocvar_g_instagib && !g_nexball);
-
-spawnfunc(item_vaporizer_cells)
-{
-       if (!g_instagib) { delete(this); return; }
-       StartItem(this, ITEM_VaporizerCells);
-}
-
-spawnfunc(item_minst_cells)
+REGISTER_MUTATOR(mutator_instagib, autocvar_g_instagib && !g_nexball)
 {
-       spawnfunc_item_vaporizer_cells(this);
+    MUTATOR_ONADD
+    {
+        ITEM_VaporizerCells.spawnflags &= ~ITEM_FLAG_MUTATORBLOCKED;
+    }
+    MUTATOR_ONROLLBACK_OR_REMOVE
+    {
+        ITEM_VaporizerCells.spawnflags |= ITEM_FLAG_MUTATORBLOCKED;
+    }
 }
 
 void instagib_invisibility(entity this)
index 051c935..9020b93 100644 (file)
@@ -4,7 +4,6 @@
 
 float autocvar_g_instagib_invis_alpha;
 
-spawnfunc(item_vaporizer_cells);
 void instagib_invisibility(entity this);
 void instagib_extralife(entity this);
 void instagib_speed(entity this);
index 4132795..f88e52a 100644 (file)
@@ -10,8 +10,6 @@ MUTATOR_HOOKFUNCTION(hmg_nadesupport, Nade_Damage)
        M_ARGV(3, float) /* damage */ = (M_ARGV(0, entity)).max_health * 0.1;
 }
 
-spawnfunc(weapon_hmg) { weapon_defaultspawnfunc(this, WEP_HMG); }
-
 void W_HeavyMachineGun_Attack_Auto(Weapon thiswep, entity actor, .entity weaponentity, int fire)
 {
        if (!PHYS_INPUT_BUTTON_ATCK(actor))
index b77728f..49457fb 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(HeavyMachineGun, Weapon)
+/* spawnfunc */ ATTRIB(HeavyMachineGun, m_canonical_spawnfunc, string, "weapon_hmg");
 /* ammotype  */ ATTRIB(HeavyMachineGun, ammo_type, int, RESOURCE_BULLETS);
 /* impulse   */ ATTRIB(HeavyMachineGun, impulse, int, 3);
 /* flags     */ ATTRIB(HeavyMachineGun, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_SUPERWEAPON);
@@ -41,6 +42,4 @@ CLASS(HeavyMachineGun, Weapon)
 ENDCLASS(HeavyMachineGun)
 REGISTER_WEAPON(HMG, hmg, NEW(HeavyMachineGun));
 
-#ifdef SVQC
-spawnfunc(weapon_hmg);
-#endif
+SPAWNFUNC_WEAPON(weapon_hmg, WEP_HMG)
index f901d11..b38e0ee 100644 (file)
@@ -1,7 +1,6 @@
 #include "rpc.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_rpc) { weapon_defaultspawnfunc(this, WEP_RPC); }
 
 void W_RocketPropelledChainsaw_Explode(entity this, entity directhitentity)
 {
index a107da3..a6891a0 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(RocketPropelledChainsaw, Weapon)
+/* spawnfunc */ ATTRIB(RocketPropelledChainsaw, m_canonical_spawnfunc, string, "weapon_rpc");
 /* ammotype  */ ATTRIB(RocketPropelledChainsaw, ammo_type, int, RESOURCE_ROCKETS);
 /* impulse   */ ATTRIB(RocketPropelledChainsaw, impulse, int, 9);
 /* flags     */ ATTRIB(RocketPropelledChainsaw, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_SUPERWEAPON);
@@ -46,6 +47,4 @@ CLASS(RocketPropelledChainsaw, Weapon)
 ENDCLASS(RocketPropelledChainsaw)
 REGISTER_WEAPON(RPC, rpc, NEW(RocketPropelledChainsaw));
 
-#ifdef SVQC
-spawnfunc(weapon_rpc);
-#endif
+SPAWNFUNC_WEAPON(weapon_rpc, WEP_RPC)
index ce015b1..734a14b 100644 (file)
@@ -28,8 +28,6 @@ REGISTER_MUTATOR(ok, expr_evaluate(autocvar_g_overkill) && !cvar("g_instagib") &
 }
 
 void W_Blaster_Attack(entity, .entity, float, float, float, float, float, float, float, float, float, float);
-spawnfunc(weapon_hmg);
-spawnfunc(weapon_rpc);
 
 MUTATOR_HOOKFUNCTION(ok, Damage_Calculate, CBC_ORDER_LAST)
 {
index 98fb481..928d174 100644 (file)
@@ -1 +1,4 @@
 // generated file; do not modify
+#ifdef SVQC
+    #include <common/mutators/mutator/random_items/sv_random_items.qh>
+#endif
index 1575fc9..97938e8 100644 (file)
@@ -934,7 +934,7 @@ LABEL(pickup)
 
        Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1);
        _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM);
-       
+
        MUTATOR_CALLHOOK(ItemTouched, this, toucher);
        if (wasfreed(this))
        {
@@ -1387,6 +1387,13 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
 
 void StartItem(entity this, GameItem def)
 {
+    def = def.m_spawnfunc_hookreplace(def, this);
+    if (def.spawnflags & ITEM_FLAG_MUTATORBLOCKED)
+    {
+        delete(this);
+        return;
+    }
+    this.classname = def.m_canonical_spawnfunc;
     _StartItem(
        this,
        this.itemdef = def,
index 71d7c3d..fa62ffb 100644 (file)
@@ -58,6 +58,10 @@ const int WS_READY  = 4;
 /** fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A" */
 CLASS(Weapon, Object)
        ATTRIB(Weapon, m_id, int, 0);
+       /** the canonical spawnfunc name */
+    ATTRIB(Weapon, m_canonical_spawnfunc, string);
+    /** control what happens when this weapon is spawned */
+    METHOD(Weapon, m_spawnfunc_hookreplace, Weapon(Weapon this, entity e)) { return this; }
     /** A: WEPSET_id : WEPSET_... */
     ATTRIB(Weapon, weapons, WepSet, '0 0 0');
     /** M: ammotype  : main ammo type */
@@ -137,6 +141,18 @@ CLASS(Weapon, Object)
        }
 ENDCLASS(Weapon)
 
+#ifdef SVQC
+
+void weapon_defaultspawnfunc(entity this, Weapon e);
+#define SPAWNFUNC_WEAPON(name, weapon) \
+    spawnfunc(name) { weapon_defaultspawnfunc(this, weapon); }
+
+#else
+
+#define SPAWNFUNC_WEAPON(name, weapon)
+
+#endif
+
 #include <common/items/_mod.qh>
 CLASS(WeaponPickup, Pickup)
     ATTRIB(WeaponPickup, m_weapon, Weapon);
index 5b98221..23e3dbc 100644 (file)
@@ -1,7 +1,6 @@
 #include "arc.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_arc) { weapon_defaultspawnfunc(this, WEP_ARC); }
 
 bool W_Arc_Beam_Send(entity this, entity to, int sf)
 {
index ed2d0a8..4ec2d4e 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Arc, Weapon)
+/* spawnfunc */ ATTRIB(Arc, m_canonical_spawnfunc, string, "weapon_arc");
 /* ammotype  */ ATTRIB(Arc, ammo_type, int, RESOURCE_CELLS);
 /* impulse   */ ATTRIB(Arc, impulse, int, 3);
 /* flags     */ ATTRIB(Arc, spawnflags, int, WEP_TYPE_HITSCAN);
@@ -74,6 +75,7 @@ CLASS(Arc, Weapon)
 ENDCLASS(Arc)
 REGISTER_WEAPON(ARC, arc, NEW(Arc));
 
+SPAWNFUNC_WEAPON(weapon_arc, WEP_ARC)
 
 #ifdef GAMEQC
 const float ARC_MAX_SEGMENTS = 20;
@@ -112,7 +114,6 @@ const int ARC_SF_LOCALMASK =   ARC_SF_START | ARC_SF_WANTDIR | ARC_SF_BEAMDIR;
 .float arc_cooldown; // (dropped arc/player) cooling speed
 .float arc_heat_percent = _STAT(ARC_HEAT);
 .float arc_smoke_sound;
-spawnfunc(weapon_arc);
 #endif
 #ifdef CSQC
 
index ac1540c..2189c1d 100644 (file)
@@ -1,8 +1,6 @@
 #include "blaster.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_blaster) { weapon_defaultspawnfunc(this, WEP_BLASTER); }
-spawnfunc(weapon_laser) { spawnfunc_weapon_blaster(this); }
 
 void W_Blaster_Touch(entity this, entity toucher)
 {
index 40e4535..0a0e7c1 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Blaster, Weapon)
+/* spawnfunc */ ATTRIB(Blaster, m_canonical_spawnfunc, string, "weapon_blaster");
 /* ammotype  */ //ATTRIB(Blaster, ammo_type, int, RESOURCE_NONE);
 /* impulse   */ ATTRIB(Blaster, impulse, int, 1);
 /* flags     */ ATTRIB(Blaster, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
@@ -44,6 +45,9 @@ CLASS(Blaster, Weapon)
 ENDCLASS(Blaster)
 REGISTER_WEAPON(BLASTER, blaster, NEW(Blaster));
 
+SPAWNFUNC_WEAPON(weapon_blaster, WEP_BLASTER)
+SPAWNFUNC_WEAPON(weapon_laser, WEP_BLASTER)
+
 #ifdef SVQC
 .float blaster_damage;
 .float blaster_edgedamage;
@@ -51,5 +55,4 @@ REGISTER_WEAPON(BLASTER, blaster, NEW(Blaster));
 .float blaster_force;
 .float blaster_lifetime;
 
-spawnfunc(weapon_blaster);
 #endif
index 2e2cb51..246452f 100644 (file)
@@ -1,7 +1,6 @@
 #include "crylink.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_crylink) { weapon_defaultspawnfunc(this, WEP_CRYLINK); }
 
 void W_Crylink_CheckLinks(entity e)
 {
index be6afd8..5ecef08 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Crylink, Weapon)
+/* spawnfunc */ ATTRIB(Crylink, m_canonical_spawnfunc, string, "weapon_crylink");
 /* ammotype  */ ATTRIB(Crylink, ammo_type, int, RESOURCE_CELLS);
 /* impulse   */ ATTRIB(Crylink, impulse, int, 6);
 /* flags     */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_CANCLIMB | WEP_FLAG_NODUAL);
@@ -59,6 +60,8 @@ CLASS(Crylink, Weapon)
 ENDCLASS(Crylink)
 REGISTER_WEAPON(CRYLINK, crylink, NEW(Crylink));
 
+SPAWNFUNC_WEAPON(weapon_crylink, WEP_CRYLINK)
+
 #ifdef SVQC
 .float gravity;
 .float crylink_waitrelease;
@@ -68,5 +71,4 @@ REGISTER_WEAPON(CRYLINK, crylink, NEW(Crylink));
 
 .entity queuenext;
 .entity queueprev;
-spawnfunc(weapon_crylink);
 #endif
index f4ef7ad..46db835 100644 (file)
@@ -1,8 +1,6 @@
 #include "devastator.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_devastator) { weapon_defaultspawnfunc(this, WEP_DEVASTATOR); }
-spawnfunc(weapon_rocketlauncher) { spawnfunc_weapon_devastator(this); }
 
 .entity lastrocket;
 
index ebfde37..0e8d8b2 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Devastator, Weapon)
+/* spawnfunc */ ATTRIB(Devastator, m_canonical_spawnfunc, string, "weapon_devastator");
 /* ammotype  */ ATTRIB(Devastator, ammo_type, int, RESOURCE_ROCKETS);
 /* impulse   */ ATTRIB(Devastator, impulse, int, 9);
 /* flags     */ ATTRIB(Devastator, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
@@ -62,8 +63,10 @@ CLASS(Devastator, Weapon)
 ENDCLASS(Devastator)
 REGISTER_WEAPON(DEVASTATOR, devastator, NEW(Devastator));
 
+SPAWNFUNC_WEAPON(weapon_devastator, WEP_DEVASTATOR)
+SPAWNFUNC_WEAPON(weapon_rocketlauncher, WEP_DEVASTATOR)
+
 #ifdef SVQC
 .float rl_release;
 .float rl_detonate_later;
-spawnfunc(weapon_devastator);
 #endif
index 8b3946e..5aec7fe 100644 (file)
@@ -1,7 +1,6 @@
 #include "electro.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_electro) { weapon_defaultspawnfunc(this, WEP_ELECTRO); }
 
 void W_Electro_TriggerCombo(vector org, float rad, entity own)
 {
index d881908..4018e59 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Electro, Weapon)
+/* spawnfunc */ ATTRIB(Electro, m_canonical_spawnfunc, string, "weapon_electro");
 /* ammotype  */ ATTRIB(Electro, ammo_type, int, RESOURCE_CELLS);
 /* impulse   */ ATTRIB(Electro, impulse, int, 5);
 /* flags     */ ATTRIB(Electro, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
@@ -66,10 +67,10 @@ CLASS(Electro, Weapon)
 ENDCLASS(Electro)
 REGISTER_WEAPON(ELECTRO, electro, NEW(Electro));
 
+SPAWNFUNC_WEAPON(weapon_electro, WEP_ELECTRO)
 
 #ifdef SVQC
 .float electro_count;
 .float electro_secondarytime;
-spawnfunc(weapon_electro);
 void W_Electro_ExplodeCombo(entity this);
 #endif
index 3f9cd4c..3f6830f 100644 (file)
@@ -1,7 +1,6 @@
 #include "fireball.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_fireball) { weapon_defaultspawnfunc(this, WEP_FIREBALL); }
 
 void W_Fireball_Explode(entity this, entity directhitentity)
 {
index cd52d2a..4302c9e 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Fireball, Weapon)
+/* spawnfunc */ ATTRIB(Fireball, m_canonical_spawnfunc, string, "weapon_fireball");
 /* ammotype  */ //ATTRIB(Fireball, ammo_type, int, RESOURCE_NONE);
 /* impulse   */ ATTRIB(Fireball, impulse, int, 9);
 /* flags     */ ATTRIB(Fireball, spawnflags, int, WEP_FLAG_SUPERWEAPON | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
@@ -53,9 +54,10 @@ CLASS(Fireball, Weapon)
 ENDCLASS(Fireball)
 REGISTER_WEAPON(FIREBALL, fireball, NEW(Fireball));
 
+SPAWNFUNC_WEAPON(weapon_fireball, WEP_FIREBALL)
+
 #ifdef SVQC
 .float bot_primary_fireballmooth; // whatever a mooth is
 .vector fireball_impactvec;
 .float fireball_primarytime;
-spawnfunc(weapon_fireball);
 #endif
index be95d5d..ff2e745 100644 (file)
@@ -1,7 +1,6 @@
 #include "hagar.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_hagar) { weapon_defaultspawnfunc(this, WEP_HAGAR); }
 
 // NO bounce protection, as bounces are limited!
 
index c5661f1..924326f 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Hagar, Weapon)
+/* spawnfunc */ ATTRIB(Hagar, m_canonical_spawnfunc, string, "weapon_hagar");
 /* ammotype  */ ATTRIB(Hagar, ammo_type, int, RESOURCE_ROCKETS);
 /* impulse   */ ATTRIB(Hagar, impulse, int, 8);
 /* flags     */ ATTRIB(Hagar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
@@ -57,6 +58,4 @@ CLASS(Hagar, Weapon)
 ENDCLASS(Hagar)
 REGISTER_WEAPON(HAGAR, hagar, NEW(Hagar));
 
-#ifdef SVQC
-spawnfunc(weapon_hagar);
-#endif
+SPAWNFUNC_WEAPON(weapon_hagar, WEP_HAGAR)
index 2fb16d6..ae6c9a6 100644 (file)
@@ -1,7 +1,6 @@
 #include "hlac.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_hlac) { weapon_defaultspawnfunc(this, WEP_HLAC); }
 
 void W_HLAC_Touch(entity this, entity toucher)
 {
index 3ab2990..d2bd427 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(HLAC, Weapon)
+/* spawnfunc */ ATTRIB(HLAC, m_canonical_spawnfunc, string, "weapon_hlac");
 /* ammotype  */ ATTRIB(HLAC, ammo_type, int, RESOURCE_CELLS);
 /* impulse   */ ATTRIB(HLAC, impulse, int, 6);
 /* flags     */ ATTRIB(HLAC, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
@@ -49,6 +50,4 @@ CLASS(HLAC, Weapon)
 ENDCLASS(HLAC)
 REGISTER_WEAPON(HLAC, hlac, NEW(HLAC));
 
-#ifdef SVQC
-spawnfunc(weapon_hlac);
-#endif
+SPAWNFUNC_WEAPON(weapon_hlac, WEP_HLAC)
index d92e0ca..4a21a51 100644 (file)
@@ -2,8 +2,6 @@
 
 #ifdef SVQC
 
-spawnfunc(weapon_hook) { weapon_defaultspawnfunc(this, WEP_HOOK); }
-
 void W_Hook_ExplodeThink(entity this)
 {
        float dt, dmg_remaining_next, f;
index d028323..31424d4 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Hook, Weapon)
+/* spawnfunc */ ATTRIB(Hook, m_canonical_spawnfunc, string, "weapon_hook");
 /* ammotype  */ ATTRIB(Hook, ammo_type, int, RESOURCE_FUEL);
 /* impulse   */ ATTRIB(Hook, impulse, int, 0);
 /* flags     */ ATTRIB(Hook, spawnflags, int, WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
@@ -49,6 +50,8 @@ CLASS(Hook, Weapon)
 ENDCLASS(Hook)
 REGISTER_WEAPON(HOOK, hook, NEW(Hook));
 
+SPAWNFUNC_WEAPON(weapon_hook, WEP_HOOK)
+
 CLASS(OffhandHook, OffhandWeapon)
 #ifdef SVQC
     METHOD(OffhandHook, offhand_think, void(OffhandHook this, entity actor, bool key_pressed))
@@ -73,5 +76,4 @@ OffhandHook OFFHAND_HOOK; STATIC_INIT(OFFHAND_HOOK) { OFFHAND_HOOK = NEW(Offhand
 .float hook_refire;
 .float hook_time_hooked;
 .float hook_time_fueldecrease;
-spawnfunc(weapon_hook);
 #endif
index 8d96c4b..100a11a 100644 (file)
@@ -2,17 +2,15 @@
 
 #ifdef SVQC
 
-spawnfunc(weapon_machinegun)
+METHOD(MachineGun, m_spawnfunc_hookreplace, Weapon(MachineGun this, entity e))
 {
        if(autocvar_sv_q3acompat_machineshotgunswap)
-       if(this.classname != "droppedweapon")
+       if(e.classname != "droppedweapon")
        {
-               weapon_defaultspawnfunc(this, WEP_SHOCKWAVE);
-               return;
+               return WEP_SHOCKWAVE;
        }
-       weapon_defaultspawnfunc(this, WEP_MACHINEGUN);
+       return this;
 }
-spawnfunc(weapon_uzi) { spawnfunc_weapon_machinegun(this); }
 
 void W_MachineGun_MuzzleFlash_Think(entity this)
 {
index 183a736..a7ede47 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(MachineGun, Weapon)
+/* spawnfunc */ ATTRIB(MachineGun, m_canonical_spawnfunc, string, "weapon_machinegun");
 /* ammotype  */ ATTRIB(MachineGun, ammo_type, int, RESOURCE_BULLETS);
 /* impulse   */ ATTRIB(MachineGun, impulse, int, 3);
 /* flags     */ ATTRIB(MachineGun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
@@ -55,6 +56,5 @@ CLASS(MachineGun, Weapon)
 ENDCLASS(MachineGun)
 REGISTER_WEAPON(MACHINEGUN, machinegun, NEW(MachineGun));
 
-#ifdef SVQC
-spawnfunc(weapon_machinegun);
-#endif
+SPAWNFUNC_WEAPON(weapon_machinegun, WEP_MACHINEGUN)
+SPAWNFUNC_WEAPON(weapon_uzi, WEP_MACHINEGUN)
index 99b00a8..575b76d 100644 (file)
@@ -1,7 +1,6 @@
 #include "minelayer.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_minelayer) { weapon_defaultspawnfunc(this, WEP_MINE_LAYER); }
 
 void W_MineLayer_Stick(entity this, entity to)
 {
index 7369d8c..f804aaf 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(MineLayer, Weapon)
+/* spawnfunc */ ATTRIB(MineLayer, m_canonical_spawnfunc, string, "weapon_minelayer");
 /* ammotype  */ ATTRIB(MineLayer, ammo_type, int, RESOURCE_ROCKETS);
 /* impulse   */ ATTRIB(MineLayer, impulse, int, 4);
 /* flags     */ ATTRIB(MineLayer, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
@@ -53,10 +54,11 @@ CLASS(MineLayer, Weapon)
 ENDCLASS(MineLayer)
 REGISTER_WEAPON(MINE_LAYER, minelayer, NEW(MineLayer));
 
+SPAWNFUNC_WEAPON(weapon_minelayer, WEP_MINE_LAYER)
+
 #ifdef SVQC
 void W_MineLayer_Think(entity this);
 .float minelayer_detonate, mine_explodeanyway;
 .float mine_time;
 .vector mine_orientation;
-spawnfunc(weapon_minelayer);
 #endif
index 6a3d2e1..6ada37c 100644 (file)
@@ -2,9 +2,6 @@
 
 #ifdef SVQC
 
-spawnfunc(weapon_mortar) { weapon_defaultspawnfunc(this, WEP_MORTAR); }
-spawnfunc(weapon_grenadelauncher) { spawnfunc_weapon_mortar(this); }
-
 void W_Mortar_Grenade_Explode(entity this, entity directhitentity)
 {
        if(directhitentity.takedamage == DAMAGE_AIM)
index be9cdbb..affec0d 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Mortar, Weapon)
+/* spawnfunc */ ATTRIB(Mortar, m_canonical_spawnfunc, string, "weapon_mortar");
 /* ammotype  */ ATTRIB(Mortar, ammo_type, int, RESOURCE_ROCKETS);
 /* impulse   */ ATTRIB(Mortar, impulse, int, 4);
 /* flags     */ ATTRIB(Mortar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
@@ -53,9 +54,10 @@ CLASS(Mortar, Weapon)
 ENDCLASS(Mortar)
 REGISTER_WEAPON(MORTAR, mortar, NEW(Mortar));
 
+SPAWNFUNC_WEAPON(weapon_mortar, WEP_MORTAR)
+SPAWNFUNC_WEAPON(weapon_grenadelauncher, WEP_MORTAR)
 
 #ifdef SVQC
 .float gl_detonate_later;
 .float gl_bouncecnt;
-spawnfunc(weapon_mortar);
 #endif
index b4dab73..9738914 100644 (file)
@@ -3,8 +3,6 @@
 #ifdef SVQC
 #include <common/triggers/trigger/jumppads.qh>
 
-spawnfunc(weapon_porto) { weapon_defaultspawnfunc(this, WEP_PORTO); }
-
 REGISTER_MUTATOR(porto_ticker, true);
 MUTATOR_HOOKFUNCTION(porto_ticker, SV_StartFrame) {
        FOREACH_CLIENT(IS_PLAYER(it), it.porto_forbidden = max(0, it.porto_forbidden - 1));
index 6af9e3b..93b3a6e 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(PortoLaunch, Weapon)
+/* spawnfunc */ ATTRIB(PortoLaunch, m_canonical_spawnfunc, string, "weapon_porto");
 /* ammotype  */ ATTRIB(PortoLaunch, ammo_type, int, RESOURCE_NONE);
 /* impulse   */ ATTRIB(PortoLaunch, impulse, int, 0);
 /* flags     */ ATTRIB(PortoLaunch, spawnflags, int, WEP_TYPE_OTHER | WEP_FLAG_SUPERWEAPON | WEP_FLAG_NODUAL);
@@ -35,11 +36,12 @@ CLASS(PortoLaunch, Weapon)
 ENDCLASS(PortoLaunch)
 REGISTER_WEAPON(PORTO, porto, NEW(PortoLaunch));
 
+SPAWNFUNC_WEAPON(weapon_porto, WEP_PORTO)
+
 #ifdef SVQC
 .entity porto_current;
 .vector porto_v_angle; // holds "held" view angles
 .float porto_v_angle_held;
 .vector right_vector;
 .float porto_forbidden;
-spawnfunc(weapon_porto);
 #endif
index 5478425..0e49171 100644 (file)
@@ -1,9 +1,6 @@
 #include "rifle.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_rifle) { weapon_defaultspawnfunc(this, WEP_RIFLE); }
-spawnfunc(weapon_campingrifle) { spawnfunc_weapon_rifle(this); }
-spawnfunc(weapon_sniperrifle) { spawnfunc_weapon_rifle(this); }
 
 void W_Rifle_FireBullet(Weapon thiswep, .entity weaponentity, float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, Sound pSound, entity actor)
 {
index 0340d9f..560354c 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Rifle, Weapon)
+/* spawnfunc */ ATTRIB(Rifle, m_canonical_spawnfunc, string, "weapon_rifle");
 /* ammotype  */ ATTRIB(Rifle, ammo_type, int, RESOURCE_BULLETS);
 /* impulse   */ ATTRIB(Rifle, impulse, int, 7);
 /* flags     */ ATTRIB(Rifle, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_PENETRATEWALLS);
@@ -47,8 +48,10 @@ CLASS(Rifle, Weapon)
 ENDCLASS(Rifle)
 REGISTER_WEAPON(RIFLE, rifle, NEW(Rifle));
 
+SPAWNFUNC_WEAPON(weapon_rifle, WEP_RIFLE)
+SPAWNFUNC_WEAPON(weapon_campingrifle, WEP_RIFLE)
+SPAWNFUNC_WEAPON(weapon_sniperrifle, WEP_RIFLE)
 
 #ifdef SVQC
 .float rifle_accumulator;
-spawnfunc(weapon_rifle);
 #endif
index b2df4f0..5e3faee 100644 (file)
@@ -1,7 +1,6 @@
 #include "seeker.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_seeker) { weapon_defaultspawnfunc(this, WEP_SEEKER); }
 
 // ============================
 // Begin: Missile functions, these are general functions to be manipulated by other code
index 40ba463..e4e9fd5 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Seeker, Weapon)
+/* spawnfunc */ ATTRIB(Seeker, m_canonical_spawnfunc, string, "weapon_seeker");
 /* ammotype  */ ATTRIB(Seeker, ammo_type, int, RESOURCE_ROCKETS);
 /* impulse   */ ATTRIB(Seeker, impulse, int, 8);
 /* flags     */ ATTRIB(Seeker, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
@@ -82,10 +83,11 @@ CLASS(Seeker, Weapon)
 ENDCLASS(Seeker)
 REGISTER_WEAPON(SEEKER, seeker, NEW(Seeker));
 
+SPAWNFUNC_WEAPON(weapon_seeker, WEP_SEEKER)
+
 #ifdef SVQC
 .entity tag_target, wps_tag_tracker;
 .float tag_time;
-spawnfunc(weapon_seeker);
 
 IntrusiveList g_seeker_trackers;
 STATIC_INIT(g_seeker_trackers) { g_seeker_trackers = IL_NEW(); }
index bc9e947..b52a5a2 100644 (file)
@@ -3,16 +3,15 @@
 REGISTER_NET_TEMP(TE_CSQC_SHOCKWAVEPARTICLE)
 
 #ifdef SVQC
-spawnfunc(weapon_shockwave)
+METHOD(Shockwave, m_spawnfunc_hookreplace, Weapon(Shockwave this, entity e))
 {
        //if(autocvar_sv_q3acompat_machineshockwaveswap) // WEAPONTODO
        if(autocvar_sv_q3acompat_machineshotgunswap)
-       if(this.classname != "droppedweapon")
+       if(e.classname != "droppedweapon")
        {
-               weapon_defaultspawnfunc(this, WEP_MACHINEGUN);
-               return;
+               return WEP_MACHINEGUN;
        }
-       weapon_defaultspawnfunc(this, WEP_SHOCKWAVE);
+       return this;
 }
 
 const float MAX_SHOCKWAVE_HITS = 10;
index d382890..ade2e9a 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Shockwave, Weapon)
+/* spawnfunc */ ATTRIB(Shockwave, m_canonical_spawnfunc, string, "weapon_shockwave");
 /* ammotype  */ //ATTRIB(Shockwave, ammo_type, int, RESOURCE_NONE);
 /* impulse   */ ATTRIB(Shockwave, impulse, int, 2);
 /* flags     */ ATTRIB(Shockwave, spawnflags, int, WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
@@ -74,6 +75,7 @@ CLASS(Shockwave, Weapon)
 ENDCLASS(Shockwave)
 REGISTER_WEAPON(SHOCKWAVE, shockwave, NEW(Shockwave));
 
+SPAWNFUNC_WEAPON(weapon_shockwave, WEP_SHOCKWAVE)
 
 #ifdef CSQC
 void Net_ReadShockwaveParticle();
@@ -84,7 +86,3 @@ void Net_ReadShockwaveParticle();
 .float sw_spread_min;
 .float sw_time;
 #endif
-
-#ifdef SVQC
-spawnfunc(weapon_shockwave);
-#endif
index e163df4..9ffef64 100644 (file)
@@ -1,7 +1,6 @@
 #include "shotgun.qh"
 
 #ifdef SVQC
-spawnfunc(weapon_shotgun) { weapon_defaultspawnfunc(this, WEP_SHOTGUN); }
 
 void W_Shotgun_Attack(Weapon thiswep, entity actor, .entity weaponentity, float isprimary)
 {
index f4afbc0..e40b1d8 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Shotgun, Weapon)
+/* spawnfunc */ ATTRIB(Shotgun, m_canonical_spawnfunc, string, "weapon_shotgun");
 /* ammotype  */ ATTRIB(Shotgun, ammo_type, int, RESOURCE_SHELLS);
 /* impulse   */ ATTRIB(Shotgun, impulse, int, 2);
 /* flags     */ ATTRIB(Shotgun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_TYPE_MELEE_SEC);
@@ -53,6 +54,4 @@ CLASS(Shotgun, Weapon)
 ENDCLASS(Shotgun)
 REGISTER_WEAPON(SHOTGUN, shotgun, NEW(Shotgun));
 
-#ifdef SVQC
-spawnfunc(weapon_shotgun);
-#endif
+SPAWNFUNC_WEAPON(weapon_shotgun, WEP_SHOTGUN)
index a5ae87c..37c3696 100644 (file)
@@ -10,8 +10,6 @@
 .float tuba_lastnotes_cnt; // over
 .vector tuba_lastnotes[MAX_TUBANOTES];
 
-spawnfunc(weapon_tuba) { weapon_defaultspawnfunc(this, WEP_TUBA); }
-
 bool W_Tuba_HasPlayed(entity pl, .entity weaponentity, string melody, int instrument, bool ignorepitch, float mintempo, float maxtempo)
 {
        float i, j, mmin, mmax, nolength;
index 8e5f3b8..ffa1dd6 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Tuba, Weapon)
+/* spawnfunc */ ATTRIB(Tuba, m_canonical_spawnfunc, string, "weapon_tuba");
 /* impulse   */ ATTRIB(Tuba, impulse, int, 1);
 /* flags     */ ATTRIB(Tuba, spawnflags, int, WEP_FLAG_HIDDEN | WEP_TYPE_SPLASH | WEP_FLAG_NODUAL);
 /* rating    */ ATTRIB(Tuba, bot_pickupbasevalue, float, 2000);
@@ -40,6 +41,8 @@ CLASS(Tuba, Weapon)
 ENDCLASS(Tuba)
 REGISTER_WEAPON(TUBA, tuba, NEW(Tuba));
 
+SPAWNFUNC_WEAPON(weapon_tuba, WEP_TUBA)
+
 #ifdef CSQC
 entityclass(Tuba);
 class(Tuba) .int note;
@@ -48,7 +51,3 @@ class(Tuba) .float tuba_volume;
 class(Tuba) .float tuba_volume_initial;
 class(Tuba) .int tuba_instrument;
 #endif
-
-#ifdef SVQC
-spawnfunc(weapon_tuba);
-#endif
index 73822b4..4a9475a 100644 (file)
@@ -105,8 +105,6 @@ NET_HANDLE(TE_CSQC_VAPORBEAMPARTICLE, bool isNew)
 #endif
 
 #ifdef SVQC
-spawnfunc(weapon_vaporizer) { weapon_defaultspawnfunc(this, WEP_VAPORIZER); }
-spawnfunc(weapon_minstanex) { spawnfunc_weapon_vaporizer(this); }
 
 void W_RocketMinsta_Explosion(entity actor, vector loc)
 {
index 874f318..ea9f8dd 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Vaporizer, Weapon)
+/* spawnfunc */ ATTRIB(Vaporizer, m_canonical_spawnfunc, string, "weapon_vaporizer");
 /* ammotype  */ ATTRIB(Vaporizer, ammo_type, int, RESOURCE_CELLS);
 /* impulse   */ ATTRIB(Vaporizer, impulse, int, 7);
 /* flags     */ ATTRIB(Vaporizer, spawnflags, int, WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN | WEP_FLAG_NODUAL);
@@ -50,6 +51,8 @@ CLASS(Vaporizer, Weapon)
 ENDCLASS(Vaporizer)
 REGISTER_WEAPON(VAPORIZER, vaporizer, NEW(Vaporizer));
 
+SPAWNFUNC_WEAPON(weapon_vaporizer, WEP_VAPORIZER)
+SPAWNFUNC_WEAPON(weapon_minstanex, WEP_VAPORIZER)
 
 #ifdef SVQC
 .float vaporizer_lasthit;
@@ -59,5 +62,4 @@ REGISTER_WEAPON(VAPORIZER, vaporizer, NEW(Vaporizer));
 .float rm_force;
 .float rm_damage;
 .float rm_edmg;
-spawnfunc(weapon_vaporizer);
 #endif
index 202780e..60557cb 100644 (file)
@@ -71,8 +71,6 @@ NET_HANDLE(TE_CSQC_VORTEXBEAMPARTICLE, bool isNew)
 #endif
 
 #ifdef SVQC
-spawnfunc(weapon_vortex) { weapon_defaultspawnfunc(this, WEP_VORTEX); }
-spawnfunc(weapon_nex) { spawnfunc_weapon_vortex(this); }
 
 REGISTER_MUTATOR(vortex_charge, true);
 
index 3a4ab52..59152e2 100644 (file)
@@ -1,6 +1,7 @@
 #pragma once
 
 CLASS(Vortex, Weapon)
+/* spawnfunc */ ATTRIB(Vortex, m_canonical_spawnfunc, string, "weapon_vortex");
 /* ammotype  */ ATTRIB(Vortex, ammo_type, int, RESOURCE_CELLS);
 /* impulse   */ ATTRIB(Vortex, impulse, int, 7);
 /* flags     */ ATTRIB(Vortex, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_NODUAL);
@@ -59,8 +60,9 @@ CLASS(Vortex, Weapon)
 ENDCLASS(Vortex)
 REGISTER_WEAPON(VORTEX, vortex, NEW(Vortex));
 
+SPAWNFUNC_WEAPON(weapon_vortex, WEP_VORTEX)
+SPAWNFUNC_WEAPON(weapon_nex, WEP_VORTEX)
 
 #ifdef SVQC
 .float vortex_lasthit;
-spawnfunc(weapon_vortex);
 #endif
index 126a0f6..e830fe6 100644 (file)
@@ -4,29 +4,15 @@
 #include <server/miscfunctions.qh>
 #include <common/weapons/_all.qh>
 
-spawnfunc(weapon_electro);
-spawnfunc(weapon_hagar);
-spawnfunc(weapon_machinegun);
-spawnfunc(item_bullets);
-spawnfunc(item_armor_mega);
-spawnfunc(item_health_mega);
-spawnfunc(item_health_medium);
-
 //***********************
 //QUAKE 1 ENTITIES - So people can play quake1 maps with the xonotic weapons
 //***********************
-spawnfunc(weapon_nailgun) {spawnfunc_weapon_electro(this);}
-spawnfunc(weapon_supernailgun) {spawnfunc_weapon_hagar(this);}
-spawnfunc(weapon_supershotgun) {spawnfunc_weapon_machinegun(this);}
+SPAWNFUNC_WEAPON(weapon_nailgun, WEP_ELECTRO)
+SPAWNFUNC_WEAPON(weapon_supernailgun, WEP_HAGAR)
+SPAWNFUNC_WEAPON(weapon_supershotgun, WEP_MACHINEGUN)
 
-spawnfunc(item_spikes) {spawnfunc_item_bullets(this);}
+SPAWNFUNC_ITEM(item_spikes, ITEM_Bullets)
 //spawnfunc(item_armor1) {spawnfunc_item_armor_medium(this);}  // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-spawnfunc(item_armor2) {spawnfunc_item_armor_mega(this);}
-spawnfunc(item_armorInv) {spawnfunc_item_armor_mega(this);} // TODO: make sure we actually want this
-spawnfunc(item_health) {if (this.spawnflags & 2) spawnfunc_item_health_mega(this);else spawnfunc_item_health_medium(this);}
-
-//spawnfunc_item_spikes
-//spawnfunc_item_health
-
-
-
+SPAWNFUNC_ITEM(item_armor2, ITEM_ArmorMega)
+SPAWNFUNC_ITEM(item_armorInv, ITEM_ArmorMega) // TODO: make sure we actually want this
+spawnfunc(item_health) {if (this.spawnflags & 2) StartItem(this, ITEM_HealthMega);else StartItem(this, ITEM_HealthMedium);}
index df99f15..3231277 100644 (file)
@@ -1,15 +1,10 @@
 #include "quake2.qh"
 
-spawnfunc(item_armor_medium);
-
-spawnfunc(item_invincible);
-
-
 //***********************
 //QUAKE 2 ENTITIES - So people can play quake2 maps with the xonotic weapons
 //***********************
-spawnfunc(item_armor_jacket) {spawnfunc_item_armor_medium(this);}
+SPAWNFUNC_ITEM(item_armor_jacket, ITEM_ArmorMedium)
 
-spawnfunc(item_invulnerability) {spawnfunc_item_invincible(this);}
+SPAWNFUNC_ITEM(item_invulnerability, ITEM_Shield)
 
 // rest of the quake 2 entities are handled by q1 and q3 compat
index d7dcbf3..4fc33ba 100644 (file)
@@ -14,51 +14,51 @@ spawnfunc(target_items);
 // NOTE: for best experience, you need to swap MGs with SGs in the map or it won't have a MG
 
 // SG -> SG
-spawnfunc(ammo_shells)         { spawnfunc_item_shells(this);         }
+SPAWNFUNC_ITEM(ammo_shells, ITEM_Shells)
 
 // MG -> MG
-spawnfunc(ammo_bullets)        { spawnfunc_item_bullets(this);        }
+SPAWNFUNC_ITEM(ammo_bullets, ITEM_Bullets)
 
 // GL -> Mortar
-spawnfunc(ammo_grenades)       { spawnfunc_item_rockets(this);        }
+SPAWNFUNC_ITEM(ammo_grenades, ITEM_Rockets)
 
 // Mines -> Rockets
-spawnfunc(weapon_prox_launcher) { spawnfunc_weapon_minelayer(this);   }
-spawnfunc(ammo_mines)           { spawnfunc_item_rockets(this);       }
+SPAWNFUNC_WEAPON(weapon_prox_launcher, WEP_MINE_LAYER)
+SPAWNFUNC_ITEM(ammo_mines, ITEM_Rockets)
 
 // LG -> Lightning
-spawnfunc(weapon_lightning)    { spawnfunc_weapon_electro(this);      }
-spawnfunc(ammo_lightning)      { spawnfunc_item_cells(this);          }
+SPAWNFUNC_WEAPON(weapon_lightning, WEP_ELECTRO)
+SPAWNFUNC_ITEM(ammo_lightning, ITEM_Cells)
 
 // Plasma -> Hagar
-spawnfunc(weapon_plasmagun)    { spawnfunc_weapon_hagar(this);        }
-spawnfunc(ammo_cells)          { spawnfunc_item_rockets(this);        }
+SPAWNFUNC_WEAPON(weapon_plasmagun, WEP_HAGAR)
+SPAWNFUNC_ITEM(ammo_cells, ITEM_Rockets)
 
 // Rail -> Vortex
-spawnfunc(weapon_railgun)      { spawnfunc_weapon_vortex(this);       }
-spawnfunc(ammo_slugs)          { spawnfunc_item_cells(this);          }
+SPAWNFUNC_WEAPON(weapon_railgun, WEP_VORTEX)
+SPAWNFUNC_ITEM(ammo_slugs, ITEM_Cells)
 
 // BFG -> Crylink
-spawnfunc(weapon_bfg)          { spawnfunc_weapon_crylink(this);      }
-spawnfunc(ammo_bfg)            { spawnfunc_item_cells(this);          }
+SPAWNFUNC_WEAPON(weapon_bfg, WEP_CRYLINK)
+SPAWNFUNC_ITEM(ammo_bfg, ITEM_Cells)
 
 // grappling hook -> hook
-spawnfunc(weapon_grapplinghook) { spawnfunc_weapon_hook(this);        }
+SPAWNFUNC_WEAPON(weapon_grapplinghook, WEP_HOOK)
 
 // RL -> RL
-spawnfunc(ammo_rockets)        { spawnfunc_item_rockets(this);        }
+SPAWNFUNC_ITEM(ammo_rockets, ITEM_Rockets)
 
 // Armor
-spawnfunc(item_armor_body)     { spawnfunc_item_armor_mega(this);     }
-spawnfunc(item_armor_combat)   { spawnfunc_item_armor_big(this);      }
-spawnfunc(item_armor_shard)    { spawnfunc_item_armor_small(this);    }
-spawnfunc(item_enviro)         { spawnfunc_item_invincible(this);     }
+SPAWNFUNC_ITEM(item_armor_body, ITEM_ArmorMega)
+SPAWNFUNC_ITEM(item_armor_combat, ITEM_ArmorBig)
+SPAWNFUNC_ITEM(item_armor_shard, ITEM_ArmorSmall)
+SPAWNFUNC_ITEM(item_enviro, ITEM_Shield)
 
 // medkit -> armor (we have no holdables)
-spawnfunc(holdable_medkit)        { spawnfunc_item_armor_mega(this);     }
+SPAWNFUNC_ITEM(holdable_medkit, ITEM_ArmorMega)
 
 // doubler -> strength
-spawnfunc(item_doubler)        { spawnfunc_item_strength(this); }
+SPAWNFUNC_ITEM(item_doubler, ITEM_Strength)
 
 .float wait;
 .float delay;
index 39abab0..d2577b4 100644 (file)
@@ -9,39 +9,34 @@ spawnfunc(item_haste);
 spawnfunc(item_invis);
 
 //***********************
-//WORD OF PADMAN ENTITIES - So people can play wop maps with the xonotic weapons
+//WORLD OF PADMAN ENTITIES - So people can play wop maps with the xonotic weapons
 //***********************
 
 //spawnfunc(item_revival)     /* handled by buffs mutator */
 //spawnfunc(item_jumper)      /* handled by buffs mutator */
 
-spawnfunc(weapon_punchy)       { spawnfunc_weapon_arc(this);                   }
-spawnfunc(weapon_nipper)       { spawnfunc_weapon_machinegun(this);    }
-spawnfunc(weapon_pumper)       { spawnfunc_weapon_shotgun(this);               }
-spawnfunc(weapon_boaster)      { spawnfunc_weapon_electro(this);               }
-spawnfunc(weapon_splasher)     { spawnfunc_weapon_vortex(this);                }
-spawnfunc(weapon_bubbleg)      { spawnfunc_weapon_hagar(this);                 }
-spawnfunc(weapon_balloony)     { spawnfunc_weapon_mortar(this);                }
-spawnfunc(weapon_betty)                { spawnfunc_weapon_devastator(this);    }
-spawnfunc(weapon_imperius)     { spawnfunc_weapon_crylink(this);               }
-
-spawnfunc(ammo_pumper)         { spawnfunc_item_shells(this);                  }
-spawnfunc(ammo_nipper)         { spawnfunc_item_bullets(this);                 }
-spawnfunc(ammo_balloony)       { spawnfunc_item_rockets(this);                 }
-spawnfunc(ammo_bubbleg)                { spawnfunc_item_rockets(this);                 }
-spawnfunc(ammo_boaster)                { spawnfunc_item_cells(this);                   }
-spawnfunc(ammo_betty)          { spawnfunc_item_rockets(this);                 }
-spawnfunc(ammo_imperius)       { spawnfunc_item_cells(this);                   }
-
-spawnfunc(item_quad)
-{
-       this.classname = "item_strength";
-       spawnfunc_item_strength(this);
-}
-spawnfunc(item_padpower)       { spawnfunc_item_quad(this);                    }
-spawnfunc(item_climber)                { spawnfunc_item_invincible(this);              }
+SPAWNFUNC_WEAPON(weapon_punchy, WEP_ARC)
+SPAWNFUNC_WEAPON(weapon_nipper, WEP_MACHINEGUN)
+SPAWNFUNC_WEAPON(weapon_pumper, WEP_SHOTGUN)
+SPAWNFUNC_WEAPON(weapon_boaster, WEP_ELECTRO)
+SPAWNFUNC_WEAPON(weapon_splasher, WEP_VORTEX)
+SPAWNFUNC_WEAPON(weapon_bubbleg, WEP_HAGAR)
+SPAWNFUNC_WEAPON(weapon_balloony, WEP_MORTAR)
+SPAWNFUNC_WEAPON(weapon_betty, WEP_DEVASTATOR)
+SPAWNFUNC_WEAPON(weapon_imperius, WEP_CRYLINK)
+
+SPAWNFUNC_ITEM(ammo_pumper, ITEM_Shells)
+SPAWNFUNC_ITEM(ammo_nipper, ITEM_Bullets)
+SPAWNFUNC_ITEM(ammo_balloony, ITEM_Rockets)
+SPAWNFUNC_ITEM(ammo_bubbleg, ITEM_Rockets)
+SPAWNFUNC_ITEM(ammo_boaster, ITEM_Cells)
+SPAWNFUNC_ITEM(ammo_betty, ITEM_Rockets)
+SPAWNFUNC_ITEM(ammo_imperius, ITEM_Cells)
+
+SPAWNFUNC_ITEM(item_padpower, ITEM_Strength)
+SPAWNFUNC_ITEM(item_climber, ITEM_Shield)
 spawnfunc(item_speedy)         { spawnfunc_item_haste(this);                   }
 spawnfunc(item_visionless)     { spawnfunc_item_invis(this);                   }
-spawnfunc(item_armor_padshield)        { spawnfunc_item_armor_mega(this);      }
+SPAWNFUNC_ITEM(item_armor_padshield, ITEM_ArmorMega)
 
-spawnfunc(holdable_floater)            { spawnfunc_item_jetpack(this);         }
+SPAWNFUNC_ITEM(holdable_floater, ITEM_Jetpack)
index f2f47c4..6a05932 100644 (file)
@@ -27,240 +27,17 @@ entity Item_Create(string class_name, vector position)
 
 void Item_Initialize(entity item, string class_name)
 {
-       switch (class_name)
+       FOREACH(Weapons, it.m_canonical_spawnfunc == class_name,
        {
-               case "item_health_small":
-               {
-                       spawnfunc_item_health_small(item);
-                       return;
-               }
-               case "item_health_medium":
-               {
-                       spawnfunc_item_health_medium(item);
-                       return;
-               }
-               case "item_health_big":
-               case "item_health_large":
-               {
-                       spawnfunc_item_health_big(item);
-                       return;
-               }
-               case "item_health_mega":
-               {
-                       spawnfunc_item_health_mega(item);
-                       return;
-               }
-               case "item_armor_small":
-               {
-                       spawnfunc_item_armor_small(item);
-                       return;
-               }
-               case "item_armor_medium":
-               {
-                       spawnfunc_item_armor_medium(item);
-                       return;
-               }
-               case "item_armor_big":
-               case "item_armor_large":
-               {
-                       spawnfunc_item_armor_big(item);
-                       return;
-               }
-               case "item_armor_mega":
-               {
-                       spawnfunc_item_armor_mega(item);
-                       return;
-               }
-               case "item_shells":
-               {
-                       spawnfunc_item_shells(item);
-                       return;
-               }
-               case "item_bullets":
-               {
-                       spawnfunc_item_bullets(item);
-                       return;
-               }
-               case "item_rockets":
-               {
-                       spawnfunc_item_rockets(item);
-                       return;
-               }
-               case "item_cells":
-               {
-                       spawnfunc_item_cells(item);
-                       return;
-               }
-               case "item_plasma":
-               {
-                       spawnfunc_item_plasma(item);
-                       return;
-               }
-               case "item_fuel":
-               {
-                       spawnfunc_item_fuel(item);
-                       return;
-               }
-               case "weapon_blaster":
-               case "weapon_laser":
-               {
-                       spawnfunc_weapon_blaster(item);
-                       return;
-               }
-               case "weapon_shotgun":
-               {
-                       spawnfunc_weapon_shotgun(item);
-                       return;
-               }
-               case "weapon_machinegun":
-               case "weapon_uzi":
-               {
-                       spawnfunc_weapon_machinegun(item);
-                       return;
-               }
-               case "weapon_mortar":
-               case "weapon_grenadelauncher":
-               {
-                       spawnfunc_weapon_mortar(item);
-                       return;
-               }
-               case "weapon_electro":
-               {
-                       spawnfunc_weapon_electro(item);
-                       return;
-               }
-               case "weapon_crylink":
-               {
-                       spawnfunc_weapon_crylink(item);
-                       return;
-               }
-               case "weapon_vortex":
-               case "weapon_nex":
-               {
-                       spawnfunc_weapon_vortex(item);
-                       return;
-               }
-               case "weapon_hagar":
-               {
-                       spawnfunc_weapon_hagar(item);
-                       return;
-               }
-               case "weapon_devastator":
-               case "weapon_rocketlauncher":
-               {
-                       spawnfunc_weapon_devastator(item);
-                       return;
-               }
-               case "weapon_shockwave":
-               {
-                       spawnfunc_weapon_shockwave(item);
-                       return;
-               }
-               case "weapon_arc":
-               {
-                       spawnfunc_weapon_arc(item);
-                       return;
-               }
-               case "weapon_hook":
-               {
-                       spawnfunc_weapon_hook(item);
-                       return;
-               }
-               case "weapon_tuba":
-               {
-                       spawnfunc_weapon_tuba(item);
-                       return;
-               }
-               case "weapon_porto":
-               {
-                       spawnfunc_weapon_porto(item);
-                       return;
-               }
-               case "weapon_fireball":
-               {
-                       spawnfunc_weapon_fireball(item);
-                       return;
-               }
-               case "weapon_minelayer":
-               {
-                       spawnfunc_weapon_minelayer(item);
-                       return;
-               }
-               case "weapon_hlac":
-               {
-                       spawnfunc_weapon_hlac(item);
-                       return;
-               }
-               case "weapon_rifle":
-               case "weapon_campingrifle":
-               case "weapon_sniperrifle":
-               {
-                       spawnfunc_weapon_rifle(item);
-                       return;
-               }
-               case "weapon_seeker":
-               {
-                       spawnfunc_weapon_seeker(item);
-                       return;
-               }
-               case "weapon_vaporizer":
-               case "weapon_minstanex":
-               {
-                       spawnfunc_weapon_vaporizer(item);
-                       return;
-               }
-               case "weapon_hmg":
-               {
-                       spawnfunc_weapon_hmg(item);
-                       return;
-               }
-               case "weapon_rpc":
-               {
-                       spawnfunc_weapon_rpc(item);
-                       return;
-               }
-               case "item_strength":
-               {
-                       spawnfunc_item_strength(item);
-                       return;
-               }
-               case "item_invincible":
-               {
-                       spawnfunc_item_invincible(item);
-                       return;
-               }
-               case "item_fuel_regen":
-               {
-                       spawnfunc_item_fuel_regen(item);
-                       return;
-               }
-               case "item_jetpack":
-               {
-                       spawnfunc_item_jetpack(item);
-                       return;
-               }
-               case "item_vaporizer_cells":
-               {
-                       spawnfunc_item_vaporizer_cells(item);
-                       return;
-               }
-               case "item_invisibility":
-               {
-                       instagib_invisibility(item);
-                       return;
-               }
-               case "item_extralife":
-               {
-                       instagib_extralife(item);
-                       return;
-               }
-               case "item_speed":
-               {
-                       instagib_speed(item);
-                       return;
-               }
-       }
-       error("Item_Initialize: Invalid classname ", class_name);
+               weapon_defaultspawnfunc(item, it);
+               return;
+       });
+       FOREACH(Items, it.m_canonical_spawnfunc == class_name,
+       {
+               StartItem(item, it);
+               return;
+       });
+       LOG_FATALF("Item_Initialize: Invalid classname: %s", class_name);
 }
 
 entity Item_CreateLoot(string class_name, vector position, vector vel,
@@ -304,162 +81,21 @@ void Item_SetLoot(entity item, bool loot)
        item.m_isloot = loot;
 }
 
-spawnfunc(item_health_small)
-{
-       StartItem(this, ITEM_HealthSmall);
-}
-
-spawnfunc(item_health_medium)
-{
-       StartItem(this, ITEM_HealthMedium);
-}
-
-spawnfunc(item_health_big)
-{
-       StartItem(this, ITEM_HealthBig);
-}
-
-spawnfunc(item_health_mega)
-{
-       StartItem(this, ITEM_HealthMega);
-}
-
-spawnfunc(item_armor_small)
-{
-       StartItem(this, ITEM_ArmorSmall);
-}
-
-spawnfunc(item_armor_medium)
-{
-       StartItem(this, ITEM_ArmorMedium);
-}
-
-spawnfunc(item_armor_big)
-{
-       StartItem(this, ITEM_ArmorBig);
-}
-
-spawnfunc(item_armor_mega)
-{
-       StartItem(this, ITEM_ArmorMega);
-}
-
-spawnfunc(item_shells)
-{
-       if (!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap &&
-               (this.classname != "droppedweapon"))
-       {
-               weaponswapping = true;
-               spawnfunc_item_bullets(this);
-               weaponswapping = false;
-               return;
-       }
-       StartItem(this, ITEM_Shells);
-}
-
-spawnfunc(item_bullets)
-{
-       if (!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap &&
-               (this.classname != "droppedweapon"))
-       {
-               weaponswapping = true;
-               spawnfunc_item_shells(this);
-               weaponswapping = false;
-               return;
-       }
-       StartItem(this, ITEM_Bullets);
-}
-
-spawnfunc(item_rockets)
-{
-       StartItem(this, ITEM_Rockets);
-}
-
-spawnfunc(item_cells)
-{
-       StartItem(this, ITEM_Cells);
-}
-
-spawnfunc(item_plasma)
-{
-       StartItem(this, ITEM_Plasma);
-}
-
-spawnfunc(item_fuel)
-{
-       StartItem(this, ITEM_JetpackFuel);
-}
-
-spawnfunc(item_strength)
-{
-       StartItem(this, ITEM_Strength);
-}
-
-spawnfunc(item_invincible)
-{
-       StartItem(this, ITEM_Shield);
-}
-
-spawnfunc(item_fuel_regen)
-{
-       if (start_items & ITEM_JetpackRegen.m_itemid)
-       {
-               spawnfunc_item_fuel(this);
-               return;
-       }
-       StartItem(this, ITEM_JetpackRegen);
-}
-
-spawnfunc(item_jetpack)
-{
-       if(start_items & ITEM_Jetpack.m_itemid)
-       {
-               spawnfunc_item_fuel(this);
-               return;
-       }
-       StartItem(this, ITEM_Jetpack);
-}
-
 // Compatibility spawn functions
 
-spawnfunc(item_armor1)
-{
-       this.classname = "item_armor_small";
-       spawnfunc_item_armor_small(this); // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
-}
+// FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
+SPAWNFUNC_ITEM(item_armor1, ITEM_ArmorSmall)
 
-spawnfunc(item_armor25)
-{
-       this.classname = "item_armor_mega";
-       spawnfunc_item_armor_mega(this);
-}
+SPAWNFUNC_ITEM(item_armor25, ITEM_ArmorMega)
 
-spawnfunc(item_armor_large)
-{
-       this.classname = "item_armor_mega";
-       spawnfunc_item_armor_mega(this);
-}
+SPAWNFUNC_ITEM(item_armor_large, ITEM_ArmorMega)
 
-spawnfunc(item_health1)
-{
-       this.classname = "item_health_small";
-       spawnfunc_item_health_small(this);
-}
+SPAWNFUNC_ITEM(item_health1, ITEM_HealthSmall)
 
-spawnfunc(item_health25)
-{
-       this.classname = "item_health_medium";
-       spawnfunc_item_health_medium(this);
-}
+SPAWNFUNC_ITEM(item_health25, ITEM_HealthMedium)
 
-spawnfunc(item_health_large)
-{
-       this.classname = "item_health_big";
-       spawnfunc_item_health_big(this);
-}
+SPAWNFUNC_ITEM(item_health_large, ITEM_HealthBig)
 
-spawnfunc(item_health100)
-{
-       this.classname = "item_health_mega";
-       spawnfunc_item_health_mega(this);
-}
+SPAWNFUNC_ITEM(item_health100, ITEM_HealthMega)
+
+SPAWNFUNC_ITEM(item_quad, ITEM_Strength)
index 37b7d10..f7e3013 100644 (file)
@@ -1,3 +1,4 @@
+#pragma once
 /// \file
 /// \brief Header file that describes the functions related to game items.
 /// \copyright GNU GPLv2 or any later version.
@@ -49,27 +50,3 @@ bool Item_IsLoot(entity item);
 /// \return No return.
 void Item_SetLoot(entity item, bool loot);
 
-// Item spawn functions.
-// If a function is declared like this:
-// spawnfunc(foo);
-// You need to call it like this:
-// spawnfunc_foo(item);
-
-spawnfunc(item_health_small);
-spawnfunc(item_health_medium);
-spawnfunc(item_health_big);
-spawnfunc(item_health_mega);
-spawnfunc(item_armor_small);
-spawnfunc(item_armor_medium);
-spawnfunc(item_armor_big);
-spawnfunc(item_armor_mega);
-spawnfunc(item_shells);
-spawnfunc(item_bullets);
-spawnfunc(item_rockets);
-spawnfunc(item_cells);
-spawnfunc(item_plasma);
-spawnfunc(item_fuel);
-spawnfunc(item_strength);
-spawnfunc(item_invincible);
-spawnfunc(item_fuel_regen);
-spawnfunc(item_jetpack);
index ab837c8..e3c6797 100644 (file)
@@ -653,7 +653,7 @@ void readplayerstartcvars()
                        "g_random_start_shells"));
                SetResourceAmount(random_start_ammo, RESOURCE_BULLETS, cvar(
                        "g_random_start_bullets"));
-               SetResourceAmount(random_start_ammo, RESOURCE_ROCKETS, 
+               SetResourceAmount(random_start_ammo, RESOURCE_ROCKETS,
                        cvar("g_random_start_rockets"));
                SetResourceAmount(random_start_ammo, RESOURCE_CELLS, cvar(
                        "g_random_start_cells"));
index d5b78aa..244c1c6 100644 (file)
@@ -26,6 +26,8 @@ string W_Apply_Weaponreplace(string in)
 void weapon_defaultspawnfunc(entity this, Weapon e)
 {
        Weapon wpn = e;
+       e = wpn = wpn.m_spawnfunc_hookreplace(wpn, this);
+       this.classname = wpn.m_canonical_spawnfunc;
        if (this.classname != "droppedweapon" && this.classname != "replacedweapon")
        {
                if (e.spawnflags & WEP_FLAG_MUTATORBLOCKED)
index 4ddf5a5..c53b150 100644 (file)
@@ -4,7 +4,6 @@
 #include <server/miscfunctions.qh>
 
 float internalteam;
-float weaponswapping;
 entity weapon_dropevent_item;
 
 ..entity weaponentity_fld;