]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into TimePath/spawnfunc 227/head
authorTimePath <andrew.hardaker1995@gmail.com>
Sat, 3 Oct 2015 07:17:49 +0000 (17:17 +1000)
committerTimePath <andrew.hardaker1995@gmail.com>
Sat, 3 Oct 2015 07:19:10 +0000 (17:19 +1000)
# Conflicts:
# qcsrc/common/turrets/unit/ewheel.qc
# qcsrc/common/turrets/unit/flac.qc
# qcsrc/common/turrets/unit/fusionreactor.qc
# qcsrc/common/turrets/unit/hellion.qc
# qcsrc/common/turrets/unit/hk.qc
# qcsrc/common/turrets/unit/machinegun.qc
# qcsrc/common/turrets/unit/mlrs.qc
# qcsrc/common/turrets/unit/phaser.qc
# qcsrc/common/turrets/unit/plasma.qc
# qcsrc/common/turrets/unit/plasma_dual.qc
# qcsrc/common/turrets/unit/tesla.qc
# qcsrc/common/turrets/unit/walker.qc
# qcsrc/server/t_items.qc

66 files changed:
1  2 
qcsrc/common/monsters/monster/mage.qc
qcsrc/common/monsters/monster/shambler.qc
qcsrc/common/monsters/monster/spider.qc
qcsrc/common/monsters/sv_monsters.qc
qcsrc/common/triggers/func/breakable.qc
qcsrc/common/triggers/func/button.qc
qcsrc/common/triggers/func/door.qc
qcsrc/common/triggers/func/door_secret.qc
qcsrc/common/triggers/func/pointparticles.qc
qcsrc/common/triggers/func/train.qc
qcsrc/common/triggers/target/music.qc
qcsrc/common/triggers/target/speaker.qc
qcsrc/common/triggers/trigger/gravity.qc
qcsrc/common/triggers/trigger/heal.qc
qcsrc/common/triggers/trigger/jumppads.qc
qcsrc/common/triggers/trigger/keylock.qc
qcsrc/common/triggers/trigger/multi.qc
qcsrc/common/turrets/unit/ewheel.qc
qcsrc/common/turrets/unit/flac.qc
qcsrc/common/turrets/unit/fusionreactor.qc
qcsrc/common/turrets/unit/hellion.qc
qcsrc/common/turrets/unit/hk.qc
qcsrc/common/turrets/unit/machinegun.qc
qcsrc/common/turrets/unit/mlrs.qc
qcsrc/common/turrets/unit/phaser.qc
qcsrc/common/turrets/unit/plasma.qc
qcsrc/common/turrets/unit/plasma_dual.qc
qcsrc/common/turrets/unit/tesla.qc
qcsrc/common/turrets/unit/walker.qc
qcsrc/common/vehicles/unit/bumblebee.qc
qcsrc/common/vehicles/unit/racer.qc
qcsrc/common/vehicles/unit/raptor.qc
qcsrc/common/vehicles/unit/spiderbot.qc
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/blaster.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/hmg.qc
qcsrc/common/weapons/weapon/hook.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/porto.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/rpc.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/lib/_all.inc
qcsrc/server/cheats.qc
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/item_key.qc
qcsrc/server/mutators/gamemode_ctf.qc
qcsrc/server/mutators/gamemode_domination.qc
qcsrc/server/mutators/gamemode_nexball.qc
qcsrc/server/mutators/gamemode_onslaught.qc
qcsrc/server/mutators/mutator_instagib.qc
qcsrc/server/mutators/mutator_overkill.qc
qcsrc/server/t_items.qc

