better sound handling in "give";
authordiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Mon, 25 Jan 2010 17:13:58 +0000 (17:13 +0000)
committerdiv0 <div0@f962a42d-fe04-0410-a3ab-8c8b0445ebaa>
Mon, 25 Jan 2010 17:13:58 +0000 (17:13 +0000)
log attempted cheats if sv_cheats is 0
don't log ineffective cheats as invalid clientcommand

git-svn-id: svn://svn.icculus.org/nexuiz/trunk@8572 f962a42d-fe04-0410-a3ab-8c8b0445ebaa

data/qcsrc/server/cheats.qc
data/qcsrc/server/t_items.qc

index 00022ef..58cce90 100644 (file)
@@ -65,12 +65,22 @@ float CheatsAllowed(float i, float argc, float fr) // the cheat gets passed as a
        if(sv_cheats && autocvar_sv_cheats)
                return 1;
 
+       // if we get here, player is not allowed to cheat. Log it.
+       if(i)
+               bprint(sprintf("Player %s^7 tried to use cheat 'impulse %d'\n", self.netname, i));
+       else if(argc)
+               bprint(sprintf("Player %s^7 tried to use cheat '%s'\n", self.netname, argv(0)));
+       else if(fr)
+               bprint(sprintf("Player %s^7 tried to use cheat frame %d\n", self.netname, fr));
+       else
+               bprint(sprintf("Player %s^7 tried to use an unknown cheat\n", self.netname));
+
        return 0;
 }
 
 #define BEGIN_CHEAT_FUNCTION() \
-       float cheating; \
-       cheating = 0
+       float cheating, attempting; \
+       cheating = 0; attempting = 0
 #define DID_CHEAT() \
        ++cheating
 #define ADD_CHEATS(e,n) \
@@ -78,19 +88,22 @@ float CheatsAllowed(float i, float argc, float fr) // the cheat gets passed as a
        e.cheatcount += n
 #define END_CHEAT_FUNCTION() \
        ADD_CHEATS(self,cheating); \
