From 2f6edd012e349c1778d399f0caed90e06aab9f0b Mon Sep 17 00:00:00 2001 From: div0 Date: Mon, 25 Jan 2010 17:13:58 +0000 Subject: [PATCH] better sound handling in "give"; 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 | 81 +++++++++++----- data/qcsrc/server/t_items.qc | 175 +++++++++++++++++++---------------- 2 files changed, 157 insertions(+), 99 deletions(-) diff --git a/data/qcsrc/server/cheats.qc b/data/qcsrc/server/cheats.qc index 00022efb2..58cce90d6 100644 --- a/data/qcsrc/server/cheats.qc +++ b/data/qcsrc/server/cheats.qc @@ -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(); } diff --git a/data/qcsrc/server/t_items.qc b/data/qcsrc/server/t_items.qc index b8980e6ee..83f6db868 100644 --- a/data/qcsrc/server/t_items.qc +++ b/data/qcsrc/server/t_items.qc @@ -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; -- 2.39.2