index f30c62e21696150ff2267bcbb3030a640ef77cb8,534005db93f558ea4bf25b9f80a53dc351b7f08a..433fed6830e23c050bb1a9aa69678cb4f420ba7a
@@@ -91,7 -91,7 +91,7 @@@ void M_Mage_Attack_Spike_Explode(
  {SELFPARAM();
        self.event_damage = func_null;
  
-       sound(self, CH_SHOTS, W_Sound("grenade_impact"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
  
        self.realowner.mage_spike = world;
  
@@@ -258,7 -258,7 +258,7 @@@ void M_Mage_Defend_Heal(
  
  void M_Mage_Attack_Push()
  {SELFPARAM();
-       sound(self, CH_SHOTS, W_Sound("tagexp1"), 1, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM);
        RadiusDamage (self, self, (autocvar_g_monster_mage_attack_push_damage), (autocvar_g_monster_mage_attack_push_damage), (autocvar_g_monster_mage_attack_push_radius), world, world, (autocvar_g_monster_mage_attack_push_force), DEATH_MONSTER_MAGE, self.enemy);
        Send_Effect(EFFECT_TE_EXPLOSION, self.origin, '0 0 0', 1);
  
@@@ -343,7 -343,7 +343,7 @@@ float M_Mage_Attack(float attack_type
        return false;
  }
  
 -void spawnfunc_monster_mage() { Monster_Spawn(MON_MAGE.monsterid); }
 +spawnfunc(monster_mage) { Monster_Spawn(MON_MAGE.monsterid); }
  
  #endif // SVQC
  
@@@ -422,8 -422,6 +422,6 @@@ bool M_Mage(int req
                }
                case MR_PRECACHE:
                {
-                       precache_sound (W_Sound("grenade_impact"));
-                       precache_sound (W_Sound("tagexp1"));
                        return true;
                }
                #endif
index 3354d2f2007bc7d5a062b7ff2410cb7682a66284,55e0f46e95413053bd525a6ce185437b17c06c88..fe6078303cb5cacd1b488e0bccb38d0b8f6e6490
@@@ -50,7 -50,7 +50,7 @@@ void M_Shambler_Attack_Smash(
  {SELFPARAM();
        makevectors(self.angles);
        Send_Effect(EFFECT_EXPLOSION_MEDIUM, (self.origin + (v_forward * 150)) - ('0 0 1' * self.maxs.z), '0 0 0', 1);
-       sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
  
        // RadiusDamage does NOT support custom starting location, which means we must use this hack...
  
@@@ -75,7 -75,7 +75,7 @@@ void M_Shambler_Attack_Lightning_Explod
  {SELFPARAM();
        entity head;
  
-       sound(self, CH_SHOTS, W_Sound("electro_impact"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM);
        Send_Effect(EFFECT_ELECTRO_IMPACT, '0 0 0', '0 0 0', 1);
  
        self.event_damage = func_null;
@@@ -211,7 -211,7 +211,7 @@@ float M_Shambler_Attack(float attack_ty
        return false;
  }
  
 -void spawnfunc_monster_shambler() { Monster_Spawn(MON_SHAMBLER.monsterid); }
 +spawnfunc(monster_shambler) { Monster_Spawn(MON_SHAMBLER.monsterid); }
  #endif // SVQC
  
  bool M_Shambler(int req)
index f2bc7d789514f09e9e7f8ca4fd4770f316beb074,f6c3089ce358d0c45b64e985f04d507a674d29e5..ba2b12695d8d9a2eb85273814b162cc161a6ac00
@@@ -63,7 -63,7 +63,7 @@@ void M_Spider_Attack_Web(
  {SELFPARAM();
        monster_makevectors(self.enemy);
  
-       sound(self, CH_SHOTS, W_Sound("electro_fire2"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_ELECTRO_FIRE2, VOL_BASE, ATTEN_NORM);
  
        entity proj = spawn ();
        proj.classname = "plasma";
@@@ -124,7 -124,7 +124,7 @@@ bool M_Spider_Attack(int attack_type
        return false;
  }
  
 -void spawnfunc_monster_spider() { Monster_Spawn(MON_SPIDER.monsterid); }
 +spawnfunc(monster_spider) { Monster_Spawn(MON_SPIDER.monsterid); }
  #endif // SVQC
  
  bool M_Spider(int req)
                }
                case MR_PRECACHE:
                {
-                       precache_sound (W_Sound("electro_fire2"));
                        return true;
                }
                #endif
index 519a5322e02b0ca9a6235bd0893659477d99d7bc,0734d54d56943b7e71809c383eaf68e722c2b90e..af251215ba9d63e13e5cf8ee68689347ca0aa2c1
@@@ -49,7 -49,7 +49,7 @@@ void monster_dropitem(
        {
                setself(e);
                e.noalign = true;
 -              e.monster_loot();
 +              e.monster_loot(e);
                e.gravity = 1;
                e.movetype = MOVETYPE_TOSS;
                e.reset = SUB_Remove;
@@@ -118,7 -118,7 +118,7 @@@ bool Monster_ValidTarget(entity mon, en
                makevectors (mon.angles);
                dot = normalize (player.origin - mon.origin) * v_forward;
  
-               if(dot <= 0.3) { return false; }
+               if(dot <= autocvar_g_monsters_target_infront_range) { return false; }
        }
  
        return true; // this target is valid!
@@@ -1085,7 -1085,7 +1085,7 @@@ void Monster_Damage(entity inflictor, e
        self.dmg_time = time;
  
        if(sound_allowed(MSG_BROADCAST, attacker) && deathtype != DEATH_DROWN)
-               spamsound (self, CH_PAIN, "misc/bodyimpact1.wav", VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
+               spamsound (self, CH_PAIN, SND(BODYIMPACT1), VOL_BASE, ATTEN_NORM);  // FIXME: PLACEHOLDER
  
        self.velocity += force * self.damageforcescale;
  
index 09ae8002b237211302031b806266bd8388b68ef9,b2a4894a5238a84f6cfa1dc7d901cc316860e7cf..af9a6b4233124190ad4ab1a417d8f6562739190b
@@@ -162,7 -162,7 +162,7 @@@ void func_breakable_behave_restore(
        self.nextthink = 0; // cancel auto respawn
        func_breakable_colormod();
        if (self.noise1)
-               sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
  }
  
  void func_breakable_init_for_player(entity player)
@@@ -207,7 -207,7 +207,7 @@@ void func_breakable_destroy(
        func_breakable_destroyed();
  
        if(self.noise)
-               sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
  
        if(self.dmg)
                RadiusDamage(self, activator, self.dmg, self.dmg_edge, self.dmg_radius, self, world, self.dmg_force, DEATH_HURTTRIGGER, world);
@@@ -266,8 -266,8 +266,8 @@@ void func_breakable_reset(
  }
  
  // destructible walls that can be used to trigger target_objective_decrease
 -void spawnfunc_func_breakable()
 -{SELFPARAM();
 +spawnfunc(func_breakable)
 +{
        float n, i;
        if(!self.health)
                self.health = 100;
  }
  
  // for use in maps with a "model" key set
 -void spawnfunc_misc_breakablemodel() {
 -      spawnfunc_func_breakable();
 +spawnfunc(misc_breakablemodel) {
 +      spawnfunc_func_breakable(this);
  }
  #endif
index 17a30cfd03c61984b984a871fb35ac6120f50fe3,a55f02ef2fcc003852ef8aadde68dc799326f147..ab1cff538ef2e1bbbd6c020208578ce326ae7a03
@@@ -44,7 -44,7 +44,7 @@@ void button_fire(
                return;
  
        if (self.noise != "")
-               sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
  
        self.state = STATE_UP;
        SUB_CalcMove (self.pos2, TSPEED_LINEAR, self.speed, button_wait);
@@@ -112,8 -112,8 +112,8 @@@ When a button is touched, it moves som
  2) metallic click
  3) in-out
  */
 -void spawnfunc_func_button()
 -{SELFPARAM();
 +spawnfunc(func_button)
 +{
        SetMovedir ();
  
        if (!InitMovingBrushTrigger())
index 7abbe08809da076c37610254e03f125a22f7f47d,422295fa86397510b3230fb87912f490a39059ef..fed8e9fa424515b9c3aa8aa5aa3f5029e07b3529
@@@ -87,7 -87,7 +87,7 @@@ void door_blocked(
  void door_hit_top()
  {SELFPARAM();
        if (self.noise1 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
        self.state = STATE_TOP;
        if (self.spawnflags & DOOR_TOGGLE)
                return;         // don't come down automatically
  void door_hit_bottom()
  {SELFPARAM();
        if (self.noise1 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
        self.state = STATE_BOTTOM;
  }
  
  void door_go_down()
  {SELFPARAM();
        if (self.noise2 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        if (self.max_health)
        {
                self.takedamage = DAMAGE_YES;
@@@ -134,7 -134,7 +134,7 @@@ void door_go_up(
        }
  
        if (self.noise2 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        self.state = STATE_UP;
        SUB_CalcMove (self.pos2, TSPEED_LINEAR, self.speed, door_hit_top);
  
@@@ -180,7 -180,7 +180,7 @@@ float door_check_keys(void
                if (other.key_door_messagetime <= time)
                {
  
-                       play2(other, "misc/talk.wav");
+                       play2(other, SND(TALK));
                        Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_ALSONEED, item_keys_keylist(door.itemkeys));
                        other.key_door_messagetime = time + 2;
                }
                // no keys were used
                if (other.key_door_messagetime <= time)
                {
-                       play2(other, "misc/talk.wav");
+                       play2(other, SND(TALK));
                        Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_LOCKED_NEED, item_keys_keylist(door.itemkeys));
  
                        other.key_door_messagetime = time + 2;
        {
  #ifdef SVQC
                // door is now unlocked
-               play2(other, "misc/talk.wav");
+               play2(other, SND(TALK));
                Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_DOOR_UNLOCKED);
  #endif
                return true;
@@@ -321,7 -321,7 +321,7 @@@ void door_touch(
        {
                if (IS_CLIENT(other))
                        centerprint(other, self.owner.message);
-               play2(other, "misc/talk.wav");
+               play2(other, SND(TALK));
        }
  #endif
  }
@@@ -367,7 -367,7 +367,7 @@@ void door_generic_plat_blocked(
  void door_rotating_hit_top()
  {SELFPARAM();
        if (self.noise1 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
        self.state = STATE_TOP;
        if (self.spawnflags & DOOR_TOGGLE)
                return;         // don't come down automatically
  void door_rotating_hit_bottom()
  {SELFPARAM();
        if (self.noise1 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
        if (self.lip==666) // self.lip is used to remember reverse opening direction for door_rotating
        {
                self.pos2 = '0 0 0' - self.pos2;
  void door_rotating_go_down()
  {SELFPARAM();
        if (self.noise2 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        if (self.max_health)
        {
                self.takedamage = DAMAGE_YES;
@@@ -412,7 -412,7 +412,7 @@@ void door_rotating_go_up(
                return;
        }
        if (self.noise2 != "")
-               sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound (self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        self.state = STATE_UP;
        SUB_CalcAngleMove (self.pos2, TSPEED_LINEAR, self.speed, door_rotating_hit_top);
  
@@@ -723,8 -723,8 +723,8 @@@ void door_reset(
  #ifdef SVQC
  
  // spawnflags require key (for now only func_door)
 -void spawnfunc_func_door()
 -{SELFPARAM();
 +spawnfunc(func_door)
 +{
        // Quake 1 keys compatibility
        if (self.spawnflags & SPAWNFLAGS_GOLD_KEY)
                self.itemkeys |= ITEM_KEY_BIT(0);
index 10536fd943d7a2a5da40d2f407f536ed1484b9f0,5b2cfc5ba05a4f620bc541279dbf59c6dc28d970..8686c671f7c097c3a5307ecca54e478ef2b3734b
@@@ -35,7 -35,7 +35,7 @@@ void fd_secret_use(
        // Make a sound, wait a little...
  
        if (self.noise1 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise1, VOL_BASE, ATTEN_NORM);
        self.SUB_NEXTTHINK = self.SUB_LTIME + 0.1;
  
        temp = 1 - (self.spawnflags & SECRET_1ST_LEFT); // 1 or -1
@@@ -60,7 -60,7 +60,7 @@@
        self.dest2 = self.dest1 + v_forward * self.t_length;
        SUB_CalcMove(self.dest1, TSPEED_LINEAR, self.speed, fd_secret_move1);
        if (self.noise2 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
  }
  
  void fd_secret_damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
@@@ -74,14 -74,14 +74,14 @@@ void fd_secret_move1(
        self.SUB_NEXTTHINK = self.SUB_LTIME + 1.0;
        self.think = fd_secret_move2;
        if (self.noise3 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
  }
  
  // Start moving sideways w/sound...
  void fd_secret_move2()
  {SELFPARAM();
        if (self.noise2 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        SUB_CalcMove(self.dest2, TSPEED_LINEAR, self.speed, fd_secret_move3);
  }
  
@@@ -89,7 -89,7 +89,7 @@@
  void fd_secret_move3()
  {SELFPARAM();
        if (self.noise3 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
        if (!(self.spawnflags & SECRET_OPEN_ONCE))
        {
                self.SUB_NEXTTHINK = self.SUB_LTIME + self.wait;
  void fd_secret_move4()
  {SELFPARAM();
        if (self.noise2 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        SUB_CalcMove(self.dest1, TSPEED_LINEAR, self.speed, fd_secret_move5);
  }
  
@@@ -111,13 -111,13 +111,13 @@@ void fd_secret_move5(
        self.SUB_NEXTTHINK = self.SUB_LTIME + 1.0;
        self.think = fd_secret_move6;
        if (self.noise3 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
  }
  
  void fd_secret_move6()
  {SELFPARAM();
        if (self.noise2 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise2, VOL_BASE, ATTEN_NORM);
        SUB_CalcMove(self.oldorigin, TSPEED_LINEAR, self.speed, fd_secret_done);
  }
  
@@@ -130,7 -130,7 +130,7 @@@ void fd_secret_done(
                //self.th_pain = fd_secret_use;
        }
        if (self.noise3 != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise3, VOL_BASE, ATTEN_NORM);
  }
  
  void secret_blocked()
@@@ -161,7 -161,7 +161,7 @@@ void secret_touch(
        {
                if (IS_CLIENT(other))
                        centerprint(other, self.message);
-               play2(other, "misc/talk.wav");
+               play2(other, SND(TALK));
        }
  }
  
@@@ -194,8 -194,8 +194,8 @@@ If a secret door has a targetname, it w
  3) base
  */
  
 -void spawnfunc_func_door_secret()
 -{SELFPARAM();
 +spawnfunc(func_door_secret)
 +{
        /*if (!self.deathtype) // map makers can override this
                self.deathtype = " got in the way";*/
  
index 25764f38700dc1524ed40f661ed8cc39125834ac,058f1199f405189a11e4026c43464c6535109a4d..04ab77f7fd70a4d3fd93f64b2cf26174416a7806
@@@ -112,8 -112,8 +112,8 @@@ void pointparticles_reset(
                self.state = 0;
  }
  
 -void spawnfunc_func_pointparticles()
 -{SELFPARAM();
 +spawnfunc(func_pointparticles)
 +{
        if(self.model != "")
                _setmodel(self, self.model);
        if(self.noise != "")
        self.nextthink = time;
  }
  
 -void spawnfunc_func_sparks()
 -{SELFPARAM();
 +spawnfunc(func_sparks)
 +{
        // self.cnt is the amount of sparks that one burst will spawn
        if(self.cnt < 1) {
                self.cnt = 25.0; // nice default value
        self.wait = 0;
        self.cnt = 0; // use mdl
  
 -      spawnfunc_func_pointparticles();
 +      spawnfunc_func_pointparticles(this);
  }
  #elif defined(CSQC)
  
@@@ -230,7 -230,7 +230,7 @@@ void Draw_PointParticles(
                        if(self.noise != "")
                        {
                                setorigin(self, p);
-                               sound(self, CH_AMBIENT, self.noise, VOL_BASE * self.volume, self.atten);
+                               _sound(self, CH_AMBIENT, self.noise, VOL_BASE * self.volume, self.atten);
                        }
                        self.just_toggled = 0;
                }
index 60c8730eb68bb258c378eba2a9230eb18680dc9d,187fd3f1b97be9174c2bbdf962be42f507c0c104..4284d24031e6d609f16428e146707ce1d5366747
@@@ -98,7 -98,7 +98,7 @@@ void train_next(
        }
  
        if(self.noise != "")
-               sound(self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTEN_IDLE);
+               _sound(self, CH_TRIGGER_SINGLE, self.noise, VOL_BASE, ATTEN_IDLE);
  }
  
  #ifdef SVQC
@@@ -183,8 -183,8 +183,8 @@@ speed : speed the train moves (can be o
  target : targetname of first spawnfunc_path_corner (starts here)
  */
  #ifdef SVQC
 -void spawnfunc_func_train()
 -{SELFPARAM();
 +spawnfunc(func_train)
 +{
        if (self.noise != "")
                precache_sound(self.noise);
  
index 2c5262885a58c69a7240de4a184eae947199134a,879c3042329c3898de0e252a1eddbd864181d9c1..2748ed6f63af351807fa7ce56d3911d7e7c2145f
@@@ -46,8 -46,8 +46,8 @@@ void target_music_use(
        entity head;
        FOR_EACH_SPEC(head) if(head.enemy == activator) { msg_entity = head; target_music_sendto(MSG_ONE, 1); }
  }
 -void spawnfunc_target_music()
 -{SELFPARAM();
 +spawnfunc(target_music)
 +{
        self.use = target_music_use;
        self.reset = target_music_reset;
        if(!self.volume)
@@@ -125,8 -125,8 +125,8 @@@ void trigger_music_use(
        self.cnt = !self.cnt;
        self.SendFlags |= 0x80;
  }
 -void spawnfunc_trigger_music()
 -{SELFPARAM();
 +spawnfunc(trigger_music)
 +{
        if(self.model != "")
                _setmodel(self, self.model);
        if(!self.volume)
@@@ -182,9 -182,9 +182,9 @@@ void TargetMusic_Advance(
                if(vol != vol0)
                {
                        if(vol0 < 0)
-                               sound(e, CH_BGM_SINGLE, e.noise, vol, ATTEN_NONE); // restart
+                               _sound(e, CH_BGM_SINGLE, e.noise, vol, ATTEN_NONE); // restart
                        else
-                               sound(e, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
+                               _sound(e, CH_BGM_SINGLE, "", vol, ATTEN_NONE);
                        e.lastvol = vol;
                }
        }
@@@ -223,7 -223,7 +223,7 @@@ void Net_TargetMusic(
                        strunzone(e.noise);
                e.noise = strzone(noi);
                precache_sound(e.noise);
-               sound(e, CH_BGM_SINGLE, e.noise, 0, ATTEN_NONE);
+               _sound(e, CH_BGM_SINGLE, e.noise, 0, ATTEN_NONE);
                if(getsoundtime(e, CH_BGM_SINGLE) < 0)
                {
                        LOG_TRACEF("Cannot initialize sound %s\n", e.noise);
@@@ -310,7 -310,7 +310,7 @@@ void Ent_ReadTriggerMusic(
                if(self.noise != s)
                {
                        precache_sound(self.noise);
-                       sound(self, CH_BGM_SINGLE, self.noise, 0, ATTEN_NONE);
+                       _sound(self, CH_BGM_SINGLE, self.noise, 0, ATTEN_NONE);
                        if(getsoundtime(self, CH_BGM_SINGLE) < 0)
                        {
                                LOG_TRACEF("Cannot initialize sound %s\n", self.noise);
index 42cfe3200565b8b09a3e9d05212bcc1e534241d0,75f733c09eefa44d420a36c894beb88dfa05b791..0b3767ff654c856a13d9e6a515dc13020c5abd4f
@@@ -10,9 -10,9 +10,9 @@@ void target_speaker_use_activator(
        {
                var .string sample = GetVoiceMessageSampleField(substring(self.noise, 1, -1));
                if(GetPlayerSoundSampleField_notFound)
-                       snd = "misc/null.wav";
+                       snd = SND(Null);
                else if(activator.(sample) == "")
-                       snd = "misc/null.wav";
+                       snd = SND(Null);
                else
                {
                        tokenize_console(activator.(sample));
@@@ -36,9 -36,9 +36,9 @@@ void target_speaker_use_on(
        {
                var .string sample = GetVoiceMessageSampleField(substring(self.noise, 1, -1));
                if(GetPlayerSoundSampleField_notFound)
-                       snd = "misc/null.wav";
+                       snd = SND(Null);
                else if(activator.(sample) == "")
-                       snd = "misc/null.wav";
+                       snd = SND(Null);
                else
                {
                        tokenize_console(activator.(sample));
        }
        else
                snd = self.noise;
-       sound(self, CH_TRIGGER_SINGLE, snd, VOL_BASE * self.volume, self.atten);
+       _sound(self, CH_TRIGGER_SINGLE, snd, VOL_BASE * self.volume, self.atten);
        if(self.spawnflags & 3)
                self.use = target_speaker_use_off;
  }
  void target_speaker_use_off()
  {SELFPARAM();
-       sound(self, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_BASE * self.volume, self.atten);
+       sound(self, CH_TRIGGER_SINGLE, SND_Null, VOL_BASE * self.volume, self.atten);
        self.use = target_speaker_use_on;
  }
  void target_speaker_reset()
@@@ -75,8 -75,8 +75,8 @@@
        }
  }
  
 -void spawnfunc_target_speaker()
 -{SELFPARAM();
 +spawnfunc(target_speaker)
 +{
        // TODO: "*" prefix to sound file name
        // TODO: wait and random (just, HOW? random is not a field)
        if(self.noise)
index 7ce15c2e2f05f579423e872554e29ff3189cc1c3,f329c71b0da0d79f6415472d454b1c5f1dcd272d..a6b3eedde651521db1a84c409b00940cec16c6a3
@@@ -80,13 -80,13 +80,13 @@@ void trigger_gravity_touch(
        {
                other.gravity = g;
                if(self.noise != "")
-                       sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+                       _sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
                UpdateCSQCProjectile(self.owner);
        }
  }
  
 -void spawnfunc_trigger_gravity()
 -{SELFPARAM();
 +spawnfunc(trigger_gravity)
 +{
        if(self.gravity == 1)
                return;
  
index af307a29927f4e596fd78425a402b5d0c026a803,49042427e61fa261f5d98f0fc05edf398fdc5cba..5d4f2d0b3a2cf26a15508c630cc47bb19f90cc38
@@@ -19,14 -19,14 +19,14 @@@ void trigger_heal_touch(
                        {
                                other.health = min(other.health + self.health, self.max_health);
                                other.pauserothealth_finished = max(other.pauserothealth_finished, time + autocvar_g_balance_pause_health_rot);
-                               sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+                               _sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
                        }
                }
        }
  }
  
 -void spawnfunc_trigger_heal()
 -{SELFPARAM();
 +spawnfunc(trigger_heal)
 +{
        self.active = ACTIVE_ACTIVE;
  
        EXACTTRIGGER_INIT;
index dfdcd7b3ae491a52658c0848cfd2d5c1bdabb607,cdc181ceb6513a769157756bd26e0e12c22cdbf7..0695811e0f4143cb95567923700fd3719825b771
@@@ -182,7 -182,7 +182,7 @@@ void trigger_push_touch(
                {
                        // flash when activated
                        Send_Effect(EFFECT_JUMPPAD, other.origin, other.velocity, 1);
-                       sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+                       _sound (other, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
                        self.pushltime = time + 0.2;
                }
                if(IS_REAL_CLIENT(other) || IS_BOT_CLIENT(other))
@@@ -363,8 -363,8 +363,8 @@@ void trigger_push_link(
   *            values to target a point on the ceiling.
   *   movedir: if target is not set, this * speed * 10 is the velocity to be reached.
   */
 -void spawnfunc_trigger_push()
 -{SELFPARAM();
 +spawnfunc(trigger_push)
 +{
        SetMovedir ();
  
        EXACTTRIGGER_INIT;
@@@ -406,9 -406,9 +406,9 @@@ void target_push_link(
        self.SendFlags |= 1; // update
  }
  
 -void spawnfunc_target_push() { target_push_link(); }
 -void spawnfunc_info_notnull() { target_push_link(); }
 -void spawnfunc_target_position() { target_push_link(); }
 +spawnfunc(target_push) { target_push_link(); }
 +spawnfunc(info_notnull) { target_push_link(); }
 +spawnfunc(target_position) { target_push_link(); }
  
  #endif
  
index 7ee7773851ec061789c1b1fb01d8543310af2c7e,f792185bc01eff4e608f176be13d8f4004be87b4..365c6f5a908d01a7ea8a3f7f76a51ce2545e0b70
@@@ -132,8 -132,8 +132,8 @@@ wait: prevent triggering again for thi
  If spawned without any key specified in itemkeys, this trigger will display an error and remove itself.
  message2 and noise2 will be resent to the player every 2 seconds while he is in the trigger zone.
  */
 -void spawnfunc_trigger_keylock(void)
 -{SELFPARAM();
 +spawnfunc(trigger_keylock)
 +{
        if(!self.itemkeys) { remove(self); return; }
  
        // set unlocked message
                if(self.sounds == 1)
                        self.noise = "misc/secret.wav";
                else if(self.sounds == 2)
-                       self.noise = "misc/talk.wav";
+                       self.noise = SND(TALK);
                else //if (self.sounds == 3) {
                        self.noise = "misc/trigger1.wav";
        }
  
        // set closed sourd
        if(self.noise2 == "")
-               self.noise2 = "misc/talk.wav";
+               self.noise2 = SND(TALK);
  
        // delay between triggering message2 and trigger2
        if(!self.wait) { self.wait = 5; }
index ca26d214a9a4a72507861ef9c20f95bd88e77dd0,2aa8f5c1ddf1ed8e101cf78466106d6c96c2dc9b..3261520d7a19e951ebdd198c7293facdf38a1de0
@@@ -32,7 -32,7 +32,7 @@@ void multi_trigger(
        }
  
        if (self.noise)
-               sound (self.enemy, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+               _sound (self.enemy, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
  
  // don't trigger again until reset
        self.takedamage = DAMAGE_NO;
@@@ -139,8 -139,8 +139,8 @@@ sound
  4)
  set "message" to text string
  */
 -void spawnfunc_trigger_multiple()
 -{SELFPARAM();
 +spawnfunc(trigger_multiple)
 +{
        self.reset = multi_reset;
        if (self.sounds == 1)
        {
        }
        else if (self.sounds == 2)
        {
-               precache_sound ("misc/talk.wav");
-               self.noise = "misc/talk.wav";
+               self.noise = SND(TALK);
        }
        else if (self.sounds == 3)
        {
@@@ -202,9 -201,9 +201,9 @@@ sound
  4)
  set "message" to text string
  */
 -void spawnfunc_trigger_once()
 -{SELFPARAM();
 -      self.wait = -1;
 -      spawnfunc_trigger_multiple();
 +spawnfunc(trigger_once)
 +{
 +      this.wait = -1;
 +      spawnfunc_trigger_multiple(this);
  }
  #endif
index d4e632c4c18e2ebf41b6852f379e40fbee937563,cd111b258e6851a2d2b5450dd6ed396b7b7d98c8..117e3478324c79a96864a30688a6ddeec925d192
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ EWHEEL,
  /* function   */ t_ewheel,
@@@ -121,7 -121,7 +121,7 @@@ void ewheel_move_idle(
          movelib_beak_simple((autocvar_g_turrets_unit_ewheel_speed_stop));
  }
  
- spawnfunc(turret_ewheel) { if(!turret_initialize(TUR_EWHEEL)) remove(self); }
 -void spawnfunc_turret_ewheel() { SELFPARAM(); if(!turret_initialize(TUR_EWHEEL.m_id)) remove(self); }
++spawnfunc(turret_ewheel) { if(!turret_initialize(TUR_EWHEEL.m_id)) remove(self); }
  
  float t_ewheel(float req)
  {SELFPARAM();
              {
                  turret_do_updates(self);
  
-                 _mis = turret_projectile(W_Sound("lasergun_fire"), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
+                 _mis = turret_projectile(SND(LASERGUN_FIRE), 1, 0, DEATH_TURRET_EWHEEL, PROJECTILE_BLASTER, TRUE, TRUE);
                  _mis.missile_flags = MIF_SPLASH;
  
                  Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
index b819ae9507d47e547f00abd538d5a8079eade54c,e19116067ee037cb4d12aff94ec2c9f982095fe2..3b9330f7e445f2df9791059cd5fc1df06f5c6af5
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ FLAC,
  /* function   */ t_flac,
@@@ -28,7 -28,7 +28,7 @@@ void turret_flac_projectile_think_explo
      remove(self);
  }
  
- spawnfunc(turret_flac) { if(!turret_initialize(TUR_FLAC)) remove(self); }
 -void spawnfunc_turret_flac() { SELFPARAM(); if(!turret_initialize(TUR_FLAC.m_id)) remove(self); }
++spawnfunc(turret_flac) { if(!turret_initialize(TUR_FLAC.m_id)) remove(self); }
  
  float t_flac(float req)
  {SELFPARAM();
@@@ -40,7 -40,7 +40,7 @@@
  
              turret_tag_fire_update();
  
-             proj = turret_projectile(W_Sound("hagar_fire"), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
+             proj = turret_projectile(SND(HAGAR_FIRE), 5, 0, DEATH_TURRET_FLAC, PROJECTILE_HAGAR, TRUE, TRUE);
              Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
              proj.think          = turret_flac_projectile_think_explode;
              proj.nextthink  = time + self.tur_impacttime + (random() * 0.01 - random() * 0.01);
index c1e2f5d4558220a32955efedb6546f2bb4d4563b,5a8df2aad16a20e40e1a0177cf91ca599f26aa26..3b6389a96428a66be641f4012987dd652db9ef1f
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ FUSIONREACTOR,
  /* function   */ t_fusionreactor,
@@@ -40,7 -40,7 +40,7 @@@ bool turret_fusionreactor_firecheck(
      return true;
  }
  
- spawnfunc(turret_fusionreactor) { if(!turret_initialize(TUR_FUSIONREACTOR)) remove(self); }
 -void spawnfunc_turret_fusionreactor() { SELFPARAM(); if(!turret_initialize(TUR_FUSIONREACTOR.m_id)) remove(self); }
++spawnfunc(turret_fusionreactor) { if(!turret_initialize(TUR_FUSIONREACTOR.m_id)) remove(self); }
  
  float t_fusionreactor(float req)
  {SELFPARAM();
index 1b798bbaafce8e764ca05287b946e58c7d7fdfdb,56f5da90a3d70b72d9e407c2923c72f6f84aa792..a253d20ed102ee1aaba5fa06c21333d98373e5f5
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ HELLION,
  /* function   */ t_hellion,
@@@ -76,7 -76,7 +76,7 @@@ void turret_hellion_missile_think(
      UpdateCSQCProjectile(self);
  }
  
- spawnfunc(turret_hellion) { if(!turret_initialize(TUR_HELLION)) remove(self); }
 -void spawnfunc_turret_hellion() { SELFPARAM(); if(!turret_initialize(TUR_HELLION.m_id)) remove(self); }
++spawnfunc(turret_hellion) { if(!turret_initialize(TUR_HELLION.m_id)) remove(self); }
  
  float t_hellion(float req)
  {SELFPARAM();
@@@ -91,7 -91,7 +91,7 @@@
              else
                  self.tur_shotorg = gettaginfo(self.tur_head, gettagindex(self.tur_head, "tag_fire2"));
  
-             missile = turret_projectile(W_Sound("rocket_fire"), 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
+             missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HELLION, PROJECTILE_ROCKET, FALSE, FALSE);
              te_explosion (missile.origin);
              missile.think             = turret_hellion_missile_think;
              missile.nextthink = time;
index 4dcbe9592dff0820d7389f4418bb59df96da32bd,106c982ae8cfa8d8b5d2832f9891740cf086241f..25235734badd158eeb3ff3f46a5e43d9b93cff94
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ HK,
  /* function   */ t_hk,
@@@ -273,7 -273,7 +273,7 @@@ float turret_hk_addtarget(entity e_targ
      return 0;
  }
  
- spawnfunc(turret_hk) { if(!turret_initialize(TUR_HK)) remove(self); }
 -void spawnfunc_turret_hk() { SELFPARAM(); if(!turret_initialize(TUR_HK.m_id)) remove(self); }
++spawnfunc(turret_hk) { if(!turret_initialize(TUR_HK.m_id)) remove(self); }
  
  float t_hk(float req)
  {SELFPARAM();
          {
              entity missile;
  
-             missile = turret_projectile(W_Sound("rocket_fire"), 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
+             missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_HK, PROJECTILE_ROCKET, FALSE, FALSE);
              te_explosion (missile.origin);
  
              missile.think                     = turret_hk_missile_think;
index bde4f560b4b3aa45aa0a04b9a1475d109ce8c0a3,35f1921edae621cca8681943bb5d8c80fdd73651..eeb889022b1610fb32c18d85bdea1a2a27dff18f
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ MACHINEGUN,
  /* function   */ t_machinegun,
@@@ -11,7 -11,7 +11,7 @@@
  );
  #else
  #ifdef SVQC
- spawnfunc(turret_machinegun) { if(!turret_initialize(TUR_MACHINEGUN)) remove(self); }
 -void spawnfunc_turret_machinegun() { SELFPARAM(); if(!turret_initialize(TUR_MACHINEGUN.m_id)) remove(self); }
++spawnfunc(turret_machinegun) { if(!turret_initialize(TUR_MACHINEGUN.m_id)) remove(self); }
  
  void W_MachineGun_MuzzleFlash(void);
  
@@@ -48,7 -48,6 +48,6 @@@ float t_machinegun(float req
          }
          case TR_PRECACHE:
          {
-             precache_sound (W_Sound("uzi_fire"));
              return true;
          }
      }
index 9ae66630756b32c99872a702bb610847ccbddb72,21e0a435d7a951619029d085a63d12fc113196a7..7e130c6e18907d57182f8427525f332eb9b54c82
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ MLRS,
  /* function   */ t_mlrs,
@@@ -11,7 -11,7 +11,7 @@@
  );
  #else
  #ifdef SVQC
- spawnfunc(turret_mlrs) { if(!turret_initialize(TUR_MLRS)) remove(self); }
 -void spawnfunc_turret_mlrs() { SELFPARAM(); if(!turret_initialize(TUR_MLRS.m_id)) remove(self); }
++spawnfunc(turret_mlrs) { if(!turret_initialize(TUR_MLRS.m_id)) remove(self); }
  
  float t_mlrs(float req)
  {SELFPARAM();
@@@ -22,7 -22,7 +22,7 @@@
              entity missile;
  
              turret_tag_fire_update();
-             missile = turret_projectile(W_Sound("rocket_fire"), 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
+             missile = turret_projectile(SND(ROCKET_FIRE), 6, 10, DEATH_TURRET_MLRS, PROJECTILE_ROCKET, TRUE, TRUE);
              missile.nextthink = time + max(self.tur_impacttime,(self.shot_radius * 2) / self.shot_speed);
              missile.missile_flags = MIF_SPLASH;
              te_explosion (missile.origin);
index ca947623e106afaf76421c8112feb109ac5db04c,04e226448405b58acfa9786be112c38918887616..6eec37ab4d6532abaaa5e20d9b49480e18e11f25
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ PHASER,
  /* function   */ t_phaser,
@@@ -26,7 -26,7 +26,7 @@@ void beam_think(
          self.owner.attack_finished_single = time + self.owner.shot_refire;
          self.owner.fireflag = 2;
          self.owner.tur_head.frame = 10;
-         sound (self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
+         sound (self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
          remove(self);
          return;
      }
@@@ -36,7 -36,7 +36,7 @@@
      if (time - self.shot_spread > 0)
      {
          self.shot_spread = time + 2;
-         sound (self, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
+         sound (self, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
      }
  
  
@@@ -57,7 -57,7 +57,7 @@@
  
  }
  
- spawnfunc(turret_phaser) { if(!turret_initialize(TUR_PHASER)) remove(self); }
 -void spawnfunc_turret_phaser() { SELFPARAM(); if(!turret_initialize(TUR_PHASER.m_id)) remove(self); }
++spawnfunc(turret_phaser) { if(!turret_initialize(TUR_PHASER.m_id)) remove(self); }
  
  float t_phaser(float req)
  {SELFPARAM();
@@@ -83,7 -83,7 +83,7 @@@
              beam.enemy = self.enemy;
              beam.bot_dodge = true;
              beam.bot_dodgerating = beam.shot_dmg;
-             sound (beam, CH_SHOTS_SINGLE, "turrets/phaser.wav", VOL_BASE, ATTEN_NORM);
+             sound (beam, CH_SHOTS_SINGLE, SND_TUR_PHASER, VOL_BASE, ATTEN_NORM);
              self.fireflag = 1;
  
              beam.attack_finished_single = self.attack_finished_single;
@@@ -91,7 -91,7 +91,7 @@@
  
              setattachment(beam,self.tur_head,"tag_fire");
  
-             soundat (self, trace_endpos, CH_SHOTS, W_Sound("neximpact"), VOL_BASE, ATTEN_NORM);
+             soundat (self, trace_endpos, CH_SHOTS, SND(NEXIMPACT), VOL_BASE, ATTEN_NORM);
  
              if (self.tur_head.frame == 0)
                  self.tur_head.frame = 1;
          }
          case TR_PRECACHE:
          {
-             precache_sound ("turrets/phaser.wav");
              return true;
          }
      }
index 36966a1ae2f68e6741d39540e03ff6c63ce4cf1b,baafa51c66b5c1a596f68c9d0337121a75a1d073..59c0f850a76f5663cc81de0ffa53416d8da0400f
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ PLASMA,
  /* function   */ t_plasma,
@@@ -11,7 -11,7 +11,7 @@@
  );
  #else
  #ifdef SVQC
- spawnfunc(turret_plasma) { if(!turret_initialize(TUR_PLASMA)) remove(self); }
 -void spawnfunc_turret_plasma() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA.m_id)) remove(self); }
++spawnfunc(turret_plasma) { if(!turret_initialize(TUR_PLASMA.m_id)) remove(self); }
  
  float t_plasma(float req)
  {SELFPARAM();
                  Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
  
                  // teamcolor / hit beam effect
-                 vector v;
-                 string s;
-                 v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-                 s = strcat("TE_TEI_G3", ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
-                 WarpZone_TrailParticles(world, _particleeffectnum(s), self.tur_shotorg, v);
+                 vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+                 WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
                  if (self.tur_head.frame == 0)
                      self.tur_head.frame = 1;
              }
              else
              {
-                 entity missile = turret_projectile(W_Sound("hagar_fire"), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
+                 entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
                  missile.missile_flags = MIF_SPLASH;
  
                  Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
index 6469c0591d3d1a16d1fdb769f2479e86b82b3252,bf3362ab897593149faff730c372e3b6653fff9f..edcf7ed21fd4c75ff6bda5c676617b4e56d04fd7
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ PLASMA_DUAL,
  /* function   */ t_plasma_dual,
@@@ -11,7 -11,7 +11,7 @@@
  );
  #else
  #ifdef SVQC
- spawnfunc(turret_plasma_dual) { if(!turret_initialize(TUR_PLASMA_DUAL)) remove(self); }
 -void spawnfunc_turret_plasma_dual() { SELFPARAM(); if(!turret_initialize(TUR_PLASMA_DUAL.m_id)) remove(self); }
++spawnfunc(turret_plasma_dual) { if(!turret_initialize(TUR_PLASMA_DUAL.m_id)) remove(self); }
  
  float t_plasma_dual(float req)
  {SELFPARAM();
                  Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
  
                  // teamcolor / hit beam effect
-                 vector v;
-                 string s;
-                 v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-                 s = strcat(EFFECT_VAPORIZER_NEUTRAL.eent_eff_name, ((self.team) ? Static_Team_ColorName_Upper(self.team) : ""));
-                 WarpZone_TrailParticles(world, _particleeffectnum(s), self.tur_shotorg, v);
+                 vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+                 WarpZone_TrailParticles(world, particleeffectnum(EFFECT_VAPORIZER(self.team)), self.tur_shotorg, v);
                  self.tur_head.frame += 1;
              }
              else
              {
-                 entity missile = turret_projectile(W_Sound("hagar_fire"), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
+                 entity missile = turret_projectile(SND(HAGAR_FIRE), 1, 0, DEATH_TURRET_PLASMA, PROJECTILE_ELECTRO_BEAM, TRUE, TRUE);
                  missile.missile_flags = MIF_SPLASH;
                  Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
                  self.tur_head.frame += 1;
index 76f8083a9a82312bbe0b1e833daa4c949b04a1a7,d3c894b96edfe548bbbd2f1b9c9ac8c4d8641267..ebcc4e997767cd3870cb2f6e007d7d40c0db02fb
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ TESLA,
  /* function   */ t_tesla,
@@@ -89,7 -89,7 +89,7 @@@ float turret_tesla_firecheck(
      return 0;
  }
  
- spawnfunc(turret_tesla) { if(!turret_initialize(TUR_TESLA)) remove(self); }
 -void spawnfunc_turret_tesla() { SELFPARAM(); if(!turret_initialize(TUR_TESLA.m_id)) remove(self); }
++spawnfunc(turret_tesla) { if(!turret_initialize(TUR_TESLA.m_id)) remove(self); }
  
  float t_tesla(float req)
  {SELFPARAM();
index ceacde8c2a62d7d021f9413eea59d1e107cdfd1b,792e7a338d0b080a16d4dcb4a1d0a7f69d936f4f..a2927cfbf29765be6ff5122c8525f39a34db0cca
@@@ -1,4 -1,4 +1,4 @@@
- #ifdef REGISTER_TURRET
+ #ifndef IMPLEMENTATION
  REGISTER_TURRET(
  /* TUR_##id   */ WALKER,
  /* function   */ t_walker,
@@@ -221,7 -221,7 +221,7 @@@ void walker_fire_rocket(vector org
      rocket = spawn ();
      setorigin(rocket, org);
  
-     sound (self, CH_WEAPON_A, W_Sound("hagar_fire"), VOL_BASE, ATTEN_NORM);
+     sound (self, CH_WEAPON_A, SND_HAGAR_FIRE, VOL_BASE, ATTEN_NORM);
      setsize (rocket, '-3 -3 -3', '3 3 3'); // give it some size so it can be shot
  
      rocket.classname            = "walker_rocket";
@@@ -334,7 -334,7 +334,7 @@@ void walker_move_path(
  #endif
  }
  
- spawnfunc(turret_walker) { if(!turret_initialize(TUR_WALKER)) remove(self); }
 -void spawnfunc_turret_walker() { SELFPARAM(); if(!turret_initialize(TUR_WALKER.m_id)) remove(self); }
++spawnfunc(turret_walker) { if(!turret_initialize(TUR_WALKER.m_id)) remove(self); }
  
  float t_walker(float req)
  {SELFPARAM();
      {
          case TR_ATTACK:
          {
-             sound (self, CH_WEAPON_A, W_Sound("uzi_fire"), VOL_BASE, ATTEN_NORM);
+             sound (self, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
              fireBullet (self.tur_shotorg, self.tur_shotdir_updated, self.shot_spread, 0, self.shot_dmg, self.shot_force, DEATH_TURRET_WALK_GUN, 0);
              Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, self.tur_shotorg, self.tur_shotdir_updated * 1000, 1);
  
          }
          case TR_PRECACHE:
          {
-             precache_sound (W_Sound("rocket_impact"));
              return true;
          }
      }
  #endif // SVQC
  #ifdef CSQC
  
- #include "../../../server/movelib.qh"
+ #include "../../../client/movelib.qh"
  
  void walker_draw()
  {SELFPARAM();
index fb06eabf517cde511955f8b9df82368e738fa1ce,6f8a2bf8f5e7bf56c357aef6b805ba5c043fd523..d36392e207734c062c41887389909d89f2efaf33
@@@ -104,7 -104,7 +104,7 @@@ float bumble_raygun_send(entity to, in
  void bumblebee_fire_cannon(entity _gun, string _tagname, entity _owner)
  {
        vector v = gettaginfo(_gun, gettagindex(_gun, _tagname));
-       vehicles_projectile(EFFECT_BIGPLASMA_MUZZLEFLASH.eent_eff_name, W_Sound("flacexp3"),
+       vehicles_projectile(EFFECT_BIGPLASMA_MUZZLEFLASH.eent_eff_name, SND(VEH_BUMBLEBEE_FIRE),
                                                v, normalize(v_forward + randomvec() * autocvar_g_vehicle_bumblebee_cannon_spread) * autocvar_g_vehicle_bumblebee_cannon_speed,
                                                autocvar_g_vehicle_bumblebee_cannon_damage, autocvar_g_vehicle_bumblebee_cannon_radius, autocvar_g_vehicle_bumblebee_cannon_force,  0,
                                                DEATH_VH_BUMB_GUN, PROJECTILE_BUMBLE_GUN, 0, true, true, _owner);
@@@ -716,7 -716,7 +716,7 @@@ void bumblebee_blowup(
                                 autocvar_g_vehicle_bumblebee_blowup_forceintensity,
                                 DEATH_VH_BUMB_DEATH, world);
  
-       sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
        Send_Effect(EFFECT_EXPLOSION_BIG, (self.origin + '0 0 100') + (randomvec() * 80), '0 0 0', 1);
  
        if(self.owner.deadflag == DEAD_DYING)
@@@ -732,7 -732,7 +732,7 @@@ void bumblebee_diethink(
  
        if(random() < 0.1)
        {
-               sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+               sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
                Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
        }
  
@@@ -768,8 -768,8 +768,8 @@@ float bumble_raygun_send(entity to, flo
        return true;
  }
  
 -void spawnfunc_vehicle_bumblebee()
 -{SELFPARAM();
 +spawnfunc(vehicle_bumblebee)
 +{
        if(!autocvar_g_vehicle_bumblebee) { remove(self); return; }
        if(!vehicle_initialize(VEH_BUMBLEBEE, false)) { remove(self); return; }
  }
index 1422ab83af47141da0c9741c41d0ac7e1a64de18,a1dc7ced65c78c9a69637ad6702bc66dd8dc9456..4d62249f47abcde8e9f63e5581a4cd4ffb47c8c3
@@@ -174,7 -174,7 +174,7 @@@ void racer_fire_cannon(string tagname
        entity bolt;
  
        v = gettaginfo(self, gettagindex(self, tagname));
-       bolt = vehicles_projectile(EFFECT_RACER_MUZZLEFLASH.eent_eff_name, W_Sound("lasergun_fire"),
+       bolt = vehicles_projectile(EFFECT_RACER_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
                                                   v, normalize(v_forward + randomvec() * autocvar_g_vehicle_racer_cannon_spread) * autocvar_g_vehicle_racer_cannon_speed,
                                                   autocvar_g_vehicle_racer_cannon_damage, autocvar_g_vehicle_racer_cannon_radius, autocvar_g_vehicle_racer_cannon_force,  0,
                                                   DEATH_VH_WAKI_GUN, PROJECTILE_WAKICANNON, 0, true, true, self.owner);
@@@ -292,7 -292,7 +292,7 @@@ void racer_rocket_tracker(
  void racer_fire_rocket(string tagname, entity trg)
  {SELFPARAM();
        vector v = gettaginfo(self, gettagindex(self, tagname));
-       entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, W_Sound("rocket_fire"),
+       entity rocket = vehicles_projectile(EFFECT_RACER_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
                                                   v, v_forward * autocvar_g_vehicle_racer_rocket_speed,
                                                   autocvar_g_vehicle_racer_rocket_damage, autocvar_g_vehicle_racer_rocket_radius, autocvar_g_vehicle_racer_rocket_force, 3,
                                                   DEATH_VH_WAKI_ROCKET, PROJECTILE_WAKIROCKET, 20, false, false, self.owner);
@@@ -385,7 -385,7 +385,7 @@@ float racer_frame(
                {
                        self.sounds = 1;
                        self.sound_nexttime = time + 10.922667; //soundlength("vehicles/racer_move.wav");
-                       sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_move.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                       sound (self, CH_TRIGGER_SINGLE, SND_VEH_RACER_MOVE, VOL_VEHICLEENGINE, ATTEN_NORM);
                }
  #endif
        }
                {
                        self.sounds = 0;
                        self.sound_nexttime = time + 11.888604; //soundlength("vehicles/racer_idle.wav");
-                       sound (self, CH_TRIGGER_SINGLE, "vehicles/racer_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                       sound (self, CH_TRIGGER_SINGLE, SND_VEH_RACER_IDLE, VOL_VEHICLEENGINE, ATTEN_NORM);
                }
        }
  #endif
                if(racer.strength_finished < time)
                {
                        racer.strength_finished = time + 10.922667; //soundlength("vehicles/racer_boost.wav");
-                       sound (racer.tur_head, CH_TRIGGER_SINGLE, "vehicles/racer_boost.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                       sound (racer.tur_head, CH_TRIGGER_SINGLE, SND_VEH_RACER_BOOST, VOL_VEHICLEENGINE, ATTEN_NORM);
                }
  #endif
        }
        else
        {
                racer.strength_finished = 0;
-               sound (racer.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+               sound (racer.tur_head, CH_TRIGGER_SINGLE, SND_Null, VOL_VEHICLEENGINE, ATTEN_NORM);
        }
  
        if(cont == CONTENT_WATER || cont == CONTENT_LAVA || cont == CONTENT_SLIME)
@@@ -589,7 -589,7 +589,7 @@@ void racer_exit(float eject
        self.think        = racer_think;
        self.nextthink  = time;
        self.movetype   = MOVETYPE_BOUNCE;
-       sound (self.tur_head, CH_TRIGGER_SINGLE, "misc/null.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+       sound (self.tur_head, CH_TRIGGER_SINGLE, SND_Null, VOL_VEHICLEENGINE, ATTEN_NORM);
  
        if(!self.owner)
                return;
@@@ -667,8 -667,8 +667,8 @@@ void racer_deadtouch(
                racer_blowup();
  }
  
 -void spawnfunc_vehicle_racer()
 -{SELFPARAM();
 +spawnfunc(vehicle_racer)
 +{
        if(!autocvar_g_vehicle_racer) { remove(self); return; }
        if(!vehicle_initialize(VEH_RACER, false)) { remove(self); return; }
  }
@@@ -856,14 -856,6 +856,6 @@@ bool v_racer(int req
  
                case VR_PRECACHE:
                {
-               #ifdef SVQC
-                       precache_sound (W_Sound("lasergun_fire"));
-                       precache_sound (W_Sound("rocket_fire"));
-                       precache_sound ("vehicles/racer_idle.wav");
-                       precache_sound ("vehicles/racer_move.wav");
-                       precache_sound ("vehicles/racer_boost.wav");
-               #endif
                        return true;
                }
        }
index 0108a3e707560d502d0bc54938263032daeca9c8,742ef7b9b2a990eac309fe7ec1922c3ecc5b6047..a1c058fb00ef3015c1402959da2afc723a636427
@@@ -195,7 -195,7 +195,7 @@@ void raptor_bombdrop(
  
  void raptor_fire_cannon(entity gun, string tagname)
  {SELFPARAM();
-       vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, W_Sound("lasergun_fire"),
+       vehicles_projectile(EFFECT_RAPTOR_MUZZLEFLASH.eent_eff_name, SND(LASERGUN_FIRE),
                                                   gettaginfo(gun, gettagindex(gun, tagname)), normalize(v_forward + randomvec() * autocvar_g_vehicle_raptor_cannon_spread) * autocvar_g_vehicle_raptor_cannon_speed,
                                                   autocvar_g_vehicle_raptor_cannon_damage, autocvar_g_vehicle_raptor_cannon_radius, autocvar_g_vehicle_raptor_cannon_force,  0,
                                                   DEATH_VH_RAPT_CANNON, PROJECTILE_RAPTORCANNON, 0, true, true, self.owner);
@@@ -334,15 -334,15 +334,15 @@@ float raptor_frame(
        if(self.sound_nexttime < time)
        {
                self.sound_nexttime = time + 7.955812;
-               //sound (self.tur_head, CH_TRIGGER_SINGLE, "vehicles/raptor_fly.wav", 1 - ftmp,   ATTEN_NORM );
-               sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", 1, ATTEN_NORM);
+               //sound (self.tur_head, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_FLY, 1 - ftmp,   ATTEN_NORM );
+               sound (self, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_SPEED, 1, ATTEN_NORM);
                self.wait = ftmp;
        }
        /*
        else if(fabs(ftmp - self.wait) > 0.2)
        {
-               sound (self.tur_head, CH_TRIGGER_SINGLE, "", 1 - ftmp,   ATTEN_NORM );
-               sound (self, CH_TRIGGER_SINGLE, "", ftmp, ATTEN_NORM);
+               sound (self.tur_head, CH_TRIGGER_SINGLE, SND_Null, 1 - ftmp,   ATTEN_NORM );
+               sound (self, CH_TRIGGER_SINGLE, SND_Null, ftmp, ATTEN_NORM);
                self.wait = ftmp;
        }
        */
                }
  
                if(_incomming)
-                       sound(self, CH_PAIN_SINGLE, "vehicles/missile_alarm.wav", VOL_BASE, ATTEN_NONE);
+                       sound(self, CH_PAIN_SINGLE, SND_VEH_MISSILE_ALARM, VOL_BASE, ATTEN_NONE);
  
                self.bomb1.cnt = time + 1;
        }
@@@ -661,7 -661,7 +661,7 @@@ float raptor_takeoff(
        if(self.sound_nexttime < time)
        {
                self.sound_nexttime = time + 7.955812; //soundlength("vehicles/raptor_fly.wav");
-               sound (self, CH_TRIGGER_SINGLE, "vehicles/raptor_speed.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+               sound (self, CH_TRIGGER_SINGLE, SND_VEH_RAPTOR_SPEED, VOL_VEHICLEENGINE, ATTEN_NORM);
        }
  
        // Takeoff sequense
@@@ -727,7 -727,7 +727,7 @@@ void raptor_diethink(
  
        if(random() < 0.05)
        {
-               sound (self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+               sound (self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
                Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
        }
        self.nextthink = time;
@@@ -789,8 -789,8 +789,8 @@@ float raptor_impulse(float _imp
        return false;
  }
  
 -void spawnfunc_vehicle_raptor()
 -{SELFPARAM();
 +spawnfunc(vehicle_raptor)
 +{
        if(!autocvar_g_vehicle_raptor) { remove(self); return; }
        if(!vehicle_initialize(VEH_RAPTOR, false)) { remove(self); return; }
  }
@@@ -969,10 -969,6 +969,6 @@@ float v_raptor(float req
                }
                case VR_PRECACHE:
                {
-                       precache_sound ("vehicles/raptor_fly.wav");
-                       precache_sound ("vehicles/raptor_speed.wav");
-                       precache_sound ("vehicles/missile_alarm.wav");
                        return true;
                }
        }
index d2d99e1e6707f3543afe95915f9d68c7244ffb31,f8efe528dd28614cfa301063a8663e1f51d94d8a..6e1fffe7a70c3cecd6f49175f8bac3e9d16744fe
@@@ -269,7 -269,7 +269,7 @@@ void spiderbot_rocket_do(
        switch(self.vehicle_weapon2mode)
        {
                case SBRM_VOLLY:
-                       rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, W_Sound("rocket_fire"),
+                       rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
                                                                   v, normalize(randomvec() * autocvar_g_vehicle_spiderbot_rocket_spread + v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                                                   autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                                                   DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, true, self.owner);
                                self.wait = -10;
                        break;
                case SBRM_GUIDE:
-                       rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, W_Sound("rocket_fire"),
+                       rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
                                                                   v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                                                   autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                                                   DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, false, self.owner);
  
                break;
                case SBRM_ARTILLERY:
-                       rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, W_Sound("rocket_fire"),
+                       rocket = vehicles_projectile(EFFECT_SPIDERBOT_ROCKETLAUNCH.eent_eff_name, SND(ROCKET_FIRE),
                                                                   v, normalize(v_forward) * autocvar_g_vehicle_spiderbot_rocket_speed,
                                                                   autocvar_g_vehicle_spiderbot_rocket_damage, autocvar_g_vehicle_spiderbot_rocket_radius, autocvar_g_vehicle_spiderbot_rocket_force, 1,
                                                                   DEATH_VH_SPID_ROCKET, PROJECTILE_SPIDERROCKET, autocvar_g_vehicle_spiderbot_rocket_health, false, true, self.owner);
@@@ -407,7 -407,7 +407,7 @@@ float spiderbot_frame(
                if(spider.flags & FL_ONGROUND)
                if(spider.frame == 4 && self.tur_head.wait != 0)
                {
-                       sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_land.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                       sound (self, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_LAND, VOL_VEHICLEENGINE, ATTEN_NORM);
                        spider.frame = 5;
                }
  
  
                if((spider.flags & FL_ONGROUND) && player.BUTTON_JUMP && !spider.BUTTON_JUMP && self.tur_head.wait < time)
                {
-                       sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_jump.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                       sound (self, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_JUMP, VOL_VEHICLEENGINE, ATTEN_NORM);
                        //dprint("spiderbot_jump:", ftos(soundlength("vehicles/spiderbot_jump.wav")), "\n");
                        self.delay = 0;
  
                                                self.delay = 3;
                                                self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_idle.wav");
                                                //dprint("spiderbot_idle:", ftos(soundlength("vehicles/spiderbot_idle.wav")), "\n");
-                                               sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_idle.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                                               sound (self, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_IDLE, VOL_VEHICLEENGINE, ATTEN_NORM);
                                        }
                                        movelib_beak_simple(autocvar_g_vehicle_spiderbot_speed_stop);
                                        spider.frame = 5;
                                        {
                                                self.delay = 1;
                                                self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_walk.wav");
-                                               sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_walk.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                                               sound (self, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_WALK, VOL_VEHICLEENGINE, ATTEN_NORM);
                                                //dprint("spiderbot_walk:", ftos(soundlength("vehicles/spiderbot_walk.wav")), "\n");
                                        }
                                }
                                        {
                                                self.delay = 2;
                                                self.sound_nexttime = time + 6.486500; //soundlength("vehicles/spiderbot_strafe.wav");
-                                               sound (self, CH_TRIGGER_SINGLE, "vehicles/spiderbot_strafe.wav", VOL_VEHICLEENGINE, ATTEN_NORM);
+                                               sound (self, CH_TRIGGER_SINGLE, SND_VEH_SPIDERBOT_STRAFE, VOL_VEHICLEENGINE, ATTEN_NORM);
                                                //dprint("spiderbot_strafe:", ftos(soundlength("vehicles/spiderbot_strafe.wav")), "\n");
                                        }
                                }
                        fireBullet(v, v_forward, autocvar_g_vehicle_spiderbot_minigun_spread, autocvar_g_vehicle_spiderbot_minigun_solidpenetration,
                                  autocvar_g_vehicle_spiderbot_minigun_damage, autocvar_g_vehicle_spiderbot_minigun_force, DEATH_VH_SPID_MINIGUN, 0);
  
-                       sound (gun, CH_WEAPON_A, W_Sound("uzi_fire"), VOL_BASE, ATTEN_NORM);
+                       sound (gun, CH_WEAPON_A, SND_UZI_FIRE, VOL_BASE, ATTEN_NORM);
                        //trailparticles(self, _particleeffectnum("spiderbot_minigun_trail"), v, trace_endpos);
                        pointparticles(particleeffectnum(EFFECT_SPIDERBOT_MINIGUN_MUZZLEFLASH), v, v_forward * 2500, 1);
  
@@@ -678,7 -678,7 +678,7 @@@ void spiderbot_headfade(
        {
                if(self.alpha > 0.1)
                {
-                       sound (self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+                       sound (self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
                        Send_Effect(EFFECT_EXPLOSION_BIG, self.origin + '0 0 100', '0 0 0', 1);
                }
                remove(self);
@@@ -691,7 -691,7 +691,7 @@@ void spiderbot_blowup(
        {
                if(random() < 0.1)
                {
-                       sound (self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+                       sound (self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
                        Send_Effect(EFFECT_EXPLOSION_SMALL, randomvec() * 80 + (self.origin + '0 0 100'), '0 0 0', 1);
                }
                self.nextthink = time + 0.1;
@@@ -811,8 -811,8 +811,8 @@@ bool spiderbot_impulse(int _imp
        return false;
  }
  
 -void spawnfunc_vehicle_spiderbot()
 -{SELFPARAM();
 +spawnfunc(vehicle_spiderbot)
 +{
        if(!autocvar_g_vehicle_spiderbot) { remove(self); return; }
        if(!vehicle_initialize(VEH_SPIDERBOT, false)) { remove(self); return; }
  }
@@@ -925,15 -925,6 +925,6 @@@ float v_spiderbot(float req
                }
                case VR_PRECACHE:
                {
-                       precache_sound (W_Sound("uzi_fire") );
-                       precache_sound (W_Sound("rocket_impact"));
-                       precache_sound ("vehicles/spiderbot_die.wav");
-                       precache_sound ("vehicles/spiderbot_idle.wav");
-                       precache_sound ("vehicles/spiderbot_jump.wav");
-                       precache_sound ("vehicles/spiderbot_strafe.wav");
-                       precache_sound ("vehicles/spiderbot_walk.wav");
-                       precache_sound ("vehicles/spiderbot_land.wav");
                        return true;
                }
        }
index cf117c823f2fb25468ee2bac11c9191109b9558a,400c950c8cf904b76534d599991e5aa7e5761a4c..6e1e2c7cb6ebdec188eab9e383154d5bbb825822
@@@ -126,7 -126,7 +126,7 @@@ vector Draw_ArcBeam_callback_last_botto
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_arc(void) { weapon_defaultspawnfunc(WEP_ARC.m_id); }
 +spawnfunc(weapon_arc) { weapon_defaultspawnfunc(WEP_ARC.m_id); }
  
  float W_Arc_Beam_Send(entity to, int sf)
  {SELFPARAM();
@@@ -267,7 -267,7 +267,7 @@@ void W_Arc_Beam_Think(void
                        {
                                Send_Effect_("arc_overheat",
                                        self.beam_start, self.beam_wantdir, 1 );
-                               sound(self, CH_WEAPON_A, W_Sound("arc_stop"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM);
                        }
                }
  
@@@ -579,7 -579,7 +579,7 @@@ void W_Arc_Beam(float burst
  
        // only play fire sound if 1 sec has passed since player let go the fire button
        if(time - self.beam_prev > 1)
-               sound(self, CH_WEAPON_A, W_Sound("arc_fire"), VOL_BASE, ATTN_NORM);
+               sound(self, CH_WEAPON_A, SND_ARC_FIRE, VOL_BASE, ATTN_NORM);
  
        entity beam = self.arc_beam = spawn();
        beam.classname = "W_Arc_Beam";
@@@ -611,7 -611,7 +611,7 @@@ void Arc_Smoke(
                        if ( !self.arc_smoke_sound )
                        {
                                self.arc_smoke_sound = 1;
-                               sound(self, CH_SHOTS_SINGLE, W_Sound("arc_loop_overheat"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS_SINGLE, SND_ARC_LOOP_OVERHEAT, VOL_BASE, ATTN_NORM);
                        }
                }
        }
                !( self.BUTTON_ATCK || self.BUTTON_ATCK2 ) ) || self.switchweapon != WEP_ARC.m_id )
        {
                self.arc_smoke_sound = 0;
-               sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
+               sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
        }
  }
  
@@@ -695,7 -695,7 +695,7 @@@ bool W_Arc(int req
  
                        if(self.arc_BUTTON_ATCK_prev != 0)
                        {
-                               sound(self, CH_WEAPON_A, W_Sound("arc_stop"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_WEAPON_A, SND_ARC_STOP, VOL_BASE, ATTN_NORM);
                                weapon_thinkf(WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
                                ATTACK_FINISHED(self) = time + WEP_CVAR(arc, beam_refire) * W_WeaponRateFactor();
                        }
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("arc_fire"));
-                       precache_sound(W_Sound("arc_loop"));
-                       precache_sound(W_Sound("arc_stop"));
-                       precache_sound(W_Sound("arc_loop_overheat"));
                        if(!arc_shotorigin[0])
                        {
                                arc_shotorigin[0] = shotorg_adjust_values(CL_Weapon_GetShotOrg(WEP_ARC.m_id), false, false, 1);
@@@ -1158,7 -1154,7 +1154,7 @@@ void Draw_ArcBeam(void
  void Remove_ArcBeam(void)
  {SELFPARAM();
        remove(self.beam_muzzleentity);
-       sound(self, CH_SHOTS_SINGLE, "misc/null.wav", VOL_BASE, ATTEN_NORM);
+       sound(self, CH_SHOTS_SINGLE, SND_Null, VOL_BASE, ATTEN_NORM);
  }
  
  void Ent_ReadArcBeam(float isnew)
                self.draw = Draw_ArcBeam;
                self.entremove = Remove_ArcBeam;
                self.move_time = time;
-               loopsound(self, CH_SHOTS_SINGLE, W_Sound("arc_loop"), VOL_BASE, ATTEN_NORM);
+               loopsound(self, CH_SHOTS_SINGLE, SND(ARC_LOOP), VOL_BASE, ATTEN_NORM);
  
                flash = spawn();
                flash.owner = self;
@@@ -1524,7 -1520,6 +1520,6 @@@ bool W_Arc(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("arc_loop"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index e91f424c16a684850c2bc03eb35a5513662401bb,6b6d207bfada68b1d3a526c601b18f66c7290e45..10e55990a5594f645aeec8859e357905cf8d6135
@@@ -48,8 -48,8 +48,8 @@@ BLASTER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_blaster(void) { weapon_defaultspawnfunc(WEP_BLASTER.m_id); }
 -void spawnfunc_weapon_laser(void) { spawnfunc_weapon_blaster(); }
 +spawnfunc(weapon_blaster) { weapon_defaultspawnfunc(WEP_BLASTER.m_id); }
 +spawnfunc(weapon_laser) { spawnfunc_weapon_blaster(this); }
  
  void W_Blaster_Touch(void)
  {SELFPARAM();
@@@ -95,7 -95,7 +95,7 @@@ void W_Blaster_Attack
  {SELFPARAM();
        vector s_forward = v_forward * cos(atk_shotangle * DEG2RAD) + v_up * sin(atk_shotangle * DEG2RAD);
  
-       W_SetupShot_Dir(self, s_forward, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_B, atk_damage);
+       W_SetupShot_Dir(self, s_forward, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_B, atk_damage);
        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
        entity missile = spawn();
@@@ -223,7 -223,6 +223,6 @@@ bool W_Blaster(int request
  
                case WR_INIT:
                {
-                       precache_sound(W_Sound("lasergun_fire"));
                        BLASTER_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
@@@ -269,13 -268,12 +268,12 @@@ bool W_Blaster(int request
                        vector org2;
                        org2 = w_org + w_backoff * 6;
                        pointparticles(particleeffectnum(EFFECT_BLASTER_IMPACT), org2, w_backoff * 1000, 1);
-                       if(!w_issilent) { sound(self, CH_SHOTS, W_Sound("laserimpact"), VOL_BASE, ATTN_NORM); }
+                       if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); }
                        return true;
                }
  
                case WR_INIT:
                {
-                       precache_sound(W_Sound("laserimpact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 3801b0b53c9cd57073a9704873083bf29479913d,43771079e2b50814d896bb11ec9b6cb4980f12ce..bf6c0795f5985b9f1ae274bf94f76019929e4fd2
@@@ -64,7 -64,7 +64,7 @@@ CRYLINK_SETTINGS(WEP_ADD_CVAR, WEP_ADD_
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_crylink(void) { weapon_defaultspawnfunc(WEP_CRYLINK.m_id); }
 +spawnfunc(weapon_crylink) { weapon_defaultspawnfunc(WEP_CRYLINK.m_id); }
  
  void W_Crylink_CheckLinks(entity e)
  {
@@@ -354,7 -354,7 +354,7 @@@ void W_Crylink_Attack(void
        if(WEP_CVAR_PRI(crylink, joinexplode))
                maxdmg += WEP_CVAR_PRI(crylink, joinexplode_damage);
  
-       W_SetupShot(self, false, 2, W_Sound("crylink_fire"), CH_WEAPON_A, maxdmg);
+       W_SetupShot(self, false, 2, SND(CRYLINK_FIRE), CH_WEAPON_A, maxdmg);
        forward = v_forward;
        right = v_right;
        up = v_up;
@@@ -463,7 -463,7 +463,7 @@@ void W_Crylink_Attack2(void
        if(WEP_CVAR_SEC(crylink, joinexplode))
                maxdmg += WEP_CVAR_SEC(crylink, joinexplode_damage);
  
-       W_SetupShot(self, false, 2, W_Sound("crylink_fire2"), CH_WEAPON_A, maxdmg);
+       W_SetupShot(self, false, 2, SND(CRYLINK_FIRE2), CH_WEAPON_A, maxdmg);
        forward = v_forward;
        right = v_right;
        up = v_up;
@@@ -638,9 -638,6 +638,6 @@@ bool W_Crylink(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("crylink_fire"));
-                       precache_sound(W_Sound("crylink_fire2"));
-                       precache_sound(W_Sound("crylink_linkjoin"));
                        CRYLINK_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), W_Sound("reload"));
+                       W_Reload(min(WEP_CVAR_PRI(crylink, ammo), WEP_CVAR_SEC(crylink, ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -699,21 -696,19 +696,19 @@@ bool W_Crylink(int req
                        {
                                pointparticles(particleeffectnum(EFFECT_CRYLINK_IMPACT2), org2, '0 0 0', 1);
                                if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("crylink_impact2"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_CRYLINK_IMPACT2, VOL_BASE, ATTN_NORM);
                        }
                        else
                        {
                                pointparticles(particleeffectnum(EFFECT_CRYLINK_IMPACT), org2, '0 0 0', 1);
                                if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("crylink_impact"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_CRYLINK_IMPACT, VOL_BASE, ATTN_NORM);
                        }
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("crylink_impact2"));
-                       precache_sound(W_Sound("crylink_impact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 149dbe4dd2f1a063e81678bf7d4b684c46e1c2cb,a011846315b81c4ecbc75633e351e59591b29fb9..0735f79ab4eda876d2da26f947a37ebbb3c1aba2
@@@ -62,8 -62,8 +62,8 @@@ DEVASTATOR_SETTINGS(WEP_ADD_CVAR, WEP_A
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_devastator(void) { weapon_defaultspawnfunc(WEP_DEVASTATOR.m_id); }
 -void spawnfunc_weapon_rocketlauncher(void) { spawnfunc_weapon_devastator(); }
 +spawnfunc(weapon_devastator) { weapon_defaultspawnfunc(WEP_DEVASTATOR.m_id); }
 +spawnfunc(weapon_rocketlauncher) { spawnfunc_weapon_devastator(this); }
  
  void W_Devastator_Unregister(void)
  {SELFPARAM();
@@@ -295,7 -295,7 +295,7 @@@ void W_Devastator_Think(void
                        {
                                Send_Effect(EFFECT_ROCKET_GUIDE, self.origin, self.velocity, 1);
                                // TODO add a better sound here
-                               sound(self.realowner, CH_WEAPON_B, W_Sound("rocket_mode"), VOL_BASE, ATTN_NORM);
+                               sound(self.realowner, CH_WEAPON_B, SND_ROCKET_MODE, VOL_BASE, ATTN_NORM);
                                self.count = 1;
                        }
                }
@@@ -342,7 -342,7 +342,7 @@@ void W_Devastator_Attack(void
  
        W_DecreaseAmmo(WEP_CVAR(devastator, ammo));
  
-       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 5, W_Sound("rocket_fire"), CH_WEAPON_A, WEP_CVAR(devastator, damage));
+       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 5, SND(ROCKET_FIRE), CH_WEAPON_A, WEP_CVAR(devastator, damage));
        Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
        missile = WarpZone_RefSys_SpawnSameRefSys(self);
@@@ -559,7 -559,7 +559,7 @@@ bool W_Devastator(int req
                                                }
                                        }
                                        if(rockfound)
-                                               sound(self, CH_WEAPON_B, W_Sound("rocket_det"), VOL_BASE, ATTN_NORM);
+                                               sound(self, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
                                }
                        }
  
                }
                case WR_INIT:
                {
-                       //if(autocvar_sv_precacheweapons)
-                       //{
-                               precache_sound(W_Sound("rocket_det"));
-                               precache_sound(W_Sound("rocket_fire"));
-                               precache_sound(W_Sound("rocket_mode"));
-                       //}
                        DEVASTATOR_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(WEP_CVAR(devastator, ammo), W_Sound("reload"));
+                       W_Reload(WEP_CVAR(devastator, ammo), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -662,13 -656,12 +656,12 @@@ bool W_Devastator(int req
                        org2 = w_org + w_backoff * 12;
                        pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("rocket_impact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 6ff7229d403f7d0e2ca5e1602350d3fda88607e2,fbc07338808e01a22dc1b10daad005a437f61f5c..85a75ed9c5b9f483ba6d45a3fd5f3fef45feae9f
@@@ -67,7 -67,7 +67,7 @@@ void W_Electro_ExplodeCombo(void)
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_electro(void) { weapon_defaultspawnfunc(WEP_ELECTRO.m_id); }
 +spawnfunc(weapon_electro) { weapon_defaultspawnfunc(WEP_ELECTRO.m_id); }
  
  void W_Electro_TriggerCombo(vector org, float rad, entity own)
  {
@@@ -255,7 -255,7 +255,7 @@@ void W_Electro_Attack_Bolt(void
                '0 0 -3',
                false,
                2,
-               W_Sound("electro_fire"),
+               SND(ELECTRO_FIRE),
                CH_WEAPON_A,
                WEP_CVAR_PRI(electro, damage)
        );
@@@ -296,7 -296,7 +296,7 @@@ void W_Electro_Orb_Touch(void
        else
        {
                //UpdateCSQCProjectile(self);
-               spamsound(self, CH_SHOTS, W_Sound("electro_bounce"), VOL_BASE, ATTEN_NORM);
+               spamsound(self, CH_SHOTS, SND(ELECTRO_BOUNCE), VOL_BASE, ATTEN_NORM);
                self.projectiledeathtype |= HITTYPE_BOUNCE;
        }
  }
@@@ -353,7 -353,7 +353,7 @@@ void W_Electro_Attack_Orb(void
                '0 0 -4',
                false,
                2,
-               W_Sound("electro_fire2"),
+               SND(ELECTRO_FIRE2),
                CH_WEAPON_A,
                WEP_CVAR_SEC(electro, damage)
        );
@@@ -498,11 -498,6 +498,6 @@@ bool W_Electro(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("electro_bounce"));
-                       precache_sound(W_Sound("electro_fire"));
-                       precache_sound(W_Sound("electro_fire2"));
-                       precache_sound(W_Sound("electro_impact"));
-                       precache_sound(W_Sound("electro_impact_combo"));
                        ELECTRO_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), W_Sound("reload"));
+                       W_Reload(min(WEP_CVAR_PRI(electro, ammo), WEP_CVAR_SEC(electro, ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -579,7 -574,7 +574,7 @@@ bool W_Electro(int req
                        {
                                pointparticles(particleeffectnum(EFFECT_ELECTRO_BALLEXPLODE), org2, '0 0 0', 1);
                                if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("electro_impact"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM);
                        }
                        else
                        {
                                        // this is sent as "primary (w_deathtype & HITTYPE_BOUNCE)" to distinguish it from (w_deathtype & HITTYPE_SECONDARY) bounced balls
                                        pointparticles(particleeffectnum(EFFECT_ELECTRO_COMBO), org2, '0 0 0', 1);
                                        if(!w_issilent)
-                                               sound(self, CH_SHOTS, W_Sound("electro_impact_combo"), VOL_BASE, ATTEN_NORM);
+                                               sound(self, CH_SHOTS, SND_ELECTRO_IMPACT_COMBO, VOL_BASE, ATTEN_NORM);
                                }
                                else
                                {
                                        pointparticles(particleeffectnum(EFFECT_ELECTRO_IMPACT), org2, '0 0 0', 1);
                                        if(!w_issilent)
-                                               sound(self, CH_SHOTS, W_Sound("electro_impact"), VOL_BASE, ATTEN_NORM);
+                                               sound(self, CH_SHOTS, SND_ELECTRO_IMPACT, VOL_BASE, ATTEN_NORM);
                                }
                        }
  
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("electro_impact"));
-                       precache_sound(W_Sound("electro_impact_combo"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index f2c8c64acf6eb3a4e02c5257930d57f5b4a310f0,2bf2a6267abb63cc03ad7b508fc524bdfe10f51d..c334932f165f74fb96e7b120522584337460bbc3
@@@ -55,7 -55,7 +55,7 @@@ FIREBALL_SETTINGS(WEP_ADD_CVAR, WEP_ADD
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_fireball(void) { weapon_defaultspawnfunc(WEP_FIREBALL.m_id); }
 +spawnfunc(weapon_fireball) { weapon_defaultspawnfunc(WEP_FIREBALL.m_id); }
  
  void W_Fireball_Explode(void)
  {SELFPARAM();
@@@ -182,7 -182,7 +182,7 @@@ void W_Fireball_Attack1(void
  {SELFPARAM();
        entity proj;
  
-       W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 2, W_Sound("fireball_fire2"), CH_WEAPON_A, WEP_CVAR_PRI(fireball, damage) + WEP_CVAR_PRI(fireball, bfgdamage));
+       W_SetupShot_ProjectileSize(self, '-16 -16 -16', '16 16 16', false, 2, SND(FIREBALL_FIRE2), CH_WEAPON_A, WEP_CVAR_PRI(fireball, damage) + WEP_CVAR_PRI(fireball, bfgdamage));
  
        Send_Effect(EFFECT_FIREBALL_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
@@@ -251,7 -251,7 +251,7 @@@ void W_Fireball_Attack1_Frame1(void
  void W_Fireball_Attack1_Frame0(void)
  {SELFPARAM();
        W_Fireball_AttackEffect(0, '-1.25 -3.75 0');
-       sound(self, CH_WEAPON_SINGLE, W_Sound("fireball_prefire2"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_WEAPON_SINGLE, SND_FIREBALL_PREFIRE2, VOL_BASE, ATTEN_NORM);
        weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_PRI(fireball, animtime), W_Fireball_Attack1_Frame1);
  }
  
@@@ -316,7 -316,7 +316,7 @@@ void W_Fireball_Attack2(void
                        f_diff = '+1.25 +3.75 0';
                        break;
        }
-       W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 2, W_Sound("fireball_fire"), CH_WEAPON_A, WEP_CVAR_SEC(fireball, damage));
+       W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 2, SND(FIREBALL_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(fireball, damage));
        traceline(w_shotorg, w_shotorg + f_diff_x * v_up + f_diff_y * v_right, MOVE_NORMAL, self);
        w_shotorg = trace_endpos;
  
@@@ -399,9 -399,6 +399,6 @@@ bool W_Fireball(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("fireball_fire"));
-                       precache_sound(W_Sound("fireball_fire2"));
-                       precache_sound(W_Sound("fireball_prefire2"));
                        FIREBALL_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
@@@ -460,14 -457,13 +457,13 @@@ bool W_Fireball(int req
                                org2 = w_org + w_backoff * 16;
                                pointparticles(particleeffectnum(EFFECT_FIREBALL_EXPLODE), org2, '0 0 0', 1);
                                if(!w_issilent)
-                                       sound(self, CH_SHOTS, W_Sound("fireball_impact2"), VOL_BASE, ATTEN_NORM * 0.25); // long range boom
+                                       sound(self, CH_SHOTS, SND_FIREBALL_IMPACT2, VOL_BASE, ATTEN_NORM * 0.25); // long range boom
                        }
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("fireball_impact2"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 29ec6b78df99b259557526ee2af33e463549c90b,8001ce15e82a041cefc4f68cc29d54be3b7bb3dd..21755eac69a07005a2a8a24d58efab0d3f2b7c72
@@@ -56,7 -56,7 +56,7 @@@ HAGAR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PR
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_hagar(void) { weapon_defaultspawnfunc(WEP_HAGAR.m_id); }
 +spawnfunc(weapon_hagar) { weapon_defaultspawnfunc(WEP_HAGAR.m_id); }
  
  // NO bounce protection, as bounces are limited!
  
@@@ -127,7 -127,7 +127,7 @@@ void W_Hagar_Attack(void
  
        W_DecreaseAmmo(WEP_CVAR_PRI(hagar, ammo));
  
-       W_SetupShot(self, false, 2, W_Sound("hagar_fire"), CH_WEAPON_A, WEP_CVAR_PRI(hagar, damage));
+       W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_PRI(hagar, damage));
  
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
@@@ -170,7 -170,7 +170,7 @@@ void W_Hagar_Attack2(void
  
        W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo));
  
-       W_SetupShot(self, false, 2, W_Sound("hagar_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
+       W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
  
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
@@@ -223,7 -223,7 +223,7 @@@ void W_Hagar_Attack2_Load_Release(void
  
        weapon_prepareattack_do(1, WEP_CVAR_SEC(hagar, refire));
  
-       W_SetupShot(self, false, 2, W_Sound("hagar_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
+       W_SetupShot(self, false, 2, SND(HAGAR_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hagar, damage));
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
        forward = v_forward;
@@@ -319,7 -319,7 +319,7 @@@ void W_Hagar_Attack2_Load(void
                                self.weaponentity.state = WS_READY;
                                W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo) * self.hagar_load * -1); // give back ammo
                                self.hagar_load = 0;
-                               sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM);
  
                                // pause until we can load rockets again, once we re-press the alt fire button
                                self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_speed) * W_WeaponRateFactor();
                                        W_DecreaseAmmo(WEP_CVAR_SEC(hagar, ammo));
                                        self.weaponentity.state = WS_INUSE;
                                        self.hagar_load += 1;
-                                       sound(self, CH_WEAPON_B, W_Sound("hagar_load"), VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most
+                                       sound(self, CH_WEAPON_B, SND_HAGAR_LOAD, VOL_BASE * 0.8, ATTN_NORM); // sound is too loud according to most
  
                                        if(self.hagar_load >= WEP_CVAR_SEC(hagar, load_max))
                                                stopped = true;
                        if(stopped && !self.hagar_loadbeep && self.hagar_load) // prevents the beep from playing each frame
                        {
                                // if this is the last rocket we can load, play a beep sound to notify the player
-                               sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM);
                                self.hagar_loadbeep = true;
                                self.hagar_loadstep = time + WEP_CVAR_SEC(hagar, load_hold) * W_WeaponRateFactor();
                        }
                        if(!self.hagar_warning) // prevents the beep from playing each frame
                        {
                                // we're about to automatically release after holding time, play a beep sound to notify the player
-                               sound(self, CH_WEAPON_A, W_Sound("hagar_beep"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_WEAPON_A, SND_HAGAR_BEEP, VOL_BASE, ATTN_NORM);
                                self.hagar_warning = true;
                        }
                }
@@@ -451,9 -451,6 +451,6 @@@ bool W_Hagar(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("hagar_fire"));
-                       precache_sound(W_Sound("hagar_load"));
-                       precache_sound(W_Sound("hagar_beep"));
                        HAGAR_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                case WR_RELOAD:
                {
                        if(!self.hagar_load) // require releasing loaded rockets first
-                               W_Reload(min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), W_Sound("reload"));
+                               W_Reload(min(WEP_CVAR_PRI(hagar, ammo), WEP_CVAR_SEC(hagar, ammo)), SND(RELOAD));
  
                        return true;
                }
@@@ -534,20 -531,17 +531,17 @@@ bool W_Hagar(int req
                        if(!w_issilent)
                        {
                                if(w_random<0.15)
-                                       sound(self, CH_SHOTS, W_Sound("hagexp1"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_HAGEXP1, VOL_BASE, ATTN_NORM);
                                else if(w_random<0.7)
-                                       sound(self, CH_SHOTS, W_Sound("hagexp2"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_HAGEXP2, VOL_BASE, ATTN_NORM);
                                else
-                                       sound(self, CH_SHOTS, W_Sound("hagexp3"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_HAGEXP3, VOL_BASE, ATTN_NORM);
                        }
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("hagexp1"));
-                       precache_sound(W_Sound("hagexp2"));
-                       precache_sound(W_Sound("hagexp3"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 034a2502d422b18605069cc97faf55c4148a61cc,a0408d6b9eb26d261f65ad80f93e1068564a795a..ac300fe540b416b632cfd2f89702dacf30f80669
@@@ -48,7 -48,7 +48,7 @@@ HLAC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PRO
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_hlac(void) { weapon_defaultspawnfunc(WEP_HLAC.m_id); }
 +spawnfunc(weapon_hlac) { weapon_defaultspawnfunc(WEP_HLAC.m_id); }
  
  void W_HLAC_Touch(void)
  {SELFPARAM();
@@@ -77,7 -77,7 +77,7 @@@ void W_HLAC_Attack(void
      if(self.crouch)
          spread = spread * WEP_CVAR_PRI(hlac, spread_crouchmod);
  
-       W_SetupShot(self, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage));
+       W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_A, WEP_CVAR_PRI(hlac, damage));
        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
        if(!autocvar_g_norecoil)
        {
@@@ -125,7 -125,7 +125,7 @@@ void W_HLAC_Attack2(void
      if(self.crouch)
          spread = spread * WEP_CVAR_SEC(hlac, spread_crouchmod);
  
-       W_SetupShot(self, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage));
+       W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hlac, damage));
        Send_Effect(EFFECT_BLASTER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
        missile = spawn();
@@@ -241,7 -241,6 +241,6 @@@ bool W_HLAC(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("lasergun_fire"));
                        HLAC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), W_Sound("reload"));
+                       W_Reload(min(WEP_CVAR_PRI(hlac, ammo), WEP_CVAR_SEC(hlac, ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -290,13 -289,12 +289,12 @@@ bool W_HLAC(int req
                        org2 = w_org + w_backoff * 6;
                        pointparticles(particleeffectnum(EFFECT_BLASTER_IMPACT), org2, w_backoff * 1000, 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("laserimpact"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("laserimpact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 18e07204af65e820b1931e7f85896a8faca5b6ef,03196daf6760cad6d0fa86ea6dfbc5db7b07296c..f4c6a3c752a075b1a743c372b69b127150aa8457
@@@ -41,7 -41,7 +41,7 @@@ HMG_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP
  #ifdef IMPLEMENTATION
  #ifdef SVQC
  
 -void spawnfunc_weapon_hmg() { weapon_defaultspawnfunc(WEP_HMG.m_id); }
 +spawnfunc(weapon_hmg) { weapon_defaultspawnfunc(WEP_HMG.m_id); }
  
  void W_HeavyMachineGun_Attack_Auto()
  {SELFPARAM();
@@@ -61,7 -61,7 +61,7 @@@
  
        W_DecreaseAmmo(WEP_CVAR(hmg, ammo));
  
-       W_SetupShot (self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, WEP_CVAR(hmg, damage));
+       W_SetupShot (self, true, 0, SND(UZI_FIRE), CH_WEAPON_A, WEP_CVAR(hmg, damage));
  
        if(!autocvar_g_norecoil)
        {
@@@ -118,7 -118,6 +118,6 @@@ bool W_HeavyMachineGun(int req
                }
                case WR_INIT:
                {
-                       precache_sound (W_Sound("uzi_fire"));
                        HMG_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(WEP_CVAR(hmg, ammo), W_Sound("reload"));
+                       W_Reload(WEP_CVAR(hmg, ammo), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -177,19 -176,16 +176,16 @@@ bool W_HeavyMachineGun(int req
                        pointparticles(particleeffectnum(EFFECT_MACHINEGUN_IMPACT), org2, w_backoff * 1000, 1);
                        if(!w_issilent)
                                if(w_random < 0.05)
-                                       sound(self, CH_SHOTS, W_Sound("ric1"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC1, VOL_BASE, ATTEN_NORM);
                                else if(w_random < 0.1)
-                                       sound(self, CH_SHOTS, W_Sound("ric2"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC2, VOL_BASE, ATTEN_NORM);
                                else if(w_random < 0.2)
-                                       sound(self, CH_SHOTS, W_Sound("ric3"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC3, VOL_BASE, ATTEN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("ric1"));
-                       precache_sound(W_Sound("ric2"));
-                       precache_sound(W_Sound("ric3"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 3828bdb1eb84263ff867e078e3f83ee58246106c,af52ec15bb01c71601e5aeec50be58f4bdebfc55..6c1f82fdf8561a6ed83387731cbbbb89bbe64343
@@@ -59,8 -59,8 +59,8 @@@ HOOK_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PRO
  #ifdef IMPLEMENTATION
  #ifdef SVQC
  
 -void spawnfunc_weapon_hook(void)
 -{SELFPARAM();
 +spawnfunc(weapon_hook)
 +{
        if(g_grappling_hook) // offhand hook
        {
                startitem_failed = true;
@@@ -134,7 -134,7 +134,7 @@@ void W_Hook_Attack2(void
        entity gren;
  
        //W_DecreaseAmmo(WEP_CVAR_SEC(hook, ammo)); // WEAPONTODO: Figure out how to handle ammo with hook secondary (gravitybomb)
-       W_SetupShot(self, false, 4, W_Sound("hookbomb_fire"), CH_WEAPON_A, WEP_CVAR_SEC(hook, damage));
+       W_SetupShot(self, false, 4, SND(HOOKBOMB_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(hook, damage));
  
        gren = spawn();
        gren.owner = gren.realowner = self;
@@@ -288,9 -288,6 +288,6 @@@ bool W_Hook(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("hook_impact")); // done by g_hook.qc
-                       precache_sound(W_Sound("hook_fire"));
-                       precache_sound(W_Sound("hookbomb_fire"));
                        HOOK_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
@@@ -344,13 -341,12 +341,12 @@@ bool W_Hook(int req
                        org2 = w_org + w_backoff * 2;
                        pointparticles(particleeffectnum(EFFECT_HOOK_EXPLODE), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("hookbomb_impact"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, SND_HOOKBOMB_IMPACT, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("hookbomb_impact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 61f9210d902cfa56ddfa576292d8f11211d6e4ca,6db6d1633d4f2ad295473b295206e02fc6a18d4c..e9a50ab4393d34c6eb976ea1dbae2c77bb211f8c
@@@ -55,8 -55,8 +55,8 @@@ MACHINEGUN_SETTINGS(WEP_ADD_CVAR, WEP_A
  #ifdef IMPLEMENTATION
  #ifdef SVQC
  
 -void spawnfunc_weapon_machinegun(void)
 -{SELFPARAM();
 +spawnfunc(weapon_machinegun)
 +{
        if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
@@@ -65,7 -65,7 +65,7 @@@
        }
        weapon_defaultspawnfunc(WEP_MACHINEGUN.m_id);
  }
 -void spawnfunc_weapon_uzi(void) { spawnfunc_weapon_machinegun(); }
 +spawnfunc(weapon_uzi) { spawnfunc_weapon_machinegun(this); }
  
  void W_MachineGun_MuzzleFlash_Think(void)
  {SELFPARAM();
@@@ -104,7 -104,7 +104,7 @@@ void W_MachineGun_MuzzleFlash(void
  
  void W_MachineGun_Attack(int deathtype)
  {SELFPARAM();
-       W_SetupShot(self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, ((self.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
+       W_SetupShot(self, true, 0, SND(UZI_FIRE), CH_WEAPON_A, ((self.misc_bulletcounter == 1) ? WEP_CVAR(machinegun, first_damage) : WEP_CVAR(machinegun, sustained_damage)));
        if(!autocvar_g_norecoil)
        {
                self.punchangle_x = random() - 0.5;
@@@ -180,7 -180,7 +180,7 @@@ void W_MachineGun_Attack_Auto(void
  
        W_DecreaseAmmo(WEP_CVAR(machinegun, sustained_ammo));
  
-       W_SetupShot(self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
+       W_SetupShot(self, true, 0, SND(UZI_FIRE), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
        if(!autocvar_g_norecoil)
        {
                self.punchangle_x = random() - 0.5;
  
  void W_MachineGun_Attack_Burst(void)
  {SELFPARAM();
-       W_SetupShot(self, true, 0, W_Sound("uzi_fire"), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
+       W_SetupShot(self, true, 0, SND(UZI_FIRE), CH_WEAPON_A, WEP_CVAR(machinegun, sustained_damage));
        if(!autocvar_g_norecoil)
        {
                self.punchangle_x = random() - 0.5;
@@@ -304,7 -304,6 +304,6 @@@ bool W_MachineGun(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("uzi_fire"));
                        MACHINEGUN_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), W_Sound("reload"));
+                       W_Reload(min(max(WEP_CVAR(machinegun, sustained_ammo), WEP_CVAR(machinegun, first_ammo)), WEP_CVAR(machinegun, burst_ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -377,19 -376,16 +376,16 @@@ bool W_MachineGun(int req
                        pointparticles(particleeffectnum(EFFECT_MACHINEGUN_IMPACT), org2, w_backoff * 1000, 1);
                        if(!w_issilent)
                                if(w_random < 0.05)
-                                       sound(self, CH_SHOTS, W_Sound("ric1"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC1, VOL_BASE, ATTN_NORM);
                                else if(w_random < 0.1)
-                                       sound(self, CH_SHOTS, W_Sound("ric2"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC2, VOL_BASE, ATTN_NORM);
                                else if(w_random < 0.2)
-                                       sound(self, CH_SHOTS, W_Sound("ric3"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC3, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("ric1"));
-                       precache_sound(W_Sound("ric2"));
-                       precache_sound(W_Sound("ric3"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index d1212d6a124fa4c90e4bfdb442d3fd07a23d2bec,05dde9852737836bf8b193944b2ffcc8947e89f0..40866970fb3438d3fd2fcd83cdc0bfeaccc05b76
@@@ -57,11 -57,11 +57,11 @@@ void W_MineLayer_Think(void)
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_minelayer(void) { weapon_defaultspawnfunc(WEP_MINE_LAYER.m_id); }
 +spawnfunc(weapon_minelayer) { weapon_defaultspawnfunc(WEP_MINE_LAYER.m_id); }
  
  void W_MineLayer_Stick(entity to)
  {SELFPARAM();
-       spamsound(self, CH_SHOTS, W_Sound("mine_stick"), VOL_BASE, ATTN_NORM);
+       spamsound(self, CH_SHOTS, SND(MINE_STICK), VOL_BASE, ATTN_NORM);
  
        // in order for mines to face properly when sticking to the ground, they must be a server side entity rather than a csqc projectile
  
@@@ -221,7 -221,7 +221,7 @@@ void W_MineLayer_Think(void
        if((time > self.cnt) && (!self.mine_time) && (self.cnt > 0))
        {
                if(WEP_CVAR(minelayer, lifetime_countdown) > 0)
-                       spamsound(self, CH_SHOTS, W_Sound("mine_trigger"), VOL_BASE, ATTN_NORM);
+                       spamsound(self, CH_SHOTS, SND(MINE_TRIGGER), VOL_BASE, ATTN_NORM);
                self.mine_time = time + WEP_CVAR(minelayer, lifetime_countdown);
                self.mine_explodeanyway = 1; // make the mine super aggressive -- Samual: Rather, make it not care if a team mate is near.
        }
                if(head != self.realowner && DIFF_TEAM(head, self.realowner)) // don't trigger for team mates
                if(!self.mine_time)
                {
-                       spamsound(self, CH_SHOTS, W_Sound("mine_trigger"), VOL_BASE, ATTN_NORM);
+                       spamsound(self, CH_SHOTS, SND(MINE_TRIGGER), VOL_BASE, ATTN_NORM);
                        self.mine_time = time + WEP_CVAR(minelayer, time);
                }
                head = head.chain;
@@@ -316,14 -316,14 +316,14 @@@ void W_MineLayer_Attack(void
                {
                        // the refire delay keeps this message from being spammed
                        Send_Notification(NOTIF_ONE, self, MSG_MULTI, WEAPON_MINELAYER_LIMIT, WEP_CVAR(minelayer, limit));
-                       play2(self, W_Sound("unavailable"));
+                       play2(self, SND(UNAVAILABLE));
                        return;
                }
        }
  
        W_DecreaseAmmo(WEP_CVAR(minelayer, ammo));
  
-       W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 5, W_Sound("mine_fire"), CH_WEAPON_A, WEP_CVAR(minelayer, damage));
+       W_SetupShot_ProjectileSize(self, '-4 -4 -4', '4 4 4', false, 5, SND(MINE_FIRE), CH_WEAPON_A, WEP_CVAR(minelayer, damage));
        Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
        mine = WarpZone_RefSys_SpawnSameRefSys(self);
@@@ -523,17 -523,13 +523,13 @@@ bool W_MineLayer(int req
                        if(self.BUTTON_ATCK2)
                        {
                                if(W_MineLayer_PlacedMines(true))
-                                       sound(self, CH_WEAPON_B, W_Sound("mine_det"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_WEAPON_B, SND_MINE_DET, VOL_BASE, ATTN_NORM);
                        }
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("mine_det"));
-                       precache_sound(W_Sound("mine_fire"));
-                       precache_sound(W_Sound("mine_stick"));
-                       precache_sound(W_Sound("mine_trigger"));
                        MINELAYER_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(WEP_CVAR(minelayer, ammo), W_Sound("reload"));
+                       W_Reload(WEP_CVAR(minelayer, ammo), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -593,13 -589,12 +589,12 @@@ bool W_MineLayer(int req
                        org2 = w_org + w_backoff * 12;
                        pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("mine_exp"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, SND_MINE_EXP, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("mine_exp"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index b766b1c3392025573230ae98e0b4444fdbf6f14b,665367fd78ad836ddc4408133455f0125c53b803..1276cca5d9347bbcd45d4142014a2793aa9c703f
@@@ -56,8 -56,8 +56,8 @@@ MORTAR_SETTINGS(WEP_ADD_CVAR, WEP_ADD_P
  #ifdef IMPLEMENTATION
  #ifdef SVQC
  
 -void spawnfunc_weapon_mortar(void) { weapon_defaultspawnfunc(WEP_MORTAR.m_id); }
 -void spawnfunc_weapon_grenadelauncher(void) { spawnfunc_weapon_mortar(); }
 +spawnfunc(weapon_mortar) { weapon_defaultspawnfunc(WEP_MORTAR.m_id); }
 +spawnfunc(weapon_grenadelauncher) { spawnfunc_weapon_mortar(this); }
  
  void W_Mortar_Grenade_Explode(void)
  {SELFPARAM();
@@@ -137,27 -137,14 +137,14 @@@ void W_Mortar_Grenade_Touch1(void
        }
        else if(WEP_CVAR_PRI(mortar, type) == 1) // bounce
        {
-               float r;
-               r = random() * 6;
-               if(r < 1)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce1"), VOL_BASE, ATTN_NORM);
-               else if(r < 2)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce2"), VOL_BASE, ATTN_NORM);
-               else if(r < 3)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce3"), VOL_BASE, ATTN_NORM);
-               else if(r < 4)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce4"), VOL_BASE, ATTN_NORM);
-               else if(r < 5)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce5"), VOL_BASE, ATTN_NORM);
-               else
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce6"), VOL_BASE, ATTN_NORM);
+               spamsound(self, CH_SHOTS, SND(GRENADE_BOUNCE_RANDOM()), VOL_BASE, ATTN_NORM);
                Send_Effect(EFFECT_HAGAR_BOUNCE, self.origin, self.velocity, 1);
                self.projectiledeathtype |= HITTYPE_BOUNCE;
                self.gl_bouncecnt += 1;
        }
        else if(WEP_CVAR_PRI(mortar, type) == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) // stick
        {
-               spamsound(self, CH_SHOTS, W_Sound("grenade_stick"), VOL_BASE, ATTN_NORM);
+               spamsound(self, CH_SHOTS, SND(GRENADE_STICK), VOL_BASE, ATTN_NORM);
  
                // let it stick whereever it is
                self.oldvelocity = self.velocity;
@@@ -182,20 -169,7 +169,7 @@@ void W_Mortar_Grenade_Touch2(void
        }
        else if(WEP_CVAR_SEC(mortar, type) == 1) // bounce
        {
-               float r;
-               r = random() * 6;
-               if(r < 1)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce1"), VOL_BASE, ATTN_NORM);
-               else if(r < 2)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce2"), VOL_BASE, ATTN_NORM);
-               else if(r < 3)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce3"), VOL_BASE, ATTN_NORM);
-               else if(r < 4)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce4"), VOL_BASE, ATTN_NORM);
-               else if(r < 5)
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce5"), VOL_BASE, ATTN_NORM);
-               else
-                       spamsound(self, CH_SHOTS, W_Sound("grenade_bounce6"), VOL_BASE, ATTN_NORM);
+               spamsound(self, CH_SHOTS, SND(GRENADE_BOUNCE_RANDOM()), VOL_BASE, ATTN_NORM);
                Send_Effect(EFFECT_HAGAR_BOUNCE, self.origin, self.velocity, 1);
                self.projectiledeathtype |= HITTYPE_BOUNCE;
                self.gl_bouncecnt += 1;
        }
        else if(WEP_CVAR_SEC(mortar, type) == 2 && (!other || (other.takedamage != DAMAGE_AIM && other.movetype == MOVETYPE_NONE))) // stick
        {
-               spamsound(self, CH_SHOTS, W_Sound("grenade_stick"), VOL_BASE, ATTN_NORM);
+               spamsound(self, CH_SHOTS, SND(GRENADE_STICK), VOL_BASE, ATTN_NORM);
  
                // let it stick whereever it is
                self.oldvelocity = self.velocity;
@@@ -228,7 -202,7 +202,7 @@@ void W_Mortar_Attack(void
  
        W_DecreaseAmmo(WEP_CVAR_PRI(mortar, ammo));
  
-       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, W_Sound("grenade_fire"), CH_WEAPON_A, WEP_CVAR_PRI(mortar, damage));
+       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, SND(GRENADE_FIRE), CH_WEAPON_A, WEP_CVAR_PRI(mortar, damage));
        w_shotdir = v_forward; // no TrueAim for grenades please
  
        Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
@@@ -277,7 -251,7 +251,7 @@@ void W_Mortar_Attack2(void
  
        W_DecreaseAmmo(WEP_CVAR_SEC(mortar, ammo));
  
-       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, W_Sound("grenade_fire"), CH_WEAPON_A, WEP_CVAR_SEC(mortar, damage));
+       W_SetupShot_ProjectileSize(self, '-3 -3 -3', '3 3 3', false, 4, SND(GRENADE_FIRE), CH_WEAPON_A, WEP_CVAR_SEC(mortar, damage));
        w_shotdir = v_forward; // no TrueAim for grenades please
  
        Send_Effect(EFFECT_GRENADE_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
@@@ -392,7 -366,7 +366,7 @@@ bool W_Mortar(int req
                                                }
                                        }
                                        if(nadefound)
-                                               sound(self, CH_WEAPON_B, W_Sound("rocket_det"), VOL_BASE, ATTN_NORM);
+                                               sound(self, CH_WEAPON_B, SND_ROCKET_DET, VOL_BASE, ATTN_NORM);
                                }
                                else if(weapon_prepareattack(1, WEP_CVAR_SEC(mortar, refire)))
                                {
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("grenade_bounce1"));
-                       precache_sound(W_Sound("grenade_bounce2"));
-                       precache_sound(W_Sound("grenade_bounce3"));
-                       precache_sound(W_Sound("grenade_bounce4"));
-                       precache_sound(W_Sound("grenade_bounce5"));
-                       precache_sound(W_Sound("grenade_bounce6"));
-                       precache_sound(W_Sound("grenade_stick"));
-                       precache_sound(W_Sound("grenade_fire"));
                        MORTAR_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), W_Sound("reload")); // WEAPONTODO
+                       W_Reload(min(WEP_CVAR_PRI(mortar, ammo), WEP_CVAR_SEC(mortar, ammo)), SND(RELOAD)); // WEAPONTODO
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -467,13 -433,12 +433,12 @@@ bool W_Mortar(int req
                        org2 = w_org + w_backoff * 12;
                        pointparticles(particleeffectnum(EFFECT_GRENADE_EXPLODE), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("grenade_impact"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, SND_GRENADE_IMPACT, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("grenade_impact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index 4438c5d83954c9ef61ae6537f585ed189055373d,d764286b705dd099154a55c2c9e286576fc636f2..66cdb21228b099c4d240a9b14ed12a0c5393cbf8
@@@ -41,7 -41,7 +41,7 @@@ PORTO_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PR
  #ifdef SVQC
  #include "../../triggers/trigger/jumppads.qh"
  
 -void spawnfunc_weapon_porto(void) { weapon_defaultspawnfunc(WEP_PORTO.m_id); }
 +spawnfunc(weapon_porto) { weapon_defaultspawnfunc(WEP_PORTO.m_id); }
  
  void W_Porto_Success(void)
  {SELFPARAM();
@@@ -132,19 -132,19 +132,19 @@@ void W_Porto_Touch(void
  
        if(self.realowner.playerid != self.playerid)
        {
-               sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+               sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                remove(self);
        }
        else if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_SLICK || trace_dphitcontents & DPCONTENTS_PLAYERCLIP)
        {
-               spamsound(self, CH_SHOTS, "porto/bounce.wav", VOL_BASE, ATTEN_NORM);
+               spamsound(self, CH_SHOTS, SND(PORTO_BOUNCE), VOL_BASE, ATTEN_NORM);
                // just reflect
                self.right_vector = self.right_vector - 2 * trace_plane_normal * (self.right_vector * trace_plane_normal);
                self.angles = vectoangles(self.velocity - 2 * trace_plane_normal * (self.velocity * trace_plane_normal));
        }
        else if(trace_dphitq3surfaceflags & Q3SURFACEFLAG_NOIMPACT)
        {
-               sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+               sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                W_Porto_Fail(0);
                if(self.cnt < 0)
                        Portal_ClearAll_PortalsOnly(self.realowner);
                // in-portal only
                if(Portal_SpawnInPortalAtTrace(self.realowner, self.right_vector, self.portal_id))
                {
-                       sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_CREATE, VOL_BASE, ATTEN_NORM);
                        trace_plane_normal = norm;
                        Send_Notification(NOTIF_ONE, self.realowner, MSG_CENTER, CENTER_PORTO_CREATED_IN);
                        W_Porto_Success();
                }
                else
                {
-                       sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                        trace_plane_normal = norm;
                        W_Porto_Fail(0);
                }
                // out-portal only
                if(Portal_SpawnOutPortalAtTrace(self.realowner, self.right_vector, self.portal_id))
                {
-                       sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_CREATE, VOL_BASE, ATTEN_NORM);
                        trace_plane_normal = norm;
                        Send_Notification(NOTIF_ONE, self.realowner, MSG_CENTER, CENTER_PORTO_CREATED_OUT);
                        W_Porto_Success();
                }
                else
                {
-                       sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                        trace_plane_normal = norm;
                        W_Porto_Fail(0);
                }
                self.effects += EF_BLUE - EF_RED;
                if(Portal_SpawnInPortalAtTrace(self.realowner, self.right_vector, self.portal_id))
                {
-                       sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_CREATE, VOL_BASE, ATTEN_NORM);
                        trace_plane_normal = norm;
                        Send_Notification(NOTIF_ONE, self.realowner, MSG_CENTER, CENTER_PORTO_CREATED_IN);
                        self.right_vector = self.right_vector - 2 * trace_plane_normal * (self.right_vector * norm);
                }
                else
                {
-                       sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                        trace_plane_normal = norm;
                        Portal_ClearAll_PortalsOnly(self.realowner);
                        W_Porto_Fail(0);
                {
                        if(Portal_SpawnOutPortalAtTrace(self.realowner, self.right_vector, self.portal_id))
                        {
-                               sound(self, CH_SHOTS, "porto/create.wav", VOL_BASE, ATTEN_NORM);
+                               sound(self, CH_SHOTS, SND_PORTO_CREATE, VOL_BASE, ATTEN_NORM);
                                trace_plane_normal = norm;
                                Send_Notification(NOTIF_ONE, self.realowner, MSG_CENTER, CENTER_PORTO_CREATED_OUT);
                                W_Porto_Success();
                        }
                        else
                        {
-                               sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+                               sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                                Portal_ClearAll_PortalsOnly(self.realowner);
                                W_Porto_Fail(0);
                        }
                }
                else
                {
-                       sound(self, CH_SHOTS, "porto/unsupported.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_SHOTS, SND_PORTO_UNSUPPORTED, VOL_BASE, ATTEN_NORM);
                        Portal_ClearAll_PortalsOnly(self.realowner);
                        W_Porto_Fail(0);
                }
@@@ -234,7 -234,7 +234,7 @@@ void W_Porto_Attack(float type
  {SELFPARAM();
        entity gren;
  
-       W_SetupShot(self, false, 4, "porto/fire.wav", CH_WEAPON_A, 0);
+       W_SetupShot(self, false, 4, SND(PORTO_FIRE), CH_WEAPON_A, 0);
        // always shoot from the eye
        w_shotdir = v_forward;
        w_shotorg = self.origin + self.view_ofs + ((w_shotorg - self.origin - self.view_ofs) * v_forward) * v_forward;
@@@ -373,12 -373,6 +373,6 @@@ bool W_Porto(int req
                }
                case WR_INIT:
                {
-                       precache_sound("porto/bounce.wav");
-                       precache_sound("porto/create.wav");
-                       precache_sound("porto/expire.wav");
-                       precache_sound("porto/explode.wav");
-                       precache_sound("porto/fire.wav");
-                       precache_sound("porto/unsupported.wav");
                        PORTO_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
index 69e325d8ef636fa9c9ec1e8f833ab907038fdb50,6d4a58f272d123ea7abba15e306fda9af89e1c73..c156d84b46e9285841f055fffc78282f0a19e859
@@@ -47,9 -47,9 +47,9 @@@ RIFLE_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PR
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_rifle(void) { weapon_defaultspawnfunc(WEP_RIFLE.m_id); }
 -void spawnfunc_weapon_campingrifle(void) { spawnfunc_weapon_rifle(); }
 -void spawnfunc_weapon_sniperrifle(void) { spawnfunc_weapon_rifle(); }
 +spawnfunc(weapon_rifle) { weapon_defaultspawnfunc(WEP_RIFLE.m_id); }
 +spawnfunc(weapon_campingrifle) { spawnfunc_weapon_rifle(this); }
 +spawnfunc(weapon_sniperrifle) { spawnfunc_weapon_rifle(this); }
  
  void W_Rifle_FireBullet(float pSpread, float pDamage, float pForce, float pSolidPenetration, float pAmmo, int deathtype, float pTracer, float pShots, string pSound)
  {SELFPARAM();
  
  void W_Rifle_Attack(void)
  {
-       W_Rifle_FireBullet(WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), W_Sound("campingrifle_fire"));
+       W_Rifle_FireBullet(WEP_CVAR_PRI(rifle, spread), WEP_CVAR_PRI(rifle, damage), WEP_CVAR_PRI(rifle, force), WEP_CVAR_PRI(rifle, solidpenetration), WEP_CVAR_PRI(rifle, ammo), WEP_RIFLE.m_id, WEP_CVAR_PRI(rifle, tracer), WEP_CVAR_PRI(rifle, shots), SND(CAMPINGRIFLE_FIRE));
  }
  
  void W_Rifle_Attack2(void)
  {
-       W_Rifle_FireBullet(WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), W_Sound("campingrifle_fire2"));
+       W_Rifle_FireBullet(WEP_CVAR_SEC(rifle, spread), WEP_CVAR_SEC(rifle, damage), WEP_CVAR_SEC(rifle, force), WEP_CVAR_SEC(rifle, solidpenetration), WEP_CVAR_SEC(rifle, ammo), WEP_RIFLE.m_id | HITTYPE_SECONDARY, WEP_CVAR_SEC(rifle, tracer), WEP_CVAR_SEC(rifle, shots), SND(CAMPINGRIFLE_FIRE2));
  }
  
  .void(void) rifle_bullethail_attackfunc;
@@@ -204,8 -204,6 +204,6 @@@ bool W_Rifle(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("campingrifle_fire"));
-                       precache_sound(W_Sound("campingrifle_fire2"));
                        RIFLE_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), W_Sound("reload"));
+                       W_Reload(min(WEP_CVAR_PRI(rifle, ammo), WEP_CVAR_SEC(rifle, ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -274,20 -272,17 +272,17 @@@ bool W_Rifle(int req
                        if(!w_issilent)
                        {
                                if(w_random < 0.2)
-                                       sound(self, CH_SHOTS, W_Sound("ric1"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC1, VOL_BASE, ATTN_NORM);
                                else if(w_random < 0.4)
-                                       sound(self, CH_SHOTS, W_Sound("ric2"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC2, VOL_BASE, ATTN_NORM);
                                else if(w_random < 0.5)
-                                       sound(self, CH_SHOTS, W_Sound("ric3"), VOL_BASE, ATTN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC3, VOL_BASE, ATTN_NORM);
                        }
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("ric1"));
-                       precache_sound(W_Sound("ric2"));
-                       precache_sound(W_Sound("ric3"));
                        if(autocvar_cl_reticle && autocvar_cl_reticle_weapon)
                        {
                                precache_pic("gfx/reticle_nex");
index a8509c15e2b137640355378cc85efa3823fe84db,5fe7552ccb60fdd6c2620b2d2609f6b789c8086c..4286ce433746a366bc78cebda4f4ffc43d7c2113
@@@ -45,7 -45,7 +45,7 @@@ RPC_SETTINGS(WEP_ADD_CVAR, WEP_ADD_PROP
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_rpc() { weapon_defaultspawnfunc(WEP_RPC.m_id); }
 +spawnfunc(weapon_rpc) { weapon_defaultspawnfunc(WEP_RPC.m_id); }
  
  void W_RocketPropelledChainsaw_Explode()
  {SELFPARAM();
@@@ -108,7 -108,7 +108,7 @@@ void W_RocketPropelledChainsaw_Attack (
        entity flash = spawn ();
  
        W_DecreaseAmmo(WEP_CVAR(rpc, ammo));
-       W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', false, 5, W_Sound("rocket_fire"), CH_WEAPON_A, WEP_CVAR(rpc, damage));
+       W_SetupShot_ProjectileSize (self, '-3 -3 -3', '3 3 3', false, 5, SND(ROCKET_FIRE), CH_WEAPON_A, WEP_CVAR(rpc, damage));
        Send_Effect(EFFECT_ROCKET_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
        PROJECTILE_MAKETRIGGER(missile);
  
@@@ -182,7 -182,6 +182,6 @@@ bool W_RocketPropelledChainsaw(int req
                }
                case WR_INIT:
                {
-                       precache_sound (W_Sound("rocket_fire"));
                        RPC_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(WEP_CVAR(rpc, ammo), W_Sound("reload"));
+                       W_Reload(WEP_CVAR(rpc, ammo), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -239,13 -238,12 +238,12 @@@ bool W_RocketPropelledChainsaw(int req
                        org2 = w_org + w_backoff * 12;
                        pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+                               sound(self, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("rocket_impact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index d3d8ac3c7328c91fc842e8f3323f335b8c5b0060,b79bb081e25e76a26fc98b2e2ed6e4459e54b823..1686ff5290fec13b21f13b7c773a598ca75a15d5
@@@ -84,7 -84,7 +84,7 @@@ SEEKER_SETTINGS(WEP_ADD_CVAR, WEP_ADD_P
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_seeker(void) { weapon_defaultspawnfunc(WEP_SEEKER.m_id); }
 +spawnfunc(weapon_seeker) { weapon_defaultspawnfunc(WEP_SEEKER.m_id); }
  
  // ============================
  // Begin: Missile functions, these are general functions to be manipulated by other code
@@@ -250,7 -250,7 +250,7 @@@ void W_Seeker_Fire_Missile(vector f_dif
        W_DecreaseAmmo(WEP_CVAR(seeker, missile_ammo));
  
        makevectors(self.v_angle);
-       W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, W_Sound("seeker_fire"), CH_WEAPON_A, 0);
+       W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(SEEKER_FIRE), CH_WEAPON_A, 0);
        w_shotorg += f_diff;
        Send_Effect(EFFECT_SEEKER_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
@@@ -341,7 -341,7 +341,7 @@@ void W_Seeker_Fire_Flac(void
                        f_diff = '+1.25 +3.75 0';
                        break;
        }
-       W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, W_Sound("flac_fire"), CH_WEAPON_A, WEP_CVAR(seeker, flac_damage));
+       W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(FLAC_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, flac_damage));
        w_shotorg += f_diff;
  
        Send_Effect(EFFECT_HAGAR_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
@@@ -559,7 -559,7 +559,7 @@@ void W_Seeker_Fire_Tag(void
        entity missile;
        W_DecreaseAmmo(WEP_CVAR(seeker, tag_ammo));
  
-       W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, W_Sound("tag_fire"), CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count));
+       W_SetupShot_ProjectileSize(self, '-2 -2 -2', '2 2 2', false, 2, SND(TAG_FIRE), CH_WEAPON_A, WEP_CVAR(seeker, missile_damage) * WEP_CVAR(seeker, missile_count));
  
        missile                 = spawn();
        missile.owner           = missile.realowner = self;
@@@ -662,9 -662,6 +662,6 @@@ bool W_Seeker(int req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("tag_fire"));
-                       precache_sound(W_Sound("flac_fire"));
-                       precache_sound(W_Sound("seeker_fire"));
                        SEEKER_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), W_Sound("reload"));
+                       W_Reload(min(WEP_CVAR(seeker, missile_ammo), WEP_CVAR(seeker, tag_ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -735,7 -732,7 +732,7 @@@ bool W_Seeker(int req
                                if(w_deathtype & HITTYPE_SECONDARY)
                                {
                                        if(!w_issilent)
-                                               sound(self, CH_SHOTS, W_Sound("tag_impact"), 1, ATTEN_NORM);
+                                               sound(self, CH_SHOTS, SND_TAG_IMPACT, 1, ATTEN_NORM);
                                }
                                else
                                {
                                        if(!w_issilent)
                                        {
                                                if(w_random<0.15)
-                                                       sound(self, CH_SHOTS, W_Sound("tagexp1"), 1, ATTEN_NORM);
+                                                       sound(self, CH_SHOTS, SND_TAGEXP1, 1, ATTEN_NORM);
                                                else if(w_random<0.7)
-                                                       sound(self, CH_SHOTS, W_Sound("tagexp2"), 1, ATTEN_NORM);
+                                                       sound(self, CH_SHOTS, SND_TAGEXP2, 1, ATTEN_NORM);
                                                else
-                                                       sound(self, CH_SHOTS, W_Sound("tagexp3"), 1, ATTEN_NORM);
+                                                       sound(self, CH_SHOTS, SND_TAGEXP3, 1, ATTEN_NORM);
                                        }
                                }
                        }
                                if(!w_issilent)
                                {
                                        if(w_random<0.15)
-                                               sound(self, CH_SHOTS, W_Sound("seekerexp1"), 1, ATTEN_NORM);
+                                               sound(self, CH_SHOTS, SND_SEEKEREXP1, 1, ATTEN_NORM);
                                        else if(w_random<0.7)
-                                               sound(self, CH_SHOTS, W_Sound("seekerexp2"), 1, ATTEN_NORM);
+                                               sound(self, CH_SHOTS, SND_SEEKEREXP2, 1, ATTEN_NORM);
                                        else
-                                               sound(self, CH_SHOTS, W_Sound("seekerexp3"), 1, ATTEN_NORM);
+                                               sound(self, CH_SHOTS, SND_SEEKEREXP3, 1, ATTEN_NORM);
                                }
                        }
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("seekerexp1"));
-                       precache_sound(W_Sound("seekerexp2"));
-                       precache_sound(W_Sound("seekerexp3"));
-                       precache_sound(W_Sound("tagexp1"));
-                       precache_sound(W_Sound("tagexp2"));
-                       precache_sound(W_Sound("tagexp3"));
-                       precache_sound(W_Sound("tag_impact"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index de8f34777b4e0185ac068f36b62d305da5f68c04,0ef52fbd9d69051b328ab0b4008c8802f8329af6..a067110b7285af22ea359248ab43981093786834
@@@ -82,8 -82,8 +82,8 @@@ void Net_ReadShockwaveParticle(void)
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_shockwave(void)
 -{SELFPARAM();
 +spawnfunc(weapon_shockwave)
 +{
        //if(autocvar_sv_q3acompat_machineshockwaveswap) // WEAPONTODO
        if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
@@@ -229,7 -229,7 +229,7 @@@ void W_Shockwave_Melee_Think(void
  
  void W_Shockwave_Melee(void)
  {SELFPARAM();
-       sound(self, CH_WEAPON_A, W_Sound("shotgun_melee"), VOL_BASE, ATTN_NORM);
+       sound(self, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTN_NORM);
        weapon_thinkf(WFRAME_FIRE2, WEP_CVAR(shockwave, melee_animtime), w_ready);
  
        entity meleetemp;
@@@ -360,7 -360,7 +360,7 @@@ void W_Shockwave_Attack(void
        float i, queue = 0;
  
        // set up the shot direction
-       W_SetupShot(self, false, 3, W_Sound("lasergun_fire"), CH_WEAPON_B, WEP_CVAR(shockwave, blast_damage));
+       W_SetupShot(self, false, 3, SND(LASERGUN_FIRE), CH_WEAPON_B, WEP_CVAR(shockwave, blast_damage));
        vector attack_endpos = (w_shotorg + (w_shotdir * WEP_CVAR(shockwave, blast_distance)));
        WarpZone_TraceLine(w_shotorg, attack_endpos, MOVE_NOMONSTERS, self);
        vector attack_hitpos = trace_endpos;
@@@ -708,9 -708,6 +708,6 @@@ bool W_Shockwave(int req
                }
                case WR_INIT:
                {
-                       precache_sound("misc/itempickup.wav");
-                       precache_sound(W_Sound("lasergun_fire"));
-                       precache_sound(W_Sound("shotgun_melee"));
                        SHOCKWAVE_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
@@@ -875,9 -872,6 +872,6 @@@ bool W_Shockwave(int req
                }
                case WR_INIT:
                {
-                       //precache_sound(W_Sound("ric1"));
-                       //precache_sound(W_Sound("ric2"));
-                       //precache_sound(W_Sound("ric3"));
                        return false;
                }
                case WR_ZOOMRETICLE:
index ce93321a94709cfb0ff19d443fa687d978b75e6c,9a8d9d0db706e1453573151d895aa10acd7c1081..05f4cf6ab0bec6d3cdf88b381714882cfbc382b8
@@@ -52,7 -52,7 +52,7 @@@ SHOTGUN_SETTINGS(WEP_ADD_CVAR, WEP_ADD_
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_shotgun(void) { weapon_defaultspawnfunc(WEP_SHOTGUN.m_id); }
 +spawnfunc(weapon_shotgun) { weapon_defaultspawnfunc(WEP_SHOTGUN.m_id); }
  
  void W_Shotgun_Attack(float isprimary)
  {SELFPARAM();
@@@ -61,7 -61,7 +61,7 @@@
  
        W_DecreaseAmmo(WEP_CVAR_PRI(shotgun, ammo));
  
-       W_SetupShot(self, true, 5, W_Sound("shotgun_fire"), ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets));
+       W_SetupShot(self, true, 5, SND(SHOTGUN_FIRE), ((isprimary) ? CH_WEAPON_A : CH_WEAPON_SINGLE), WEP_CVAR_PRI(shotgun, damage) * WEP_CVAR_PRI(shotgun, bullets));
        for(sc = 0;sc < WEP_CVAR_PRI(shotgun, bullets);sc = sc + 1)
                fireBullet(w_shotorg, w_shotdir, WEP_CVAR_PRI(shotgun, spread), WEP_CVAR_PRI(shotgun, solidpenetration), WEP_CVAR_PRI(shotgun, damage), WEP_CVAR_PRI(shotgun, force), WEP_SHOTGUN.m_id, 0);
  
@@@ -181,7 -181,7 +181,7 @@@ void W_Shotgun_Melee_Think(void
  
  void W_Shotgun_Attack2(void)
  {SELFPARAM();
-       sound(self, CH_WEAPON_A, W_Sound("shotgun_melee"), VOL_BASE, ATTEN_NORM);
+       sound(self, CH_WEAPON_A, SND_SHOTGUN_MELEE, VOL_BASE, ATTEN_NORM);
        weapon_thinkf(WFRAME_FIRE2, WEP_CVAR_SEC(shotgun, animtime), w_ready);
  
        entity meleetemp;
@@@ -203,7 -203,7 +203,7 @@@ void W_Shotgun_Attack3_Frame2(
                return;
        }
  
-       sound(self, CH_WEAPON_SINGLE, "misc/null.wav", VOL_BASE, ATTN_NORM); // kill previous sound
+       sound(self, CH_WEAPON_SINGLE, SND_Null, VOL_BASE, ATTN_NORM); // kill previous sound
        W_Shotgun_Attack(true); // actually is secondary, but we trick the last shot into playing full reload sound
        weapon_thinkf(WFRAME_FIRE1, WEP_CVAR_SEC(shotgun, alt_animtime), w_ready);
  }
@@@ -286,9 -286,6 +286,6 @@@ float W_Shotgun(float req
                }
                case WR_INIT:
                {
-                       precache_sound("misc/itempickup.wav");
-                       precache_sound(W_Sound("shotgun_fire"));
-                       precache_sound(W_Sound("shotgun_melee"));
                        SHOTGUN_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(WEP_CVAR_PRI(shotgun, ammo), W_Sound("reload")); // WEAPONTODO
+                       W_Reload(WEP_CVAR_PRI(shotgun, ammo), SND(RELOAD)); // WEAPONTODO
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -359,11 -356,11 +356,11 @@@ float W_Shotgun(float req
                        if(!w_issilent && time - self.prevric > 0.25)
                        {
                                if(w_random < 0.0165)
-                                       sound(self, CH_SHOTS, W_Sound("ric1"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC1, VOL_BASE, ATTEN_NORM);
                                else if(w_random < 0.033)
-                                       sound(self, CH_SHOTS, W_Sound("ric2"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC2, VOL_BASE, ATTEN_NORM);
                                else if(w_random < 0.05)
-                                       sound(self, CH_SHOTS, W_Sound("ric3"), VOL_BASE, ATTEN_NORM);
+                                       sound(self, CH_SHOTS, SND_RIC3, VOL_BASE, ATTEN_NORM);
                                self.prevric = time;
                        }
  
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("ric1"));
-                       precache_sound(W_Sound("ric2"));
-                       precache_sound(W_Sound("ric3"));
                        return true;
                }
                case WR_ZOOMRETICLE:
index edc7079d9aad13d33a0b3ab51e9aafe01754b6e9,d27f99180f2b0964a840944fd6af12dd8622ddb5..8cdeb61accad228365716bf78c1f03baafaa1111
@@@ -55,8 -55,8 +55,8 @@@ VAPORIZER_SETTINGS(WEP_ADD_CVAR, WEP_AD
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_vaporizer(void) { weapon_defaultspawnfunc(WEP_VAPORIZER.m_id); }
 -void spawnfunc_weapon_minstanex(void) { spawnfunc_weapon_vaporizer(); }
 +spawnfunc(weapon_vaporizer) { weapon_defaultspawnfunc(WEP_VAPORIZER.m_id); }
 +spawnfunc(weapon_minstanex) { spawnfunc_weapon_vaporizer(this); }
  
  void W_RocketMinsta_Explosion(vector loc)
  {SELFPARAM();
@@@ -77,7 -77,7 +77,7 @@@ void W_Vaporizer_Attack(void
        W_SetupShot(self, true, 0, "", CH_WEAPON_A, vaporizer_damage);
        // handle sound separately so we can change the volume
        // added bonus: no longer plays the strength sound (strength gives no bonus to instakill anyway)
-       sound (self, CH_WEAPON_A, W_Sound("minstanexfire"), VOL_BASE * 0.8, ATTEN_NORM);
+       sound (self, CH_WEAPON_A, SND_MINSTANEXFIRE, VOL_BASE * 0.8, ATTEN_NORM);
  
        yoda = 0;
        damage_goodhits = 0;
        Send_Effect(EFFECT_VORTEX_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
  
        // teamcolor / hit beam effect
-       vector v;
-       v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
-       switch(self.team)
-       {
-               case NUM_TEAM_1:   // Red
-                       if(damage_goodhits)
-                               Send_Effect(EFFECT_VAPORIZER_RED_HIT, w_shotorg, v, 1);
-                       else
-                               Send_Effect(EFFECT_VAPORIZER_RED, w_shotorg, v, 1);
-                       break;
-               case NUM_TEAM_2:   // Blue
-                       if(damage_goodhits)
-                               Send_Effect(EFFECT_VAPORIZER_BLUE_HIT, w_shotorg, v, 1);
-                       else
-                               Send_Effect(EFFECT_VAPORIZER_BLUE, w_shotorg, v, 1);
-                       break;
-               case NUM_TEAM_3:   // Yellow
-                       if(damage_goodhits)
-                               Send_Effect(EFFECT_VAPORIZER_YELLOW_HIT, w_shotorg, v, 1);
-                       else
-                               Send_Effect(EFFECT_VAPORIZER_YELLOW, w_shotorg, v, 1);
-                       break;
-               case NUM_TEAM_4:   // Pink
-                       if(damage_goodhits)
-                               Send_Effect(EFFECT_VAPORIZER_PINK_HIT, w_shotorg, v, 1);
-                       else
-                               Send_Effect(EFFECT_VAPORIZER_PINK, w_shotorg, v, 1);
-                       break;
-               default:
-                       if(damage_goodhits)
-                               Send_Effect_("TE_TEI_G3_HIT", w_shotorg, v, 1);
-                       else
-                               Send_Effect_("TE_TEI_G3", w_shotorg, v, 1);
-                       break;
-       }
+       vector v = WarpZone_UnTransformOrigin(WarpZone_trace_transform, trace_endpos);
+       Send_Effect((damage_goodhits ? EFFECT_VAPORIZER_HIT(self.team) : EFFECT_VAPORIZER(self.team)), w_shotorg, v, 1);
  
        if(autocvar_g_rm)
        if(!(trace_dphitq3surfaceflags & (Q3SURFACEFLAG_SKY | Q3SURFACEFLAG_NOIMPACT)))
@@@ -174,7 -141,7 +141,7 @@@ void W_RocketMinsta_Attack2(void
  
        float w = self.weapon;
        self.weapon = WEP_ELECTRO.m_id;
-       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, W_Sound("crylink_fire"), CH_WEAPON_A, autocvar_g_rm_laser_damage);
+       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND(CRYLINK_FIRE), CH_WEAPON_A, autocvar_g_rm_laser_damage);
        self.weapon = w;
  
        Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
@@@ -227,7 -194,7 +194,7 @@@ void W_RocketMinsta_Attack3 (void
  
        int w = self.weapon;
        self.weapon = WEP_ELECTRO.m_id;
-       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, W_Sound("electro_fire2"), CH_WEAPON_A, autocvar_g_rm_laser_damage);
+       W_SetupShot_ProjectileSize (self, '0 0 -3', '0 0 -3', false, 2, SND(ELECTRO_FIRE2), CH_WEAPON_A, autocvar_g_rm_laser_damage);
        self.weapon = w;
  
        Send_Effect(EFFECT_ELECTRO_MUZZLEFLASH, w_shotorg, w_shotdir * 1000, 1);
@@@ -362,10 -329,6 +329,6 @@@ float W_Vaporizer(float req
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("minstanexfire"));
-                       precache_sound(W_Sound("nexwhoosh1"));
-                       precache_sound(W_Sound("nexwhoosh2"));
-                       precache_sound(W_Sound("nexwhoosh3"));
                        //W_Blaster(WR_INIT); // Samual: Is this really the proper thing to do? Didn't we already run this previously?
                        VAPORIZER_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                        else
                                used_ammo = vaporizer_ammo;
  
-                       W_Reload(used_ammo, W_Sound("reload"));
+                       W_Reload(used_ammo, SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -434,19 -397,17 +397,17 @@@ float W_Vaporizer(float req
                        if(w_deathtype & HITTYPE_SECONDARY)
                        {
                                pointparticles(particleeffectnum(EFFECT_BLASTER_IMPACT), org2, w_backoff * 1000, 1);
-                               if(!w_issilent) { sound(self, CH_SHOTS, W_Sound("laserimpact"), VOL_BASE, ATTN_NORM); }
+                               if(!w_issilent) { sound(self, CH_SHOTS, SND_LASERIMPACT, VOL_BASE, ATTN_NORM); }
                        }
                        else
                        {
                                pointparticles(particleeffectnum(EFFECT_VORTEX_IMPACT), org2, '0 0 0', 1);
-                               if(!w_issilent) { sound(self, CH_SHOTS, W_Sound("neximpact"), VOL_BASE, ATTN_NORM); }
+                               if(!w_issilent) { sound(self, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM); }
                        }
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("laserimpact"));
-                       precache_sound(W_Sound("neximpact"));
                        if(autocvar_cl_reticle && autocvar_cl_reticle_weapon)
                        {
                                precache_pic("gfx/reticle_nex");
index 5e7cc479c267047e938e34dc8d738960f2a97397,8584b8ab91147db1932d3648ff354e22e685348d..8238ac22c83d87b9e7ab70242921185753bbe5bd
@@@ -59,8 -59,8 +59,8 @@@ VORTEX_SETTINGS(WEP_ADD_CVAR, WEP_ADD_P
  #endif
  #ifdef IMPLEMENTATION
  #ifdef SVQC
 -void spawnfunc_weapon_vortex(void) { weapon_defaultspawnfunc(WEP_VORTEX.m_id); }
 -void spawnfunc_weapon_nex(void) { spawnfunc_weapon_vortex(); }
 +spawnfunc(weapon_vortex) { weapon_defaultspawnfunc(WEP_VORTEX.m_id); }
 +spawnfunc(weapon_nex) { spawnfunc_weapon_vortex(this); }
  
  void SendCSQCVortexBeamParticle(float charge) {
        vector v;
@@@ -103,10 -103,10 +103,10 @@@ void W_Vortex_Attack(float issecondary
        mydmg *= charge;
        myforce *= charge;
  
-       W_SetupShot(self, true, 5, W_Sound("nexfire"), CH_WEAPON_A, mydmg);
+       W_SetupShot(self, true, 5, SND(NEXFIRE), CH_WEAPON_A, mydmg);
        if(charge > WEP_CVAR(vortex, charge_animlimit) && WEP_CVAR(vortex, charge_animlimit)) // if the Vortex is overcharged, we play an extra sound
        {
-               sound(self, CH_WEAPON_B, W_Sound("nexcharge"), VOL_BASE * (charge - 0.5 * WEP_CVAR(vortex, charge_animlimit)) / (1 - 0.5 * WEP_CVAR(vortex, charge_animlimit)), ATTN_NORM);
+               sound(self, CH_WEAPON_B, SND_NEXCHARGE, VOL_BASE * (charge - 0.5 * WEP_CVAR(vortex, charge_animlimit)) / (1 - 0.5 * WEP_CVAR(vortex, charge_animlimit)), ATTN_NORM);
        }
  
        yoda = 0;
        W_DecreaseAmmo(myammo);
  }
  
 -void spawnfunc_weapon_vortex(void); // defined in t_items.qc
 +spawnfunc(weapon_vortex); // defined in t_items.qc
  
  .float vortex_chargepool_pauseregen_finished;
  bool W_Vortex(int req)
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("nexfire"));
-                       precache_sound(W_Sound("nexcharge"));
-                       precache_sound(W_Sound("nexwhoosh1"));
-                       precache_sound(W_Sound("nexwhoosh2"));
-                       precache_sound(W_Sound("nexwhoosh3"));
                        VORTEX_SETTINGS(WEP_SKIP_CVAR, WEP_SET_PROP);
                        return true;
                }
                }
                case WR_RELOAD:
                {
-                       W_Reload(min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), W_Sound("reload"));
+                       W_Reload(min(WEP_CVAR_PRI(vortex, ammo), WEP_CVAR_SEC(vortex, ammo)), SND(RELOAD));
                        return true;
                }
                case WR_SUICIDEMESSAGE:
@@@ -325,13 -320,12 +320,12 @@@ bool W_Vortex(int req
                        org2 = w_org + w_backoff * 6;
                        pointparticles(particleeffectnum(EFFECT_VORTEX_IMPACT), org2, '0 0 0', 1);
                        if(!w_issilent)
-                               sound(self, CH_SHOTS, W_Sound("neximpact"), VOL_BASE, ATTN_NORM);
+                               sound(self, CH_SHOTS, SND_NEXIMPACT, VOL_BASE, ATTN_NORM);
  
                        return true;
                }
                case WR_INIT:
                {
-                       precache_sound(W_Sound("neximpact"));
                        if(autocvar_cl_reticle && autocvar_cl_reticle_weapon)
                        {
                                precache_pic("gfx/reticle_nex");
diff --combined qcsrc/lib/_all.inc
index 2b15e8acb4b0d60f5e5457953aca656295e1716c,cda9b3a8804e3a3ac6b7f13cf815036c528c9ea3..e7ee2746f553f5e06dbec8c491ca1982ad0e479c
@@@ -7,6 -7,7 +7,7 @@@
  #include "cvar.qh"
  #include "defer.qh"
  #include "draw.qh"
+ #include "file.qh"
  #include "i18n.qh"
  #include "lazy.qh"
  #include "log.qh"
@@@ -19,8 -20,8 +20,9 @@@
  #include "prandom.qc"
  #include "progname.qh"
  #include "registry.qh"
+ #include "replicate.qh"
  #include "sortlist.qc"
 +#include "spawnfunc.qh"
  #include "static.qh"
  #include "string.qh"
  #include "struct.qh"
diff --combined qcsrc/server/cheats.qc
index 0721d05fc20f76d97e881a3508ea3b4a2e9ee11e,361afadee6d1dce14f016c3022f8ac06425046c1..9912174dd8d17a5a024fd8ac9e77f5340e839b49
@@@ -129,8 -129,8 +129,8 @@@ void info_autoscreenshot_findtarget(
        self.angles_y = a.y;
        // we leave Rick Roll alone
  }
 -void spawnfunc_info_autoscreenshot()
 -{SELFPARAM();
 +spawnfunc(info_autoscreenshot)
 +{
        if(++num_autoscreenshot > autocvar_g_max_info_autoscreenshot)
        {
                objerror("Too many info_autoscreenshot entitites. FAIL!");
@@@ -283,7 -283,7 +283,7 @@@ float CheatImpulse(float i
                                e = self;
  
                        Send_Effect(EFFECT_ROCKET_EXPLODE, e.origin, '0 0 0', 1);
-                       sound(e, CH_SHOTS, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+                       sound(e, CH_SHOTS, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
  
                        e2 = spawn();
                        setorigin(e2, e.origin);
@@@ -372,7 -372,7 +372,7 @@@ float CheatCommand(float argc
                                                e.angles = fixedvectoangles2(trace_plane_normal, v_forward);
                                                e.angles = AnglesTransform_ApplyToAngles(e.angles, '-90 0 0'); // so unrotated models work
                                        }
 -                                      WITH(entity, self, e, spawnfunc_func_breakable());
 +                                      WITH(entity, self, e, spawnfunc_func_breakable(e));
                                        // now, is it valid?
                                        if(f == 0)
                                        {
diff --combined qcsrc/server/defs.qh
index 82d6e7b6bc14647d7a94cd17604cc78e7c093f6b,02e80845b778c91fb58ed24b1f4ab26674cb39ef..723b137a1366c54d7480eea6a8ee1523ced2ca1e
@@@ -5,6 -5,8 +5,6 @@@
  
  #define INDEPENDENT_ATTACK_FINISHED
  
 -noref float require_spawnfunc_prefix; // if this float exists, only functions with spawnfunc_ name prefix qualify as spawn functions
 -
  #define BUTTON_ATCK       button0
  #define BUTTON_JUMP       button2
  #define BUTTON_ATCK2      button3
@@@ -145,7 -147,9 +145,9 @@@ const float MAX_DAMAGEEXTRARADIUS = 16
  .float pauserothealth_finished;
  .float pauserotarmor_finished;
  .float pauserotfuel_finished;
+ // string overrides entity
  .string item_pickupsound;
+ .entity item_pickupsound_ent;
  
  // definitions for weaponsystem
  // more WEAPONTODO: move these to their proper files
diff --combined qcsrc/server/g_world.qc
index 635b0d8e8fd0ae9071a18f347d1c1798a801929b,e17e7adbcff7dd162f345a89a84e2b0b4e9bf8ad..53990fb21392f0b22c64d91ab93e8cc49e39e526
@@@ -534,8 -534,8 +534,8 @@@ void RandomSeed_Spawn(
        WITH(entity, self, randomseed, randomseed.think()); // sets random seed and nextthink
  }
  
 -void spawnfunc___init_dedicated_server(void)
 -{SELFPARAM();
 +spawnfunc(__init_dedicated_server)
 +{
        // handler for _init/_init map (only for dedicated server initialization)
  
        world_initialized = -1; // don't complain
@@@ -572,8 -572,8 +572,8 @@@ void ClientInit_Spawn()
  void WeaponStats_Init();
  void WeaponStats_Shutdown();
  void Physics_AddStats();
 -void spawnfunc_worldspawn (void)
 -{SELFPARAM();
 +spawnfunc(worldspawn)
 +{
        float fd, l, j, n;
        string s;
  
        CALL_ACCUMULATED_FUNCTION(RegisterNotifications);
        CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes);
  
-       initialize_minigames();
        ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid));
  
        TemporaryDB = db_create();
        world_initialized = 1;
  }
  
 -void spawnfunc_light (void)
 -{SELFPARAM();
 +spawnfunc(light)
 +{
        //makestatic (self); // Who the f___ did that?
        remove(self);
  }
diff --combined qcsrc/server/item_key.qc
index f25879c8828fd4ca04144728153242c5395dac66,780607871fe96173d15cab6759579deae08c86db..713fbf6c3df57e87a8c704e7916da1ba11e562b0
@@@ -148,8 -148,8 +148,8 @@@ This is the only correct way to put key
  
  itemkeys MUST always have exactly one bit set.
  */
 -void spawnfunc_item_key()
 -{SELFPARAM();
 +spawnfunc(item_key)
 +{
        string _netname;
        vector _colormod;
  
                self.message = strzone(strcat("You've picked up the ", self.netname, "!"));
  
        if (self.noise == "")
-               self.noise = "misc/itempickup.wav";
+               self.noise = SND(ITEMPICKUP);
  
        // save the name for later
        item_keys_names[lowestbit(self.itemkeys)] = self.netname;
@@@ -255,11 -255,11 +255,11 @@@ FLOATING: the item will float in air, i
  ---------NOTES----------
  Don't use this entity on new maps! Use item_key instead.
  */
 -void spawnfunc_item_key1(void)
 -{SELFPARAM();
 -      self.classname = "item_key";
 -      self.itemkeys = ITEM_KEY_BIT(1);
 -      spawnfunc_item_key();
 +spawnfunc(item_key1)
 +{
 +      this.classname = "item_key";
 +      this.itemkeys = ITEM_KEY_BIT(1);
 +      spawnfunc_item_key(this);
  };
  
  /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32) FLOATING
@@@ -274,9 -274,9 +274,9 @@@ FLOATING: the item will float in air, i
  ---------NOTES----------
  Don't use this entity on new maps! Use item_key instead.
  */
 -void spawnfunc_item_key2(void)
 -{SELFPARAM();
 -      self.classname = "item_key";
 -      self.itemkeys = ITEM_KEY_BIT(0);
 -      spawnfunc_item_key();
 +spawnfunc(item_key2)
 +{
 +      this.classname = "item_key";
 +      this.itemkeys = ITEM_KEY_BIT(0);
 +      spawnfunc_item_key(this);
  };
index db93a4321d53ad107a8a8a5a725ce61237332889,c0dd9b84ebe8c391c458329bd4f5b90c9099effb..108b8dda6f369b10163cdc376d968e90e6d65a49
@@@ -239,7 -239,7 +239,7 @@@ void ctf_Handle_Drop(entity flag, entit
  
        // messages and sounds
        Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_LOST_) : INFO_CTF_LOST_NEUTRAL), player.netname);
-       sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
+       _sound(flag, CH_TRIGGER, flag.snd_flag_dropped, VOL_BASE, ATTEN_NONE);
        ctf_EventLog("dropped", player.team, player);
  
        // scoring
@@@ -296,7 -296,7 +296,7 @@@ void ctf_Handle_Retrieve(entity flag, e
        flag.ctf_status = FLAG_CARRY;
  
        // messages and sounds
-       sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
+       _sound(player, CH_TRIGGER, flag.snd_flag_pass, VOL_BASE, ATTEN_NORM);
        ctf_EventLog("receive", flag.team, player);
  
        FOR_EACH_REALPLAYER(tmp_player)
@@@ -363,7 -363,7 +363,7 @@@ void ctf_Handle_Throw(entity player, en
                        flag.ctf_status = FLAG_PASSING;
  
                        // other
-                       sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
+                       _sound(player, CH_TRIGGER, flag.snd_flag_touch, VOL_BASE, ATTEN_NORM);
                        WarpZone_TrailParticles(world, _particleeffectnum(flag.passeffect), player.origin, targ_origin);
                        ctf_EventLog("pass", flag.team, player);
                        break;
@@@ -436,7 -436,7 +436,7 @@@ void ctf_Handle_Capture(entity flag, en
        // messages and sounds
        Send_Notification(NOTIF_ONE, player, MSG_CENTER, ((enemy_flag.team) ? APP_TEAM_ENT_4(enemy_flag, CENTER_CTF_CAPTURE_) : CENTER_CTF_CAPTURE_NEUTRAL));
        ctf_CaptureRecord(enemy_flag, player);
-       sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE);
+       _sound(player, CH_TRIGGER, ((ctf_oneflag) ? player_team_flag.snd_flag_capture : ((DIFF_TEAM(player, flag)) ? enemy_flag.snd_flag_capture : flag.snd_flag_capture)), VOL_BASE, ATTEN_NONE);
  
        switch(capturetype)
        {
@@@ -485,7 -485,7 +485,7 @@@ void ctf_Handle_Return(entity flag, ent
                Send_Notification(NOTIF_ONE, player, MSG_CENTER, APP_TEAM_ENT_4(flag, CENTER_CTF_RETURN_));
                Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(flag, INFO_CTF_RETURN_), player.netname);
        }
-       sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE);
+       _sound(player, CH_TRIGGER, flag.snd_flag_returned, VOL_BASE, ATTEN_NONE);
        ctf_EventLog("return", flag.team, player);
  
        // scoring
@@@ -573,7 -573,7 +573,7 @@@ void ctf_Handle_Pickup(entity flag, ent
        else
                Send_Notification(NOTIF_ONE, tmp_entity, MSG_CHOICE, ((SAME_TEAM(flag, player)) ? CHOICE_CTF_PICKUP_ENEMY_TEAM : CHOICE_CTF_PICKUP_ENEMY), Team_ColorCode(player.team), player.netname);
  
-       sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
+       _sound(player, CH_TRIGGER, flag.snd_flag_taken, VOL_BASE, ATTEN_NONE);
  
        // scoring
        PlayerScore_Add(player, SP_CTF_PICKUPS, 1);
@@@ -641,7 -641,7 +641,7 @@@ void ctf_CheckFlagReturn(entity flag, i
                                case RETURN_TIMEOUT:
                                        { Send_Notification(NOTIF_ALL, world, MSG_INFO, ((flag.team) ? APP_TEAM_ENT_4(flag, INFO_CTF_FLAGRETURN_TIMEOUT_) : INFO_CTF_FLAGRETURN_TIMEOUT_NEUTRAL)); break; }
                        }
-                       sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
+                       _sound(flag, CH_TRIGGER, flag.snd_flag_respawn, VOL_BASE, ATTEN_NONE);
                        ctf_EventLog("returned", flag.team, world);
                        ctf_RespawnFlag(flag);
                }
@@@ -941,7 -941,7 +941,7 @@@ void ctf_FlagTouch(
                if(time > self.wait) // if we haven't in a while, play a sound/effect
                {
                        Send_Effect_(self.toucheffect, self.origin, '0 0 0', 1);
-                       sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
+                       _sound(self, CH_TRIGGER, self.snd_flag_touch, VOL_BASE, ATTEN_NORM);
                        self.wait = time + FLAG_TOUCHRATE;
                }
                return;
@@@ -1091,7 -1091,6 +1091,6 @@@ void set_flag_string(entity flag, .stri
  void ctf_FlagSetup(int teamnumber, entity flag) // called when spawning a flag entity on the map as a spawnfunc
  {SELFPARAM();
        // declarations
-       string teamname = Static_Team_ColorName_Lower(teamnumber);
        setself(flag); // for later usage with droptofloor()
  
        // main setup
        flag.nextthink = time + FLAG_THINKRATE;
        flag.ctf_status = FLAG_BASE;
  
+       string teamname = Static_Team_ColorName_Lower(teamnumber);
        // appearence
        if(!flag.scale)                         { flag.scale = FLAG_SCALE; }
        if(flag.skin == 0)                      { flag.skin = cvar(sprintf("g_ctf_flag_%s_skin", teamname)); }
        set_flag_string(flag, capeffect,        "%s_cap",               teamname);
  
        // sounds
-       set_flag_string(flag, snd_flag_taken,           "ctf/%s_taken.wav",     teamname);
-       set_flag_string(flag, snd_flag_returned,        "ctf/%s_returned.wav",  teamname);
-       set_flag_string(flag, snd_flag_capture,         "ctf/%s_capture.wav",   teamname);
-       set_flag_string(flag, snd_flag_dropped,         "ctf/%s_dropped.wav",   teamname);
-       if(flag.snd_flag_respawn == "")         { flag.snd_flag_respawn = "ctf/flag_respawn.wav"; } // if there is ever a team-based sound for this, update the code to match.
-       if(flag.snd_flag_touch == "")           { flag.snd_flag_touch = "ctf/touch.wav"; } // again has no team-based sound
-       if(flag.snd_flag_pass == "")            { flag.snd_flag_pass = "ctf/pass.wav"; } // same story here
-       // precache
-       precache_sound(flag.snd_flag_taken);
-       precache_sound(flag.snd_flag_returned);
-       precache_sound(flag.snd_flag_capture);
+       flag.snd_flag_taken = SND(CTF_TAKEN(teamnumber));
+       flag.snd_flag_returned = SND(CTF_RETURNED(teamnumber));
+       flag.snd_flag_capture = SND(CTF_CAPTURE(teamnumber));
+       flag.snd_flag_dropped = SND(CTF_DROPPED(teamnumber));
+       if (flag.snd_flag_respawn == "") flag.snd_flag_respawn = SND(CTF_RESPAWN); // if there is ever a team-based sound for this, update the code to match.
        precache_sound(flag.snd_flag_respawn);
-       precache_sound(flag.snd_flag_dropped);
+       if (flag.snd_flag_touch == "") flag.snd_flag_touch = SND(CTF_TOUCH); // again has no team-based sound
        precache_sound(flag.snd_flag_touch);
+       if (flag.snd_flag_pass == "") flag.snd_flag_pass = SND(CTF_PASS); // same story here
        precache_sound(flag.snd_flag_pass);
+       // precache
        precache_model(flag.model);
  
        // appearence
@@@ -2251,8 -2247,8 +2247,8 @@@ Keys
  "noise3" sound played when flag is lost in the field and respawns itself...
  "noise4" sound played when flag is dropped by a player...
  "noise5" sound played when flag touches the ground... */
 -void spawnfunc_item_flag_team1()
 -{SELFPARAM();
 +spawnfunc(item_flag_team1)
 +{
        if(!g_ctf) { remove(self); return; }
  
        ctf_FlagSetup(NUM_TEAM_1, self);
@@@ -2269,8 -2265,8 +2265,8 @@@ Keys
  "noise3" sound played when flag is lost in the field and respawns itself...
  "noise4" sound played when flag is dropped by a player...
  "noise5" sound played when flag touches the ground... */
 -void spawnfunc_item_flag_team2()
 -{SELFPARAM();
 +spawnfunc(item_flag_team2)
 +{
        if(!g_ctf) { remove(self); return; }
  
        ctf_FlagSetup(NUM_TEAM_2, self);
@@@ -2287,8 -2283,8 +2283,8 @@@ Keys
  "noise3" sound played when flag is lost in the field and respawns itself...
  "noise4" sound played when flag is dropped by a player...
  "noise5" sound played when flag touches the ground... */
 -void spawnfunc_item_flag_team3()
 -{SELFPARAM();
 +spawnfunc(item_flag_team3)
 +{
        if(!g_ctf) { remove(self); return; }
  
        ctf_FlagSetup(NUM_TEAM_3, self);
@@@ -2305,8 -2301,8 +2301,8 @@@ Keys
  "noise3" sound played when flag is lost in the field and respawns itself...
  "noise4" sound played when flag is dropped by a player...
  "noise5" sound played when flag touches the ground... */
 -void spawnfunc_item_flag_team4()
 -{SELFPARAM();
 +spawnfunc(item_flag_team4)
 +{
        if(!g_ctf) { remove(self); return; }
  
        ctf_FlagSetup(NUM_TEAM_4, self);
@@@ -2323,8 -2319,8 +2319,8 @@@ Keys
  "noise3" sound played when flag is lost in the field and respawns itself...
  "noise4" sound played when flag is dropped by a player...
  "noise5" sound played when flag touches the ground... */
 -void spawnfunc_item_flag_neutral()
 -{SELFPARAM();
 +spawnfunc(item_flag_neutral)
 +{
        if(!g_ctf) { remove(self); return; }
        if(!cvar("g_ctf_oneflag")) { remove(self); return; }
  
@@@ -2337,8 -2333,8 +2333,8 @@@ Note: If you use spawnfunc_ctf_team ent
  Keys:
  "netname" Name of the team (for example Red, Blue, Green, Yellow, Life, Death, Offense, Defense, etc)...
  "cnt" Scoreboard color of the team (for example 4 is red and 13 is blue)... */
 -void spawnfunc_ctf_team()
 -{SELFPARAM();
 +spawnfunc(ctf_team)
 +{
        if(!g_ctf) { remove(self); return; }
  
        self.classname = "ctf_team";
  }
  
  // compatibility for quake maps
 -void spawnfunc_team_CTF_redflag()    { spawnfunc_item_flag_team1();    }
 -void spawnfunc_team_CTF_blueflag()   { spawnfunc_item_flag_team2();    }
 -void spawnfunc_team_CTF_redplayer()  { spawnfunc_info_player_team1();  }
 -void spawnfunc_team_CTF_blueplayer() { spawnfunc_info_player_team2();  }
 -void spawnfunc_team_CTF_redspawn()   { spawnfunc_info_player_team1();  }
 -void spawnfunc_team_CTF_bluespawn()  { spawnfunc_info_player_team2();  }
 +spawnfunc(team_CTF_redflag)    { spawnfunc_item_flag_team1(this);    }
 +spawnfunc(team_CTF_blueflag)   { spawnfunc_item_flag_team2(this);    }
 +spawnfunc(team_CTF_redplayer)  { spawnfunc_info_player_team1(this);  }
 +spawnfunc(team_CTF_blueplayer) { spawnfunc_info_player_team2(this);  }
 +spawnfunc(team_CTF_redspawn)   { spawnfunc_info_player_team1(this);  }
 +spawnfunc(team_CTF_bluespawn)  { spawnfunc_info_player_team2(this);  }
  
 -void team_CTF_neutralflag()                    { spawnfunc_item_flag_neutral();  }
 -void team_neutralobelisk()                     { spawnfunc_item_flag_neutral();  }
 +void team_CTF_neutralflag()                    { SELFPARAM(); spawnfunc_item_flag_neutral(self);  }
 +void team_neutralobelisk()                     { SELFPARAM(); spawnfunc_item_flag_neutral(self);  }
  
  
  // ==============
@@@ -2378,12 -2374,15 +2374,12 @@@ void ctf_ScoreRules(int teams
  
  // code from here on is just to support maps that don't have flag and team entities
  void ctf_SpawnTeam (string teamname, int teamcolor)
 -{SELFPARAM();
 -      setself(spawn());
 -      self.classname = "ctf_team";
 -      self.netname = teamname;
 -      self.cnt = teamcolor;
 -
 -      spawnfunc_ctf_team();
 -
 -      setself(this);
 +{
 +      entity this = new(ctf_team);
 +      this.netname = teamname;
 +      this.cnt = teamcolor;
 +      this.spawnfunc_checked = true;
 +      WITH(entity, self, this, spawnfunc_ctf_team(this));
  }
  
  void ctf_DelayedInit() // Do this check with a delay so we can wait for teams to be set up.
index 50d644836c46cc9a865fbaef32cc75168cd893aa,66f4c8da316fafdfda252ca9ec48203d9d5baf33..34b2875105a6f404588ad6d05477c2920230c369
@@@ -61,9 -61,9 +61,9 @@@ void dompoint_captured (
  
        if (head.noise != "")
                if(self.enemy)
-                       sound(self.enemy, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
+                       _sound(self.enemy, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
                else
-                       sound(self, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
+                       _sound(self, CH_TRIGGER, head.noise, VOL_BASE, ATTEN_NORM);
        if (head.noise1 != "")
                play2all(head.noise1);
  
@@@ -447,8 -447,8 +447,8 @@@ MUTATOR_HOOKFUNCTION(dom_BotRoles
  /*QUAKED spawnfunc_dom_controlpoint (0 .5 .8) (-16 -16 -24) (16 16 32)
  Control point for Domination gameplay.
  */
 -void spawnfunc_dom_controlpoint()
 -{SELFPARAM();
 +spawnfunc(dom_controlpoint)
 +{
        if(!g_domination)
        {
                remove(self);
@@@ -492,8 -492,8 +492,8 @@@ Keys
   (this is a global sound, like "Red team has captured a control point")
  */
  
 -void spawnfunc_dom_team()
 -{SELFPARAM();
 +spawnfunc(dom_team)
 +{
        if(!g_domination || autocvar_g_domination_teams_override >= 2)
        {
                remove(self);
@@@ -567,27 -567,26 +567,27 @@@ void dom_spawnteam (string teamname, fl
        setself(this);
  }
  
 +void _spawnfunc_dom_controlpoint() { SELFPARAM(); spawnfunc_dom_controlpoint(self); }
  void dom_spawnpoint(vector org)
  {SELFPARAM();
        setself(spawn());
        self.classname = "dom_controlpoint";
 -      self.think = spawnfunc_dom_controlpoint;
 +      self.think = _spawnfunc_dom_controlpoint;
        self.nextthink = time;
        setorigin(self, org);
 -      spawnfunc_dom_controlpoint();
 +      spawnfunc_dom_controlpoint(this);
        setself(this);
  }
  
  // spawn some default teams if the map is not set up for domination
  void dom_spawnteams(float teams)
  {
-       dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, "domination/claim.wav", "", "Red team has captured a control point");
-       dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, "domination/claim.wav", "", "Blue team has captured a control point");
+       dom_spawnteam("Red", NUM_TEAM_1-1, "models/domination/dom_red.md3", 0, SND(DOM_CLAIM), "", "Red team has captured a control point");
+       dom_spawnteam("Blue", NUM_TEAM_2-1, "models/domination/dom_blue.md3", 0, SND(DOM_CLAIM), "", "Blue team has captured a control point");
        if(teams >= 3)
-               dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, "domination/claim.wav", "", "Yellow team has captured a control point");
+               dom_spawnteam("Yellow", NUM_TEAM_3-1, "models/domination/dom_yellow.md3", 0, SND(DOM_CLAIM), "", "Yellow team has captured a control point");
        if(teams >= 4)
-               dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, "domination/claim.wav", "", "Pink team has captured a control point");
+               dom_spawnteam("Pink", NUM_TEAM_4-1, "models/domination/dom_pink.md3", 0, SND(DOM_CLAIM), "", "Pink team has captured a control point");
        dom_spawnteam("", 0, "models/domination/dom_unclaimed.md3", 0, "", "", "");
  }
  
@@@ -623,8 -622,6 +623,6 @@@ void dom_DelayedInit() // Do this chec
  
  void dom_Initialize()
  {
-       precache_sound("domination/claim.wav");
        InitializeEntity(world, dom_DelayedInit, INITPRIO_GAMETYPE);
  }
  
index 0227f96875cb3ce35a1939f09c92cf15016c7625,a318748fda952e97f28aebe85c4b9977e82a8a22..3675831acc915ff9961e7eba121a77230707acf9
@@@ -207,7 -207,7 +207,7 @@@ void InitBall(void
        self.teamtime = 0;
        self.pusher = world;
        self.team = false;
-       sound(self, CH_TRIGGER, self.noise1, VOL_BASE, ATTEN_NORM);
+       _sound(self, CH_TRIGGER, self.noise1, VOL_BASE, ATTEN_NORM);
        WaypointSprite_Ping(self.waypointsprite_attachedforcarrier);
        LogNB("init", world);
  }
@@@ -254,7 -254,7 +254,7 @@@ void football_touch(void
        {
                if(time > self.lastground + 0.1)
                {
-                       sound(self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+                       _sound(self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
                        self.lastground = time;
                }
                if(vlen(self.velocity) && !self.cnt)
@@@ -310,7 -310,7 +310,7 @@@ void basketball_touch(void
        }
        else if(other.solid == SOLID_BSP)
        {
-               sound(self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
+               _sound(self, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NORM);
                if(vlen(self.velocity) && !self.cnt)
                        self.nextthink = min(time + autocvar_g_nexball_delay_idle, self.teamtime);
        }
@@@ -376,7 -376,7 +376,7 @@@ void GoalTouch(void
                pscore = 1;
        }
  
-       sound(ball, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NONE);
+       _sound(ball, CH_TRIGGER, self.noise, VOL_BASE, ATTEN_NONE);
  
        if(ball.team && pscore)
        {
  //=======================//
  //       team ents       //
  //=======================//
 -void spawnfunc_nexball_team(void)
 -{SELFPARAM();
 +spawnfunc(nexball_team)
 +{
        if(!g_nexball)
        {
                remove(self);
@@@ -515,13 -515,13 +515,13 @@@ void SpawnBall(void
        if(!autocvar_g_nexball_sound_bounce)
                self.noise = "";
        else if(self.noise == "")
-               self.noise = "sound/nexball/bounce.wav";
+               self.noise = SND(NB_BOUNCE);
        //bounce sound placeholder (FIXME)
        if(self.noise1 == "")
-               self.noise1 = "sound/nexball/drop.wav";
+               self.noise1 = SND(NB_DROP);
        //ball drop sound placeholder (FIXME)
        if(self.noise2 == "")
-               self.noise2 = "sound/nexball/steal.wav";
+               self.noise2 = SND(NB_STEAL);
        //stealing sound placeholder (FIXME)
        if(self.noise) precache_sound(self.noise);
        precache_sound(self.noise1);
        self.nextthink = game_starttime + autocvar_g_nexball_delay_start;
  }
  
 -void spawnfunc_nexball_basketball(void)
 -{SELFPARAM();
 +spawnfunc(nexball_basketball)
 +{
        nexball_mode |= NBM_BASKETBALL;
        self.classname = "nexball_basketball";
        if (!(balls & BALL_BASKET))
        SpawnBall();
  }
  
 -void spawnfunc_nexball_football(void)
 -{SELFPARAM();
 +spawnfunc(nexball_football)
 +{
        nexball_mode |= NBM_FOOTBALL;
        self.classname = "nexball_football";
        self.solid = SOLID_TRIGGER;
@@@ -598,40 -598,40 +598,40 @@@ void SpawnGoal(void
        self.touch = GoalTouch;
  }
  
 -void spawnfunc_nexball_redgoal(void)
 -{SELFPARAM();
 +spawnfunc(nexball_redgoal)
 +{
        self.team = NUM_TEAM_1;
        SpawnGoal();
  }
 -void spawnfunc_nexball_bluegoal(void)
 -{SELFPARAM();
 +spawnfunc(nexball_bluegoal)
 +{
        self.team = NUM_TEAM_2;
        SpawnGoal();
  }
 -void spawnfunc_nexball_yellowgoal(void)
 -{SELFPARAM();
 +spawnfunc(nexball_yellowgoal)
 +{
        self.team = NUM_TEAM_3;
        SpawnGoal();
  }
 -void spawnfunc_nexball_pinkgoal(void)
 -{SELFPARAM();
 +spawnfunc(nexball_pinkgoal)
 +{
        self.team = NUM_TEAM_4;
        SpawnGoal();
  }
  
 -void spawnfunc_nexball_fault(void)
 -{SELFPARAM();
 +spawnfunc(nexball_fault)
 +{
        self.team = GOAL_FAULT;
        if(self.noise == "")
-               self.noise = "misc/typehit.wav";
+               self.noise = SND(TYPEHIT);
        SpawnGoal();
  }
  
 -void spawnfunc_nexball_out(void)
 -{SELFPARAM();
 +spawnfunc(nexball_out)
 +{
        self.team = GOAL_OUT;
        if(self.noise == "")
-               self.noise = "misc/typehit.wav";
+               self.noise = SND(TYPEHIT);
        SpawnGoal();
  }
  
  //Spawnfuncs preserved for compatibility
  //
  
 -void spawnfunc_ball(void)
 +spawnfunc(ball)
  {
 -      spawnfunc_nexball_football();
 +      spawnfunc_nexball_football(this);
  }
 -void spawnfunc_ball_football(void)
 +spawnfunc(ball_football)
  {
 -      spawnfunc_nexball_football();
 +      spawnfunc_nexball_football(this);
  }
 -void spawnfunc_ball_basketball(void)
 +spawnfunc(ball_basketball)
  {
 -      spawnfunc_nexball_basketball();
 +      spawnfunc_nexball_basketball(this);
  }
  // The "red goal" is defended by blue team. A ball in there counts as a point for red.
 -void spawnfunc_ball_redgoal(void)
 +spawnfunc(ball_redgoal)
  {
 -      spawnfunc_nexball_bluegoal();   // I blame Revenant
 +      spawnfunc_nexball_bluegoal(this);       // I blame Revenant
  }
 -void spawnfunc_ball_bluegoal(void)
 +spawnfunc(ball_bluegoal)
  {
 -      spawnfunc_nexball_redgoal();    // but he didn't mean to cause trouble :p
 +      spawnfunc_nexball_redgoal(this);        // but he didn't mean to cause trouble :p
  }
 -void spawnfunc_ball_fault(void)
 +spawnfunc(ball_fault)
  {
 -      spawnfunc_nexball_fault();
 +      spawnfunc_nexball_fault(this);
  }
 -void spawnfunc_ball_bound(void)
 +spawnfunc(ball_bound)
  {
 -      spawnfunc_nexball_out();
 +      spawnfunc_nexball_out(this);
  }
  
  //=======================//
@@@ -705,7 -705,7 +705,7 @@@ void W_Nexball_Touch(void
                        if(!attacker.ballcarried)
                        {
                                LogNB("stole", attacker);
-                               sound(other, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
+                               _sound(other, CH_TRIGGER, ball.noise2, VOL_BASE, ATTEN_NORM);
  
                                if(SAME_TEAM(attacker, other) && time > attacker.teamkill_complain)
                                {
@@@ -727,7 -727,7 +727,7 @@@ void W_Nexball_Attack(float t
        if(!(ball = self.ballcarried))
                return;
  
-       W_SetupShot(self, false, 4, "nexball/shoot1.wav", CH_WEAPON_A, 0);
+       W_SetupShot(self, false, 4, SND(NB_SHOOT1), CH_WEAPON_A, 0);
        tracebox(w_shotorg, BALL_MINS, BALL_MAXS, w_shotorg, MOVE_WORLDONLY, world);
        if(trace_startsolid)
        {
@@@ -761,7 -761,7 +761,7 @@@ void W_Nexball_Attack2(void
        if(self.ballcarried.enemy)
        {
                entity _ball = self.ballcarried;
-               W_SetupShot(self, false, 4, "nexball/shoot1.wav", CH_WEAPON_A, 0);
+               W_SetupShot(self, false, 4, SND(NB_SHOOT1), CH_WEAPON_A, 0);
                DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32));
                _ball.think = W_Nexball_Think;
                _ball.nextthink = time;
        entity missile;
        if(!(balls & BALL_BASKET))
                return;
-       W_SetupShot(self, false, 2, "nexball/shoot2.wav", CH_WEAPON_A, 0);
+       W_SetupShot(self, false, 2, SND(NB_SHOOT2), CH_WEAPON_A, 0);
        missile = spawn();
  
        missile.owner = self;
@@@ -860,9 -860,6 +860,6 @@@ float w_nexball_weapon(float req
        }
        else if(req == WR_INIT)
        {
-               precache_sound("nexball/shoot1.wav");
-               precache_sound("nexball/shoot2.wav");
-               precache_sound("misc/typehit.wav");
        }
        else if(req == WR_SETUP)
        {
index 9d88f70698796e6928de7890f56388bf2a9c8440,32dcaf556f4df867df989a757bfc0e634032b470..35a8e7bdc76c92f9eb04356f197c02b73d762cbe
@@@ -31,7 -31,7 +31,7 @@@ void ons_CaptureShield_Touch(
  
        if(IS_REAL_CLIENT(other))
        {
-               play2(other, "onslaught/damageblockedbyshield.wav");
+               play2(other, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
  
                if(self.enemy.classname == "onslaught_generator")
                        Send_Notification(NOTIF_ONE, other, MSG_CENTER, CENTER_ONS_GENERATOR_SHIELDED);
@@@ -353,7 -353,7 +353,7 @@@ void ons_ControlPoint_Icon_Damage(entit
                if (time > self.pain_finished)
                        if (IS_PLAYER(attacker))
                        {
-                               play2(attacker, "onslaught/damageblockedbyshield.wav");
+                               play2(attacker, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
                                self.pain_finished = time + 1;
                                attacker.typehitsound += 1; // play both sounds (shield is way too quiet)
                        }
        if(IS_PLAYER(attacker))
        if(time - ons_notification_time[self.team] > 10)
        {
-               play2team(self.team, "onslaught/controlpoint_underattack.wav");
+               play2team(self.team, SND(ONS_CONTROLPOINT_UNDERATTACK));
                ons_notification_time[self.team] = time;
        }
  
        pointparticles(particleeffectnum(EFFECT_SPARKS), hitloc, force*-1, 1);
        //sound on every hit
        if (random() < 0.5)
-               sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE+0.3, ATTEN_NORM);
+               sound(self, CH_TRIGGER, SND_ONS_HIT1, VOL_BASE+0.3, ATTEN_NORM);
        else
-               sound(self, CH_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE+0.3, ATTEN_NORM);
+               sound(self, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE+0.3, ATTEN_NORM);
  
        if (self.health < 0)
        {
-               sound(self, CH_TRIGGER, W_Sound("grenade_impact"), VOL_BASE, ATTEN_NORM);
+               sound(self, CH_TRIGGER, SND_GRENADE_IMPACT, VOL_BASE, ATTEN_NORM);
                pointparticles(particleeffectnum(EFFECT_ROCKET_EXPLODE), self.origin, '0 0 0', 1);
                Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_NUM_4(self.team, INFO_ONSLAUGHT_CPDESTROYED_), self.owner.message, attacker.netname);
  
@@@ -490,9 -490,9 +490,9 @@@ void ons_ControlPoint_Icon_Think(
                Send_Effect(EFFECT_ELECTRIC_SPARKS, self.origin + randompos('-10 -10 -20', '10 10 20'), '0 0 0', 1);
  
                if(random() > 0.8)
-                       sound(self, CH_PAIN, "onslaught/ons_spark1.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_PAIN, SND_ONS_SPARK1, VOL_BASE, ATTEN_NORM);
                else if (random() > 0.5)
-                       sound(self, CH_PAIN, "onslaught/ons_spark2.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_PAIN, SND_ONS_SPARK2, VOL_BASE, ATTEN_NORM);
        }
  }
  
@@@ -516,11 -516,11 +516,11 @@@ void ons_ControlPoint_Icon_BuildThink(
                self.health = self.max_health;
                self.count = autocvar_g_onslaught_cp_regen * ONS_CP_THINKRATE; // slow repair rate from now on
                self.think = ons_ControlPoint_Icon_Think;
-               sound(self, CH_TRIGGER, "onslaught/controlpoint_built.wav", VOL_BASE, ATTEN_NORM);
+               sound(self, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILT, VOL_BASE, ATTEN_NORM);
                self.owner.iscaptured = true;
                self.solid = SOLID_BBOX;
  
-               Send_Effect_(sprintf("%s_cap", Static_Team_ColorName_Lower(self.owner.team)), self.owner.origin, '0 0 0', 1);
+               Send_Effect(EFFECT_CAP(self.owner.team), self.owner.origin, '0 0 0', 1);
  
                WaypointSprite_UpdateMaxHealth(self.owner.sprite, self.max_health);
                WaypointSprite_UpdateHealth(self.owner.sprite, self.health);
@@@ -572,13 -572,13 +572,13 @@@ void ons_ControlPoint_Icon_Spawn(entit
        e.colormap = 1024 + (e.team - 1) * 17;
        e.count = (e.max_health - e.health) * ONS_CP_THINKRATE / autocvar_g_onslaught_cp_buildtime; // how long it takes to build
  
-       sound(e, CH_TRIGGER, "onslaught/controlpoint_build.wav", VOL_BASE, ATTEN_NORM);
+       sound(e, CH_TRIGGER, SND_ONS_CONTROLPOINT_BUILD, VOL_BASE, ATTEN_NORM);
  
        cp.goalentity = e;
        cp.team = e.team;
        cp.colormap = e.colormap;
  
-       Send_Effect_(sprintf("%sflag_touch", Static_Team_ColorName_Lower(player.team)), e.origin, '0 0 0', 1);
+       Send_Effect(EFFECT_FLAG_TOUCH(player.team), e.origin, '0 0 0', 1);
  
        WaypointSprite_UpdateBuildFinished(cp.sprite, time + (e.max_health - e.health) / (e.count / ONS_CP_THINKRATE));
        WaypointSprite_UpdateRule(cp.sprite,cp.team,SPRITERULE_TEAMPLAY);
@@@ -751,15 -751,6 +751,6 @@@ void ons_ControlPoint_Setup(entity cp
  
        if(cp.message == "") { cp.message = "a"; }
  
-       // precache - TODO: clean up!
-       precache_sound("onslaught/controlpoint_build.wav");
-       precache_sound("onslaught/controlpoint_built.wav");
-       precache_sound(W_Sound("grenade_impact"));
-       precache_sound("onslaught/damageblockedbyshield.wav");
-       precache_sound("onslaught/controlpoint_underattack.wav");
-       precache_sound("onslaught/ons_spark1.wav");
-       precache_sound("onslaught/ons_spark2.wav");
        // appearence
        setmodel_fixsize(cp, MDL_ONS_CP_PAD1);
  
@@@ -838,7 -829,7 +829,7 @@@ void ons_GeneratorDamage(entity inflict
                        if (time > self.pain_finished)
                                if (IS_PLAYER(attacker))
                                {
-                                       play2(attacker, "onslaught/damageblockedbyshield.wav");
+                                       play2(attacker, SND(ONS_DAMAGEBLOCKEDBYSHIELD));
                                        attacker.typehitsound += 1;
                                        self.pain_finished = time + 1;
                                }
                        self.pain_finished = time + 10;
                        entity head;
                        FOR_EACH_REALPLAYER(head) if(SAME_TEAM(head, self)) { Send_Notification(NOTIF_ONE, head, MSG_CENTER, CENTER_GENERATOR_UNDERATTACK); }
-                       play2team(self.team, "onslaught/generator_underattack.wav");
+                       play2team(self.team, SND(ONS_GENERATOR_UNDERATTACK));
                }
        }
        self.health = self.health - damage;
        // Throw some flaming gibs on damage, more damage = more chance for gib
        if(random() < damage/220)
        {
-               sound(self, CH_TRIGGER, W_Sound("rocket_impact"), VOL_BASE, ATTEN_NORM);
+               sound(self, CH_TRIGGER, SND_ROCKET_IMPACT, VOL_BASE, ATTEN_NORM);
        }
        else
        {
  
                //sound on every hit
                if (random() < 0.5)
-                       sound(self, CH_TRIGGER, "onslaught/ons_hit1.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_TRIGGER, SND_ONS_HIT1, VOL_BASE, ATTEN_NORM);
                else
-                       sound(self, CH_TRIGGER, "onslaught/ons_hit2.wav", VOL_BASE, ATTEN_NORM);
+                       sound(self, CH_TRIGGER, SND_ONS_HIT2, VOL_BASE, ATTEN_NORM);
        }
  
        self.SendFlags |= GSF_STATUS;
@@@ -921,7 -912,7 +912,7 @@@ void ons_GeneratorThink(
                                if(SAME_TEAM(e, self))
                                {
                                        Send_Notification(NOTIF_ONE, e, MSG_CENTER, CENTER_ONS_NOTSHIELDED_TEAM);
-                     soundto(MSG_ONE, e, CHAN_AUTO, "kh/alarm.wav", VOL_BASE, ATTEN_NONE);    // FIXME: unique sound?
+                     soundto(MSG_ONE, e, CHAN_AUTO, SND(KH_ALARM), VOL_BASE, ATTEN_NONE);    // FIXME: unique sound?
                  }
                                else
                                        Send_Notification(NOTIF_ONE, e, MSG_CENTER, APP_TEAM_NUM_4(self.team, CENTER_ONS_NOTSHIELDED_));
@@@ -1008,16 -999,6 +999,6 @@@ void ons_GeneratorSetup(entity gen) // 
        gen.isshielded = true;
        gen.touch = onslaught_generator_touch;
  
-       // precache - TODO: clean up!
-       precache_sound("onslaught/generator_decay.wav");
-       precache_sound(W_Sound("grenade_impact"));
-       precache_sound(W_Sound("rocket_impact"));
-       precache_sound("onslaught/generator_underattack.wav");
-       precache_sound("onslaught/shockwave.wav");
-       precache_sound("onslaught/ons_hit1.wav");
-       precache_sound("onslaught/ons_hit2.wav");
-       precache_sound("onslaught/generator_underattack.wav");
        // appearence
        // model handled by CSQC
        setsize(gen, GENERATOR_MIN, GENERATOR_MAX);
@@@ -1095,7 -1076,7 +1076,7 @@@ bool Onslaught_CheckWinner(
                if (!wpforenemy_announced)
                {
                        Send_Notification(NOTIF_ALL, world, MSG_CENTER, CENTER_OVERTIME_CONTROLPOINT);
-                       sound(world, CH_INFO, "onslaught/generator_decay.wav", VOL_BASE, ATTEN_NONE);
+                       sound(world, CH_INFO, SND_ONS_GENERATOR_DECAY, VOL_BASE, ATTEN_NONE);
  
                        wpforenemy_announced = true;
                }
  
        ons_stalemate = false;
  
-       play2all(sprintf("ctf/%s_capture.wav", Static_Team_ColorName_Lower(winner_team)));
+       play2all(SND(CTF_CAPTURE(winner_team)));
  
        round_handler_Init(7, autocvar_g_onslaught_warmup, autocvar_g_onslaught_round_timelimit);
  
@@@ -1658,7 -1639,7 +1639,7 @@@ bool ons_Teleport(entity player, entit
                                if ( tele_effects )
                                {
                                        Send_Effect(EFFECT_TELEPORT, player.origin, '0 0 0', 1);
-                                       sound (player, CH_TRIGGER, "misc/teleport.wav", VOL_BASE, ATTEN_NORM);
+                                       sound (player, CH_TRIGGER, SND_TELEPORT, VOL_BASE, ATTEN_NORM);
                                }
                                setorigin(player, loc);
                                player.angles = '0 1 0' * ( theta * RAD2DEG + 180 );
@@@ -2044,8 -2025,8 +2025,8 @@@ keys
  "target" - first control point.
  "target2" - second control point.
   */
 -void spawnfunc_onslaught_link()
 -{SELFPARAM();
 +spawnfunc(onslaught_link)
 +{
        if(!g_onslaught) { remove(self); return; }
  
        if (self.target == "" || self.target2 == "")
@@@ -2069,8 -2050,8 +2050,8 @@@ keys
  "message" - name of this control point (should reflect the location in the map, such as "center bridge", "north tower", etc)
   */
  
 -void spawnfunc_onslaught_controlpoint()
 -{SELFPARAM();
 +spawnfunc(onslaught_controlpoint)
 +{
        if(!g_onslaught) { remove(self); return; }
  
        ons_ControlPoint_Setup(self);
@@@ -2085,8 -2066,8 +2066,8 @@@ keys
  "team" - team that owns this generator (5 = red, 14 = blue, etc), MUST BE SET.
  "targetname" - name that spawnfunc_onslaught_link entities will use to target this.
   */
 -void spawnfunc_onslaught_generator()
 -{SELFPARAM();
 +spawnfunc(onslaught_generator)
 +{
        if(!g_onslaught) { remove(self); return; }
        if(!self.team) { objerror("team must be set"); }
  
@@@ -2114,11 -2095,6 +2095,6 @@@ void ons_DelayedInit() // Do this chec
  
  void ons_Initialize()
  {
-       precache_sound("ctf/red_capture.wav");
-       precache_sound("ctf/blue_capture.wav");
-       precache_sound("ctf/yellow_capture.wav");
-       precache_sound("ctf/pink_capture.wav");
        ons_captureshield_force = autocvar_g_onslaught_shield_force;
  
        addstat(STAT_ROUNDLOST, AS_INT, ons_roundlost);
index 938b9873513fa71701930f05b558810868fc5a6c,67be0829099d6ceb60955fa36a9426e538b4ebf3..cbe57ca2ac5f671c5c99325a5a2ca196e89a335c
@@@ -7,8 -7,8 +7,8 @@@
  
  #include "../../common/items/all.qc"
  
 -void spawnfunc_item_minst_cells()
 -{SELFPARAM();
 +spawnfunc(item_minst_cells)
 +{
        if (!g_instagib) { remove(self); return; }
        if (!self.ammo_cells) self.ammo_cells = autocvar_g_instagib_ammo_drop;
        StartItemA(ITEM_VaporizerCells);
@@@ -187,7 -187,7 +187,7 @@@ MUTATOR_HOOKFUNCTION(instagib_PlayerPow
  
        if (self.items & ITEM_Invisibility.m_itemid)
        {
-               play_countdown(self.strength_finished, "misc/poweroff.wav");
+               play_countdown(self.strength_finished, SND(POWEROFF));
                if (time > self.strength_finished)
                {
                        self.alpha = default_player_alpha;
  
        if (self.items & ITEM_Speed.m_itemid)
        {
-               play_countdown(self.invincible_finished, "misc/poweroff.wav");
+               play_countdown(self.invincible_finished, SND(POWEROFF));
                if (time > self.invincible_finished)
                {
                        self.items &= ~ITEM_Speed.m_itemid;
@@@ -357,7 -357,7 +357,7 @@@ MUTATOR_HOOKFUNCTION(instagib_FilterIte
                e.noalign = self.noalign;
          e.cnt = self.cnt;
          e.team = self.team;
 -              WITH(entity, self, e, spawnfunc_item_minst_cells());
 +              WITH(entity, self, e, spawnfunc_item_minst_cells(e));
                return true;
        }
  
index 33df11312ca2a0552de865af256de10844270db3,3bc1e79589355e376e712199ee3925e1105cff8d..2114efc92d56cc0c1773e3b74a8c42a1e38d3875
@@@ -4,8 -4,8 +4,8 @@@
  #include "mutator.qh"
  
  void W_Blaster_Attack(float, float, float, float, float, float, float, float, float, float);
 -void spawnfunc_weapon_hmg();
 -void spawnfunc_weapon_rpc();
 +spawnfunc(weapon_hmg);
 +spawnfunc(weapon_rpc);
  
  void ok_DecreaseCharge(entity ent, int wep)
  {
@@@ -84,7 -84,7 +84,7 @@@ MUTATOR_HOOKFUNCTION(ok_PlayerDies
        self.ok_item = true;
        self.noalign = true;
        self.pickup_anyway = true;
 -      spawnfunc_item_armor_small();
 +      spawnfunc_item_armor_small(this);
        self.movetype = MOVETYPE_TOSS;
        self.gravity = 1;
        self.reset = SUB_Remove;
@@@ -174,7 -174,7 +174,7 @@@ MUTATOR_HOOKFUNCTION(ok_PlayerPreThink
                {
                        //Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_OVERKILL_CHARGE);
                        self.ok_notice_time = time + 2;
-                       play2(self, W_Sound("dryfire"));
+                       play2(self, SND(DRYFIRE));
                }
                if(self.weaponentity.state != WS_CLEAR)
                        w_ready();
@@@ -205,9 -205,6 +205,9 @@@ MUTATOR_HOOKFUNCTION(ok_PlayerSpawn
        return false;
  }
  
 +void _spawnfunc_weapon_hmg() { SELFPARAM(); spawnfunc_weapon_hmg(this); }
 +void _spawnfunc_weapon_rpc() { SELFPARAM(); spawnfunc_weapon_rpc(this); }
 +
  MUTATOR_HOOKFUNCTION(ok_OnEntityPreSpawn)
  {SELFPARAM();
        if(autocvar_g_powerups)
                        wep.team = self.team;
                        wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
                        wep.pickup_anyway = true;
 -                      wep.think = spawnfunc_weapon_hmg;
 +                      wep.think = _spawnfunc_weapon_hmg;
                        wep.nextthink = time + 0.1;
                        return true;
                }
                        wep.team = self.team;
                        wep.respawntime = autocvar_g_overkill_superguns_respawn_time;
                        wep.pickup_anyway = true;
 -                      wep.think = spawnfunc_weapon_rpc;
 +                      wep.think = _spawnfunc_weapon_rpc;
                        wep.nextthink = time + 0.1;
                        return true;
                }
@@@ -319,8 -316,6 +319,6 @@@ void ok_Initialize(
  
        precache_all_playermodels("models/ok_player/*.dpm");
  
-       precache_sound(W_Sound("dryfire"));
        addstat(STAT_OK_AMMO_CHARGE, AS_FLOAT, ok_use_ammocharge);
        addstat(STAT_OK_AMMO_CHARGEPOOL, AS_FLOAT, ok_ammo_charge);
  
diff --combined qcsrc/server/t_items.qc
index c256d4df9022dc6a9fa7b8de864f2506737603fb,7d3e59836b9ebb80f85769d2de5a45130942d5d5..015d4aeb2cae9d50b22bd734a824a48e150b2e34
@@@ -436,11 -436,11 +436,11 @@@ void Item_Respawn (void
        Item_Show(self, 1);
        // this is ugly...
        if(self.items == ITEM_Strength.m_itemid)
-               sound (self, CH_TRIGGER, "misc/strength_respawn.wav", VOL_BASE, ATTEN_NORM);    // play respawn sound
+               sound (self, CH_TRIGGER, SND_STRENGTH_RESPAWN, VOL_BASE, ATTEN_NORM);   // play respawn sound
        else if(self.items == ITEM_Shield.m_itemid)
-               sound (self, CH_TRIGGER, "misc/shield_respawn.wav", VOL_BASE, ATTEN_NORM);      // play respawn sound
+               sound (self, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTEN_NORM);     // play respawn sound
        else
-               sound (self, CH_TRIGGER, "misc/itemrespawn.wav", VOL_BASE, ATTEN_NORM); // play respawn sound
+               sound (self, CH_TRIGGER, SND_ITEMRESPAWN, VOL_BASE, ATTEN_NORM);        // play respawn sound
        setorigin (self, self.origin);
  
      if (Item_ItemsTime_Allow(self.itemdef, self.weapons))
@@@ -472,15 -472,24 +472,24 @@@ void Item_RespawnCountdown (void
                if(self.count == 1)
                {
                        MUTATOR_CALLHOOK(Item_RespawnCountdown, string_null, '0 0 0');
-                       int wpextra = 0;
-             entity e = self.itemdef;
-             if (e) wpextra = e.m_id;
-                       if (self.flags & FL_WEAPON) {
-                               entity wi = get_weaponinfo(self.weapon);
-                               if (wi) wpextra = wi.m_id;
-                       }
-             entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP);
-             wp.wp_extra = wpextra;
+                       do {
+                               {
+                                       entity wi = get_weaponinfo(self.weapon);
+                                       if (wi.m_id) {
+                                               entity wp = WaypointSprite_Spawn(WP_Weapon, 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP);
+                                               wp.wp_extra = wi.m_id;
+                                               break;
+                                       }
+                               }
+                               {
+                                       entity ii = self.itemdef;
+                                       if (ii.m_id) {
+                                               entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_POWERUP);
+                                               wp.wp_extra = ii.m_id;
+                                               break;
+                                       }
+                               }
+                       } while (0);
              if(self.waypointsprite_attached)
              {
                  GameItem def = self.itemdef;
                                if(self.waypointsprite_visible_for_player(e))
                                {
                                        msg_entity = e;
-                                       soundto(MSG_ONE, this, CH_TRIGGER, "misc/itemrespawncountdown.wav", VOL_BASE, ATTEN_NORM);      // play respawn sound
+                                       soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM);    // play respawn sound
                                }
                        setself(this);
  
                        //WaypointSprite_UpdateHealth(self.waypointsprite_attached, self.count);
                }
                else
-                       sound(self, CH_TRIGGER, "misc/itemrespawncountdown.wav", VOL_BASE, ATTEN_NORM); // play respawn sound
+                       sound(self, CH_TRIGGER, SND_ITEMRESPAWNCOUNTDOWN, VOL_BASE, ATTEN_NORM);        // play respawn sound
        }
  }
  
@@@ -750,7 -759,7 +759,7 @@@ void Item_Touch (void
        other.last_pickup = time;
  
        Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1);
-       sound (other, CH_TRIGGER, self.item_pickupsound, VOL_BASE, ATTEN_NORM);
+       _sound (other, CH_TRIGGER, (self.item_pickupsound ? self.item_pickupsound : self.item_pickupsound_ent.sound_str()), VOL_BASE, ATTEN_NORM);
  
        if (self.classname == "droppedweapon")
                remove (self);
@@@ -1119,14 -1128,6 +1128,6 @@@ void StartItem (string itemmodel, strin
                precache_model (self.model);
                precache_sound (self.item_pickupsound);
  
-               precache_sound ("misc/itemrespawncountdown.wav");
-               if(itemid == ITEM_Strength.m_itemid)
-                       precache_sound ("misc/strength_respawn.wav");
-               else if(itemid == ITEM_Shield.m_itemid)
-                       precache_sound ("misc/shield_respawn.wav");
-               else
-                       precache_sound ("misc/itemrespawn.wav");
                if((itemflags & (FL_POWERUP | FL_WEAPON)) || (itemid & (IT_HEALTH | IT_ARMOR | IT_KEY1 | IT_KEY2)))
                        self.target = "###item###"; // for finding the nearest item using find()
  
        }
  }
  
- string Item_Model(string item_mdl)
- {
-       string output = strcat("models/items/", item_mdl);
-       MUTATOR_CALLHOOK(ItemModel, item_mdl, output);
-       return strzone(item_model_output);
- }
  void StartItemA (entity a)
  {SELFPARAM();
      self.itemdef = a;
-     StartItem(Item_Model(a.m_model), a.m_sound, a.m_respawntime(), a.m_respawntimejitter(), a.m_name, a.m_itemid, 0, a.m_itemflags, a.m_pickupevalfunc, a.m_botvalue);
+     StartItem(strzone(a.m_model.model_str()), a.m_sound, a.m_respawntime(), a.m_respawntimejitter(), a.m_name, a.m_itemid, 0, a.m_itemflags, a.m_pickupevalfunc, a.m_botvalue);
  }
  
 -void spawnfunc_item_rockets()
 -{SELFPARAM();
 +spawnfunc(item_rockets)
 +{
        if(!self.ammo_rockets)
                self.ammo_rockets = g_pickup_rockets;
        if(!self.pickup_anyway)
      StartItemA (ITEM_Rockets);
  }
  
 -void spawnfunc_item_bullets()
 -{SELFPARAM();
 +spawnfunc(item_bullets)
 +{
        if(!weaponswapping)
        if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
                weaponswapping = true;
 -              spawnfunc_item_shells();
 +              spawnfunc_item_shells(this);
                weaponswapping = false;
                return;
        }
      StartItemA (ITEM_Bullets);
  }
  
 -void spawnfunc_item_cells()
 -{SELFPARAM();
 +spawnfunc(item_cells)
 +{
        if(!self.ammo_cells)
                self.ammo_cells = g_pickup_cells;
        if(!self.pickup_anyway)
        StartItemA (ITEM_Cells);
  }
  
 -void spawnfunc_item_plasma()
 -{SELFPARAM();
 +spawnfunc(item_plasma)
 +{
        if(!self.ammo_plasma)
                self.ammo_plasma = g_pickup_plasma;
        if(!self.pickup_anyway)
        StartItemA (ITEM_Plasma);
  }
  
 -void spawnfunc_item_shells()
 -{SELFPARAM();
 +spawnfunc(item_shells)
 +{
        if(!weaponswapping)
        if(autocvar_sv_q3acompat_machineshotgunswap)
        if(self.classname != "droppedweapon")
        {
                weaponswapping = true;
 -              spawnfunc_item_bullets();
 +              spawnfunc_item_bullets(this);
                weaponswapping = false;
                return;
        }
        StartItemA (ITEM_Shells);
  }
  
 -void spawnfunc_item_armor_small()
 -{SELFPARAM();
 +spawnfunc(item_armor_small)
 +{
        if(!self.armorvalue)
                self.armorvalue = g_pickup_armorsmall;
        if(!self.max_armorvalue)
        StartItemA (ITEM_ArmorSmall);
  }
  
 -void spawnfunc_item_armor_medium()
 -{SELFPARAM();
 +spawnfunc(item_armor_medium)
 +{
        if(!self.armorvalue)
                self.armorvalue = g_pickup_armormedium;
        if(!self.max_armorvalue)
        StartItemA (ITEM_ArmorMedium);
  }
  
 -void spawnfunc_item_armor_big()
 -{SELFPARAM();
 +spawnfunc(item_armor_big)
 +{
        if(!self.armorvalue)
                self.armorvalue = g_pickup_armorbig;
        if(!self.max_armorvalue)
        StartItemA (ITEM_ArmorLarge);
  }
  
 -void spawnfunc_item_armor_large()
 -{SELFPARAM();
 +spawnfunc(item_armor_large)
 +{
        if(!self.armorvalue)
                self.armorvalue = g_pickup_armorlarge;
        if(!self.max_armorvalue)
        StartItemA (ITEM_ArmorMega);
  }
  
 -void spawnfunc_item_health_small()
 -{SELFPARAM();
 +spawnfunc(item_health_small)
 +{
        if(!self.max_health)
                self.max_health = g_pickup_healthsmall_max;
        if(!self.health)
        StartItemA (ITEM_HealthSmall);
  }
  
 -void spawnfunc_item_health_medium()
 -{SELFPARAM();
 +spawnfunc(item_health_medium)
 +{
        if(!self.max_health)
                self.max_health = g_pickup_healthmedium_max;
        if(!self.health)
      StartItemA (ITEM_HealthMedium);
  }
  
 -void spawnfunc_item_health_large()
 -{SELFPARAM();
 +spawnfunc(item_health_large)
 +{
        if(!self.max_health)
                self.max_health = g_pickup_healthlarge_max;
        if(!self.health)
        StartItemA (ITEM_HealthLarge);
  }
  
 -void spawnfunc_item_health_mega()
 -{SELFPARAM();
 +spawnfunc(item_health_mega)
 +{
      if(!self.max_health)
          self.max_health = g_pickup_healthmega_max;
      if(!self.health)
  }
  
  // support old misnamed entities
 -void spawnfunc_item_armor1() { spawnfunc_item_armor_small(); }  // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
 -void spawnfunc_item_armor25() { spawnfunc_item_armor_large(); }
 -void spawnfunc_item_health1() { spawnfunc_item_health_small(); }
 -void spawnfunc_item_health25() { spawnfunc_item_health_medium(); }
 -void spawnfunc_item_health100() { spawnfunc_item_health_mega(); }
 +spawnfunc(item_armor1) { spawnfunc_item_armor_small(this); }  // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard
 +spawnfunc(item_armor25) { spawnfunc_item_armor_large(this); }
 +spawnfunc(item_health1) { spawnfunc_item_health_small(this); }
 +spawnfunc(item_health25) { spawnfunc_item_health_medium(this); }
 +spawnfunc(item_health100) { spawnfunc_item_health_mega(this); }
  
 -void spawnfunc_item_strength()
 -{SELFPARAM();
 +spawnfunc(item_strength)
 +{
-               precache_sound("weapons/strength_fire.wav");
                if(!self.strength_finished)
                        self.strength_finished = autocvar_g_balance_powerup_strength_time;
                StartItemA (ITEM_Strength);
  }
  
 -void spawnfunc_item_invincible()
 -{SELFPARAM();
 +spawnfunc(item_invincible)
 +{
                if(!self.invincible_finished)
                        self.invincible_finished = autocvar_g_balance_powerup_invincible_time;
                StartItemA (ITEM_Shield);
  }
  
  // compatibility:
 -void spawnfunc_item_quad() {SELFPARAM(); self.classname = "item_strength";spawnfunc_item_strength();}
 +spawnfunc(item_quad) { self.classname = "item_strength";spawnfunc_item_strength(this);}
  
  void target_items_use()
  {SELFPARAM();
                centerprint(activator, self.message);
  }
  
 -void spawnfunc_target_items (void)
 -{SELFPARAM();
 +spawnfunc(target_items)
 +{
        float n, i, j;
        entity e;
        string s;
        if(!self.superweapons_finished)
                self.superweapons_finished = autocvar_g_balance_superweapons_time;
  
-       precache_sound("misc/itempickup.wav");
-       precache_sound("misc/megahealth.wav");
-       precache_sound("misc/armor25.wav");
-       precache_sound("misc/powerup.wav");
-       precache_sound("misc/poweroff.wav");
-       precache_sound(W_Sound("weaponpickup"));
        n = tokenize_console(self.netname);
        if(argv(0) == "give")
        {
        }
  }
  
 -void spawnfunc_item_fuel(void)
 -{SELFPARAM();
 +spawnfunc(item_fuel)
 +{
        if(!self.ammo_fuel)
                self.ammo_fuel = g_pickup_fuel;
        if(!self.pickup_anyway)
        StartItemA (ITEM_JetpackFuel);
  }
  
 -void spawnfunc_item_fuel_regen(void)
 +spawnfunc(item_fuel_regen)
  {
        if(start_items & ITEM_JetpackRegen.m_itemid)
        {
 -              spawnfunc_item_fuel();
 +              spawnfunc_item_fuel(this);
                return;
        }
        StartItemA (ITEM_JetpackRegen);
  }
  
 -void spawnfunc_item_jetpack(void)
 -{SELFPARAM();
 +spawnfunc(item_jetpack)
 +{
        if(!self.ammo_fuel)
                self.ammo_fuel = g_pickup_fuel_jetpack;
        if(start_items & ITEM_Jetpack.m_itemid)
        {
 -              spawnfunc_item_fuel();
 +              spawnfunc_item_fuel(this);
                return;
        }
        StartItemA (ITEM_Jetpack);
@@@ -1660,12 -1646,12 +1646,12 @@@ void GiveSound(entity e, float v0, floa
        if(v1 <= v0 - t)
        {
                if(snd_decr != "")
-                       sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
+                       _sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM);
        }
        else if(v0 >= v0 + t)
        {
                if(snd_incr != "")
-                       sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTEN_NORM);
+                       _sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTEN_NORM);
        }
  }
  
@@@ -1831,31 -1817,31 +1817,31 @@@ float GiveItems(entity e, float beginar
                op = OP_SET;
        }
  
-       POSTGIVE_BIT(e, items, ITEM_JetpackRegen.m_itemid, "misc/itempickup.wav", string_null);
-       POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, "misc/powerup.wav", "misc/poweroff.wav");
-       POSTGIVE_BIT(e, items, IT_UNLIMITED_WEAPON_AMMO, "misc/powerup.wav", "misc/poweroff.wav");
-       POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, "misc/itempickup.wav", string_null);
+       POSTGIVE_BIT(e, items, ITEM_JetpackRegen.m_itemid, SND(ITEMPICKUP), string_null);
+       POSTGIVE_BIT(e, items, IT_UNLIMITED_SUPERWEAPONS, SND(POWERUP), SND(POWEROFF));
+       POSTGIVE_BIT(e, items, IT_UNLIMITED_WEAPON_AMMO, SND(POWERUP), SND(POWEROFF));
+       POSTGIVE_BIT(e, items, ITEM_Jetpack.m_itemid, SND(ITEMPICKUP), string_null);
        for(j = WEP_FIRST; j <= WEP_LAST; ++j)
        {
                wi = get_weaponinfo(j);
                if(wi.weapon)
                {
-                       POSTGIVE_WEAPON(e, j, W_Sound("weaponpickup"), string_null);
+                       POSTGIVE_WEAPON(e, j, SND(WEAPONPICKUP), string_null);
                        if (!(save_weapons & WepSet_FromWeapon(j)))
                                if(e.weapons & WepSet_FromWeapon(j))
                                        WEP_ACTION(wi.weapon, WR_INIT);
                }
        }
-       POSTGIVE_VALUE(e, strength_finished, 1, "misc/powerup.wav", "misc/poweroff.wav");
-       POSTGIVE_VALUE(e, invincible_finished, 1, "misc/powerup_shield.wav", "misc/poweroff.wav");
-       POSTGIVE_VALUE(e, ammo_nails, 0, "misc/itempickup.wav", string_null);
-       POSTGIVE_VALUE(e, ammo_cells, 0, "misc/itempickup.wav", string_null);
-       POSTGIVE_VALUE(e, ammo_plasma, 0, "misc/itempickup.wav", string_null);
-       POSTGIVE_VALUE(e, ammo_shells, 0, "misc/itempickup.wav", string_null);
-       POSTGIVE_VALUE(e, ammo_rockets, 0, "misc/itempickup.wav", string_null);
-       POSTGIVE_VALUE_ROT(e, ammo_fuel, 1, pauserotfuel_finished, autocvar_g_balance_pause_fuel_rot, pauseregen_finished, autocvar_g_balance_pause_fuel_regen, "misc/itempickup.wav", string_null);
-       POSTGIVE_VALUE_ROT(e, armorvalue, 1, pauserotarmor_finished, autocvar_g_balance_pause_armor_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, "misc/armor25.wav", string_null);
-       POSTGIVE_VALUE_ROT(e, health, 1, pauserothealth_finished, autocvar_g_balance_pause_health_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, "misc/megahealth.wav", string_null);
+       POSTGIVE_VALUE(e, strength_finished, 1, SND(POWERUP), SND(POWEROFF));
+       POSTGIVE_VALUE(e, invincible_finished, 1, "misc/powerup_shield.wav", SND(POWEROFF));
+       POSTGIVE_VALUE(e, ammo_nails, 0, SND(ITEMPICKUP), string_null);
+       POSTGIVE_VALUE(e, ammo_cells, 0, SND(ITEMPICKUP), string_null);
+       POSTGIVE_VALUE(e, ammo_plasma, 0, SND(ITEMPICKUP), string_null);
+       POSTGIVE_VALUE(e, ammo_shells, 0, SND(ITEMPICKUP), string_null);
+       POSTGIVE_VALUE(e, ammo_rockets, 0, SND(ITEMPICKUP), string_null);
+       POSTGIVE_VALUE_ROT(e, ammo_fuel, 1, pauserotfuel_finished, autocvar_g_balance_pause_fuel_rot, pauseregen_finished, autocvar_g_balance_pause_fuel_regen, SND(ITEMPICKUP), string_null);
+       POSTGIVE_VALUE_ROT(e, armorvalue, 1, pauserotarmor_finished, autocvar_g_balance_pause_armor_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, SND(ARMOR25), string_null);
+       POSTGIVE_VALUE_ROT(e, health, 1, pauserothealth_finished, autocvar_g_balance_pause_health_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, SND(MEGAHEALTH), string_null);
  
        if(e.superweapons_finished <= 0)
                if(self.weapons & WEPSET_SUPERWEAPONS)