-       return cheating
+       return attempting
+#define IS_CHEAT(i,argc,fr) \
+       ++attempting; \
+       if(!CheatsAllowed(i,argc,fr)) \
+               break
 
 float CheatImpulse(float i)
 {
        BEGIN_CHEAT_FUNCTION();
-       if not(CheatsAllowed(i, 0, 0))
-               return 0;
        switch(i)
        {
                entity e, e2;
                vector org;
 
                case CHIMPULSE_SPEEDRUN_INIT: // deploy personal waypoint
+                       // shared with regular waypoint init, so this is not a cheat by itself
                        if(!self.personal)
                        {
                                self.personal = spawn();
@@ -117,6 +130,7 @@ float CheatImpulse(float i)
                        self.personal.teleport_time = time;
                        break; // this part itself doesn't cheat, so let's not count this
                case CHIMPULSE_CLONE_MOVING:
+                       IS_CHEAT(i, 0, 0);
                        makevectors (self.v_angle);
                        self.velocity = self.velocity + v_forward * 300;
                        CopyBody(1);
@@ -125,14 +139,17 @@ float CheatImpulse(float i)
                        DID_CHEAT();
                        break;
                case CHIMPULSE_CLONE_STANDING:
+                       IS_CHEAT(i, 0, 0);
                        CopyBody(0);
                        self.lip += 1;
                        DID_CHEAT();
                        break;
                case CHIMPULSE_GIVE_ALL:
+                       IS_CHEAT(i, 0, 0);
                        CheatCommand(tokenize_console("give all"));
                        break; // already counted as cheat
                case CHIMPULSE_SPEEDRUN:
+                       IS_CHEAT(i, 0, 0);
                        if(self.personal)
                        {
                                self.speedrunning = TRUE;
@@ -198,6 +215,7 @@ float CheatImpulse(float i)
                                sprint(self, "No waypoint set, cheater (use g_waypointsprite_personal to set one)\n");
                        break;
                case CHIMPULSE_TELEPORT:
+                       IS_CHEAT(i, 0, 0);
                        if(MoveToRandomMapLocation(self, DPCONTENTS_SOLID | DPCONTENTS_CORPSE | DPCONTENTS_PLAYERCLIP, DPCONTENTS_SLIME | DPCONTENTS_LAVA | DPCONTENTS_SKY | DPCONTENTS_BODY | DPCONTENTS_DONOTENTER, Q3SURFACEFLAG_SKY, ((sv_cheats >= 2) ? 100000 : 100), 1024, 256))
                        {
                                self.angles_x = -self.angles_x;
@@ -209,6 +227,7 @@ float CheatImpulse(float i)
                        sprint(self, "Emergency teleport could not find a good location, forget it!\n");
                        break;
                case CHIMPULSE_R00T:
+                       IS_CHEAT(i, 0, 0);
                        FOR_EACH_PLAYER(e)
                        {
                                if( e.playermodel == "models/player/jeandarc.zym"
@@ -251,8 +270,6 @@ float drag_lastcnt;
 float CheatCommand(float argc)
 {
        BEGIN_CHEAT_FUNCTION();
-       if not(CheatsAllowed(0, argc, 0))
-               return 0;
        string cmd;
        cmd = argv(0);
        switch(cmd)
@@ -263,6 +280,7 @@ float CheatCommand(float argc)
                entity oldself;
 
                case "pointparticles":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 5)
                        {
                                // arguments:
@@ -282,6 +300,7 @@ float CheatCommand(float argc)
                        sprint(self, "Usage: sv_cheats 1; restart; cmd pointparticles effectname position(0..1) velocityvector multiplier\n");
                        break;
                case "trailparticles":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 2)
                        {
                                // arguments:
@@ -296,6 +315,7 @@ float CheatCommand(float argc)
                        sprint(self, "Usage: sv_cheats 1; restart; cmd trailparticles effectname\n");
                        break;
                case "make":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 3)
                        {
                                // arguments:
@@ -344,6 +364,7 @@ float CheatCommand(float argc)
                                sprint(self, "Usage: sv_cheats 1; restart; cmd make models/... 0/1/2\n");
                        break;
                case "penalty":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 3)
                        {
                                race_ImposePenaltyTime(self, stof(argv(1)), argv(2));
@@ -353,6 +374,7 @@ float CheatCommand(float argc)
                        sprint(self, "Usage: sv_cheats 1; restart; cmd penalty 5.0 AHAHAHAHAHAHAH))\n");
                        break;
                case "dragbox_spawn":
+                       IS_CHEAT(0, argc, 0);
                        e = spawn();
                        e.classname = "dragbox_box";
                        e.think = DragBox_Think;
@@ -403,6 +425,7 @@ float CheatCommand(float argc)
                        DID_CHEAT();
                        break;
                case "dragpoint_spawn":
+                       IS_CHEAT(0, argc, 0);
                        e = spawn();
                        e.classname = "dragpoint";
                        e.think = DragBox_Think;
@@ -436,6 +459,7 @@ float CheatCommand(float argc)
                        DID_CHEAT();
                        break;
                case "drag_remove":
+                       IS_CHEAT(0, argc, 0);
                        RandomSelection_Init();
                        for(e = world; (e = find(e, classname, "dragbox_box")); )
                                RandomSelection_Add(e, 0, string_null, 1, 1 / vlen(e.origin + (e.mins + e.maxs) * 0.5 - self.cursor_trace_endpos));
@@ -454,6 +478,7 @@ float CheatCommand(float argc)
                        DID_CHEAT();
                        break;
                case "drag_setcnt":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 2)
                        {
                                RandomSelection_Init();
@@ -474,6 +499,7 @@ float CheatCommand(float argc)
                        sprint(self, "Usage: sv_cheats 1; restart; cmd dragbox_setcnt cnt\n");
                        break;
                case "drag_save":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 2)
                        {
                                f = fopen(argv(1), FILE_WRITE);
@@ -493,6 +519,7 @@ float CheatCommand(float argc)
                        sprint(self, "Usage: sv_cheats 1; restart; cmd dragbox_save filename\n");
                        break;
                case "drag_saveraceent":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 2)
                        {
                                f = fopen(argv(1), FILE_WRITE);
@@ -561,6 +588,7 @@ float CheatCommand(float argc)
                        sprint(self, "Usage: sv_cheats 1; restart; cmd dragbox_save filename\n");
                        break;
                case "drag_clear":
+                       IS_CHEAT(0, argc, 0);
                        for(e = world; (e = find(e, classname, "dragbox_box")); )
                                remove(e);
                        for(e = world; (e = find(e, classname, "dragbox_corner_1")); )
@@ -574,6 +602,7 @@ float CheatCommand(float argc)
                        DID_CHEAT();
                        break;
                case "warp":
+                       IS_CHEAT(0, argc, 0);
                        if(argc == 2) if(cvar("g_campaign"))
                        {
                                CampaignLevelWarp(stof(argv(1)));
@@ -581,6 +610,7 @@ float CheatCommand(float argc)
                        }
                        break;
                case "god":
+                       IS_CHEAT(0, argc, 0);
                        BITXOR_ASSIGN(self.flags, FL_GODMODE);
                        if(self.flags & FL_GODMODE)
                        {
@@ -591,6 +621,7 @@ float CheatCommand(float argc)
                                sprint(self, "godmode OFF\n");
                        break;
                case "notarget":
+                       IS_CHEAT(0, argc, 0);
                        BITXOR_ASSIGN(self.flags, FL_NOTARGET);
                        if(self.flags & FL_NOTARGET)
                        {
@@ -601,6 +632,7 @@ float CheatCommand(float argc)
                                sprint(self, "notarget OFF\n");
                        break;
                case "noclip":
+                       IS_CHEAT(0, argc, 0);
                        if(self.movetype != MOVETYPE_NOCLIP)
                        {
                                self.movetype = MOVETYPE_NOCLIP;
@@ -614,6 +646,7 @@ float CheatCommand(float argc)
                        }
                        break;
                case "fly":
+                       IS_CHEAT(0, argc, 0);
                        if(self.movetype != MOVETYPE_FLY)
                        {
                                self.movetype = MOVETYPE_FLY;
@@ -627,6 +660,7 @@ float CheatCommand(float argc)
                        }
                        break;
                case "give":
+                       IS_CHEAT(0, argc, 0);
                        if(GiveItems(self, 1, argc))
                                DID_CHEAT();
                        break;
@@ -652,20 +686,6 @@ float CheatFrame()
 {
        BEGIN_CHEAT_FUNCTION();
 
-       if(CheatsAllowed(0, 0, CHRAME_DRAG))
-               if(Drag_CanDrag(self))
-                       if(self.BUTTON_DRAG)
-                               if(!self.dragentity)
-                                       if(self.cursor_trace_ent)
-                                               if(Drag_IsDraggable(self.cursor_trace_ent))
-                                               {
-                                                       if(self.cursor_trace_ent.draggedby)
-                                                               Drag_Finish(self.cursor_trace_ent.draggedby);
-                                                       if(self.cursor_trace_ent.tag_entity)
-                                                               detach_sameorigin(self.cursor_trace_ent);
-                                                       Drag_Begin(self, self.cursor_trace_ent, self.cursor_trace_endpos);
-                                                       DID_CHEAT();
-                                               }
        if(Drag_IsDragging(self))
        {
                if(self.BUTTON_DRAG)
@@ -697,6 +717,25 @@ float CheatFrame()
                        Drag_Finish(self);
                }
        }
+       else
+       {
+               if(Drag_CanDrag(self))
+                       if(self.BUTTON_DRAG)
+                               if(self.cursor_trace_ent)
+                                       if(Drag_IsDraggable(self.cursor_trace_ent))
+                                               switch(0)
+                                               {
+                                                       default:
+                                                               IS_CHEAT(0, 0, CHRAME_DRAG);
+                                                               if(self.cursor_trace_ent.draggedby)
+                                                                       Drag_Finish(self.cursor_trace_ent.draggedby);
+                                                               if(self.cursor_trace_ent.tag_entity)
+                                                                       detach_sameorigin(self.cursor_trace_ent);
+                                                               Drag_Begin(self, self.cursor_trace_ent, self.cursor_trace_endpos);
+                                                               DID_CHEAT();
+                                                               break;
+                                               }
+       }
 
        END_CHEAT_FUNCTION();
 }
index b8980e6..83f6db8 100644 (file)
@@ -1519,21 +1519,7 @@ void spawnfunc_weapon_seeker()
 #define OP_PLUS 3
 #define OP_MINUS 4
 
-void GiveSound(entity e, float v0, float v1, string snd_incr, string snd_decr)
-{
-       if(v0 > v1)
-       {
-               if(snd_decr != "")
-                       sound (e, CHAN_AUTO, snd_decr, VOL_BASE, ATTN_NORM);
-       }
-       else if(v0 < v1)
-       {
-               if(snd_incr != "")
-                       sound (e, CHAN_AUTO, snd_incr, VOL_BASE, ATTN_NORM);
-       }
-}
-
-float GiveBit(entity e, .float fld, float bit, float op, float val, string snd_incr, string snd_decr)
+float GiveBit(entity e, .float fld, float bit, float op, float val)
 {
        float v0, v1;
        v0 = (e.fld & bit);
@@ -1560,11 +1546,10 @@ float GiveBit(entity e, .float fld, float bit, float op, float val, string snd_i
                        break;
        }
        v1 = (e.fld & bit);
-       GiveSound(e, v0, v1, snd_incr, snd_decr);
        return (v0 != v1);
 }
 
-float GiveValue(entity e, .float fld, float op, float val, string snd_incr, string snd_decr)
+float GiveValue(entity e, .float fld, float op, float val)
 {
        float v0, v1;
        v0 = e.fld;
@@ -1587,23 +1572,36 @@ float GiveValue(entity e, .float fld, float op, float val, string snd_incr, stri
                        break;
        }
        v1 = e.fld;
-       GiveSound(e, v0, v1, snd_incr, snd_decr);
        return (v0 != v1);
 }
 
-float GiveValueRot(entity e, .float fld, .float rotfield, float rottime, .float regenfield, float regentime, float op, float val, string snd_incr, string snd_decr)
+void GiveSound(entity e, float v0, float v1, string snd_incr, string snd_decr)
+{
+       if(v0 > v1)
+       {
+               if(snd_decr != "")
+                       sound (e, CHAN_AUTO, snd_decr, VOL_BASE, ATTN_NORM);
+       }
+       else if(v0 < v1)
+       {
+               if(snd_incr != "")
+                       sound (e, CHAN_AUTO, snd_incr, VOL_BASE, ATTN_NORM);
+       }
+}
+
+void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .float regenfield, float regentime)
 {
-       float v0, v1;
-       v0 = e.fld;
-       GiveValue(e, fld, op, val, snd_incr, snd_decr);
-       v1 = e.fld;
        if(v0 < v1)
                e.rotfield = max(e.rotfield, time + rottime);
        else if(v0 > v1)
                e.regenfield = max(e.regenfield, time + regentime);
-       return (v0 != v1);
 }
 
+#define PREGIVE(e,f) float save_##f; save_##f = (e).f
+#define POSTGIVE_BIT(e,f,b,snd_incr,snd_decr) GiveSound((e), save_##f & (b), (e).f & (b), snd_incr, snd_decr)
+#define POSTGIVE_VALUE(e,f,snd_incr,snd_decr) GiveSound((e), save_##f, (e).f, snd_incr, snd_decr)
+#define POSTGIVE_VALUE_ROT(e,f,rotfield,rottime,regenfield,regentime,snd_incr,snd_decr) GiveRot((e), save_##f, (e).f, rotfield, rottime, regenfield, regentime); GiveSound((e), save_##f, (e).f, snd_incr, snd_decr)
+
 float GiveItems(entity e, float beginarg, float endarg)
 {
        float got, i, j, val, op;
@@ -1621,10 +1619,20 @@ float GiveItems(entity e, float beginarg, float endarg)
                if (activator.switchweapon == w_getbestweapon(activator))
                        _switchweapon = TRUE;
 
-       if(activator.strength_finished <= time)
-               activator.strength_finished = time;
-       if(activator.invincible_finished <= time)
-               activator.invincible_finished = time;
+       activator.strength_finished = max(0, activator.strength_finished - time);
+       activator.invincible_finished = max(0, activator.invincible_finished - time);
+       
+       PREGIVE(e, items);
+       PREGIVE(e, weapons);
+       PREGIVE(e, strength_finished);
+       PREGIVE(e, invincible_finished);
+       PREGIVE(e, ammo_nails);
+       PREGIVE(e, ammo_cells);
+       PREGIVE(e, ammo_shells);
+       PREGIVE(e, ammo_rockets);
+       PREGIVE(e, ammo_fuel);
+       PREGIVE(e, armorvalue);
+       PREGIVE(e, health);
 
        for(i = beginarg; i < endarg; ++i)
        {
@@ -1654,79 +1662,70 @@ float GiveItems(entity e, float beginarg, float endarg)
                                op = OP_MINUS;
                                continue;
                        case "ALL":
-                               got += GiveBit(e, items, IT_FUEL_REGEN, op, val, "misc/itempickup.wav", string_null);
-                               got += GiveValue(e, strength_finished, op, time + val, "misc/powerup.wav", "misc/poweroff.wav");
-                               got += GiveValue(e, invincible_finished, op, time + val, "misc/powerup_shield.wav", "misc/poweroff.wav");
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val, "misc/powerup.wav", "misc/poweroff.wav");
+                               got += GiveBit(e, items, IT_FUEL_REGEN, op, val);
+                               got += GiveValue(e, strength_finished, op, time + val);
+                               got += GiveValue(e, invincible_finished, op, time + val);
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
                        case "all":
-                               got += GiveBit(e, items, IT_JETPACK, op, val, "misc/powerup.wav", "misc/poweroff.wav");
-                               got += GiveValue(e, ammo_cells, op, val, "misc/itempickup.wav", string_null);
-                               got += GiveValue(e, ammo_shells, op, val, "misc/itempickup.wav", string_null);
-                               got += GiveValue(e, ammo_nails, op, val, "misc/itempickup.wav", string_null);
-                               got += GiveValue(e, ammo_rockets, op, val, "misc/itempickup.wav", string_null);
-                               got += GiveValueRot(e, health, pauserothealth_finished, cvar("g_balance_pause_health_rot"), pauseregen_finished, cvar("g_balance_pause_health_regen"), op, val, "misc/megahealth.wav", string_null);
-                               got += GiveValueRot(e, armorvalue, pauserotarmor_finished, cvar("g_balance_pause_armor_rot"), pauseregen_finished, cvar("g_balance_pause_health_regen"), op, val, "misc/armor25.wav", string_null);
-                               got += GiveValueRot(e, ammo_fuel, pauserotfuel_finished, cvar("g_balance_pause_fuel_rot"), pauseregen_finished, cvar("g_balance_pause_fuel_regen"), op, val, "misc/itempickup.wav", string_null);
+                               got += GiveBit(e, items, IT_JETPACK, op, val);
+                               got += GiveValue(e, health, op, val);
+                               got += GiveValue(e, armorvalue, op, val);
+                       case "allweapons":
                                for(j = WEP_FIRST; j <= WEP_LAST; ++j)
                                {
                                        wi = get_weaponinfo(j);
                                        if(wi.weapons)
-                                       {
-                                               if(e.weapons & wi.weapons)
-                                               {
-                                                       got += GiveBit(e, weapons, wi.weapons, op, val, "weapons/weaponpickup.wav", "");
-                                               }
-                                               else
-                                               {
-                                                       got += GiveBit(e, weapons, wi.weapons, op, val, "weapons/weaponpickup.wav", "");
-                                                       if(e.weapons & wi.weapons)
-                                                               weapon_action(wi.weapon, WR_PRECACHE);
-                                               }
-                                       }
+                                               got += GiveBit(e, weapons, wi.weapons, op, val);
                                }
+                       case "allammo":
+                               got += GiveValue(e, ammo_cells, op, val);
+                               got += GiveValue(e, ammo_shells, op, val);
+                               got += GiveValue(e, ammo_nails, op, val);
+                               got += GiveValue(e, ammo_rockets, op, val);
+                               got += GiveValue(e, ammo_fuel, op, val);
                                break;
                        case "unlimited_ammo":
-                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val, "misc/powerup.wav", "misc/poweroff.wav");
+                               got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val);
                                break;
                        case "unlimited_weapon_ammo":
-                               got += GiveBit(e, items, IT_UNLIMITED_WEAPON_AMMO, op, val, "misc/powerup.wav", "misc/poweroff.wav");
+                               got += GiveBit(e, items, IT_UNLIMITED_WEAPON_AMMO, op, val);
                                break;
                        case "unlimited_superweapons":
-                               got += GiveBit(e, items, IT_UNLIMITED_SUPERWEAPONS, op, val, "misc/powerup.wav", "misc/poweroff.wav");
+                               got += GiveBit(e, items, IT_UNLIMITED_SUPERWEAPONS, op, val);
                                break;
                        case "jetpack":
-                               got += GiveBit(e, items, IT_JETPACK, op, val, "misc/itempickup.wav", string_null);
+                               got += GiveBit(e, items, IT_JETPACK, op, val);
                                break;
                        case "fuel_regen":
-                               got += GiveBit(e, items, IT_FUEL_REGEN, op, val, "misc/itempickup.wav", string_null);
+                               got += GiveBit(e, items, IT_FUEL_REGEN, op, val);
                                break;
                        case "strength":
-                               got += GiveValue(e, strength_finished, op, time + val, "misc/powerup.wav", "misc/poweroff.wav");
+                               got += GiveValue(e, strength_finished, op, time + val);
                                break;
                        case "invincible":
-                               got += GiveValue(e, invincible_finished, op, time + val, "misc/powerup_shield.wav", "misc/poweroff.wav");
+                               got += GiveValue(e, invincible_finished, op, time + val);
                                break;
                        case "cells":
-                               got += GiveValue(e, ammo_cells, op, val, "misc/itempickup.wav", string_null);
+                               got += GiveValue(e, ammo_cells, op, val);
                                break;
                        case "shells":
-                               got += GiveValue(e, ammo_shells, op, val, "misc/itempickup.wav", string_null);
+                               got += GiveValue(e, ammo_shells, op, val);
                                break;
                        case "nails":
                        case "bullets":
-                               got += GiveValue(e, ammo_nails, op, val, "misc/itempickup.wav", string_null);
+                               got += GiveValue(e, ammo_nails, op, val);
                                break;
                        case "rockets":
-                               got += GiveValue(e, ammo_rockets, op, val, "misc/itempickup.wav", string_null);
+                               got += GiveValue(e, ammo_rockets, op, val);
                                break;
                        case "health":
-                               got += GiveValueRot(e, health, pauserothealth_finished, cvar("g_balance_pause_health_rot"), pauseregen_finished, cvar("g_balance_pause_health_regen"), op, val, "misc/megahealth.wav", string_null);
+                               got += GiveValue(e, health, op, val);
                                break;
                        case "armor":
-                               got += GiveValueRot(e, armorvalue, pauserotarmor_finished, cvar("g_balance_pause_armor_rot"), pauseregen_finished, cvar("g_balance_pause_health_regen"), op, val, "misc/armor25.wav", string_null);
+                               got += GiveValue(e, armorvalue, op, val);
                                break;
                        case "fuel":
-                               got += GiveValueRot(e, ammo_fuel, pauserotfuel_finished, cvar("g_balance_pause_fuel_rot"), pauseregen_finished, cvar("g_balance_pause_fuel_regen"), op, val, "misc/itempickup.wav", string_null);
+                               got += GiveValue(e, ammo_fuel, op, val);
                                break;
                        default:
                                for(j = WEP_FIRST; j <= WEP_LAST; ++j)
@@ -1734,16 +1733,7 @@ float GiveItems(entity e, float beginarg, float endarg)
                                        wi = get_weaponinfo(j);
                                        if(cmd == wi.netname)
                                        {
-                                               if(e.weapons & wi.weapons)
-                                               {
-                                                       got += GiveBit(e, weapons, wi.weapons, op, val, "weapons/weaponpickup.wav", "");
-                                               }
-                                               else
-                                               {
-                                                       got += GiveBit(e, weapons, wi.weapons, op, val, "weapons/weaponpickup.wav", "");
-                                                       if(e.weapons & wi.weapons)
-                                                               weapon_action(wi.weapon, WR_PRECACHE);
-                                               }
+                                               got += GiveBit(e, weapons, wi.weapons, op, val);
                                                break;
                                        }
                                }
@@ -1755,10 +1745,39 @@ float GiveItems(entity e, float beginarg, float endarg)
                op = OP_SET;
        }
 
-       if(activator.strength_finished <= time)
+       POSTGIVE_BIT(e, items, IT_FUEL_REGEN, "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, IT_JETPACK, "misc/itempickup.wav", string_null);
+       for(j = WEP_FIRST; j <= WEP_LAST; ++j)
+       {
+               wi = get_weaponinfo(j);
+               if(wi.weapons)
+               {
+                       POSTGIVE_BIT(e, weapons, wi.weapons, "weapons/weaponpickup.wav", string_null);
+                       if not(save_weapons & wi.weapons)
+                               if(e.weapons & wi.weapons)
+                                       weapon_action(wi.weapon, WR_PRECACHE);
+               }
+       }
+       POSTGIVE_VALUE(e, strength_finished, "misc/powerup.wav", "misc/poweroff.wav");
+       POSTGIVE_VALUE(e, invincible_finished, "misc/powerup_shield.wav", "misc/poweroff.wav");
+       POSTGIVE_VALUE(e, ammo_nails, "misc/itempickup.wav", string_null);
+       POSTGIVE_VALUE(e, ammo_cells, "misc/itempickup.wav", string_null);
+       POSTGIVE_VALUE(e, ammo_shells, "misc/itempickup.wav", string_null);
+       POSTGIVE_VALUE(e, ammo_rockets, "misc/itempickup.wav", string_null);
+       POSTGIVE_VALUE_ROT(e, ammo_fuel, pauserotfuel_finished, cvar("g_balance_pause_fuel_rot"), pauseregen_finished, cvar("g_balance_pause_fuel_regen"), "misc/itempickup.wav", string_null);
+       POSTGIVE_VALUE_ROT(e, armorvalue, pauserotarmor_finished, cvar("g_balance_pause_armor_rot"), pauseregen_finished, cvar("g_balance_pause_health_regen"), "misc/armor25.wav", string_null);
+       POSTGIVE_VALUE_ROT(e, health, pauserothealth_finished, cvar("g_balance_pause_health_rot"), pauseregen_finished, cvar("g_balance_pause_health_regen"), "misc/megahealth.wav", string_null);
+
+       if(activator.strength_finished <= 0)
                activator.strength_finished = 0;
-       if(activator.invincible_finished <= time)
+       else
+               activator.strength_finished += time;
+       if(activator.invincible_finished <= 0)
                activator.invincible_finished = 0;
+       else
+               activator.invincible_finished += time;
 
        if not(activator.weapons & W_WeaponBit(activator.switchweapon))
                _switchweapon = TRUE;