X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fcommon%2Ft_items.qc;h=af0c52e2345f76e0721e8b8732156179733ffbf8;hb=3bbcff2475d1b2efc1314a358bf60c6fba6e4be6;hp=e47e357bf33a1f0767e3ab81a65b4ed106e93beb;hpb=2c6bdfd37b7792655bae84def194f8364aa5e55b;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index e47e357bf..af0c52e23 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -1,32 +1,31 @@ #include "t_items.qh" -#include "items/all.qc" +#include "items/_mod.qh" #if defined(SVQC) - #include "../server/bot/bot.qh" - #include "../server/bot/waypoints.qh" + #include "../server/bot/api.qh" - #include "../server/mutators/all.qh" + #include #include "../server/weapons/common.qh" #include "../server/weapons/selection.qh" #include "../server/weapons/weaponsystem.qh" #include "constants.qh" - #include "deathtypes/all.qh" - #include "notifications.qh" + #include + #include #include "triggers/subs.qh" #include "util.qh" - #include "monsters/all.qh" + #include - #include "weapons/all.qh" + #include #include "../lib/warpzone/util_server.qh" #elif defined(CSQC) #include "physics/movetypes/movetypes.qh" - #include "weapons/all.qh" + #include #include "../lib/csqcmodel/cl_model.qh" #include "../lib/csqcmodel/common.qh" #endif @@ -34,12 +33,17 @@ REGISTER_NET_LINKED(ENT_CLIENT_ITEM) #ifdef CSQC +bool autocvar_cl_ghost_items_vehicle = true; +.vector item_glowmod; void Item_SetAlpha(entity this) { - if(!hud && (this.ItemStatus & ITS_AVAILABLE)) + bool veh_hud = (hud && autocvar_cl_ghost_items_vehicle); + + if(!veh_hud && (this.ItemStatus & ITS_AVAILABLE)) { this.alpha = 1; - this.colormod = this.glowmod = '1 1 1'; + this.colormod = '1 1 1'; + this.glowmod = this.item_glowmod; } else { @@ -52,30 +56,31 @@ void Item_SetAlpha(entity this) this.alpha = -1; } - if(!hud) + if(!veh_hud) if(this.ItemStatus & ITS_STAYWEP) { this.colormod = this.glowmod = autocvar_cl_weapon_stay_color; this.alpha = autocvar_cl_weapon_stay_alpha; } } + void ItemDraw(entity this) { if(this.gravity) { Movetype_Physics_MatchServer(this, false); - if(this.move_flags & FL_ONGROUND) - { // For some reason move_avelocity gets set to '0 0 0' here ... + if(IS_ONGROUND(this)) + { // For some reason avelocity gets set to '0 0 0' here ... this.oldorigin = this.origin; this.gravity = 0; if(autocvar_cl_animate_items) { // ... so reset it if animations are requested. if(this.ItemStatus & ITS_ANIMATE1) - this.move_avelocity = '0 180 0'; + this.avelocity = '0 180 0'; if(this.ItemStatus & ITS_ANIMATE2) - this.move_avelocity = '0 -90 0'; + this.avelocity = '0 -90 0'; } } } @@ -83,13 +88,13 @@ void ItemDraw(entity this) { if(this.ItemStatus & ITS_ANIMATE1) { - this.angles += this.move_avelocity * frametime; + this.angles += this.avelocity * frametime; setorigin(this, '0 0 10' + this.oldorigin + '0 0 8' * sin(time * 2)); } if(this.ItemStatus & ITS_ANIMATE2) { - this.angles += this.move_avelocity * frametime; + this.angles += this.avelocity * frametime; setorigin(this, '0 0 8' + this.oldorigin + '0 0 4' * sin(time * 3)); } } @@ -103,41 +108,43 @@ void ItemDrawSimple(entity this) { Movetype_Physics_MatchServer(this, false); - if(this.move_flags & FL_ONGROUND) + if(IS_ONGROUND(this)) this.gravity = 0; } + + Item_SetAlpha(this); } -void Item_PreDraw() -{SELFPARAM(); +void Item_PreDraw(entity this) +{ if(warpzone_warpzones_exist) { // just incase warpzones were initialized last, reset these - self.alpha = 1; - self.drawmask = MASK_NORMAL; + //this.alpha = 1; // alpha is already set by the draw function + this.drawmask = MASK_NORMAL; return; } float alph; vector org = getpropertyvec(VF_ORIGIN); - if(!checkpvs(org, self)) // this makes sense as long as we don't support recursive warpzones + if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones alph = 0; - else if(self.fade_start) - alph = bound(0, (self.fade_end - vlen(org - self.origin - 0.5 * (self.mins + self.maxs))) / (self.fade_end - self.fade_start), 1); + else if(this.fade_start) + alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1); else alph = 1; - //printf("%v <-> %v\n", view_origin, self.origin + 0.5 * (self.mins + self.maxs)); - if(!hud && (self.ItemStatus & ITS_AVAILABLE)) - self.alpha = alph; + //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs)); + if(!hud && (this.ItemStatus & ITS_AVAILABLE)) + this.alpha = alph; if(alph <= 0) - self.drawmask = 0; + this.drawmask = 0; else - self.drawmask = MASK_NORMAL; + this.drawmask = MASK_NORMAL; } -void ItemRemove() -{SELFPARAM(); - if (self.mdl) - strunzone(self.mdl); +void ItemRemove(entity this) +{ + if(this.mdl) + strunzone(this.mdl); } NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) @@ -146,134 +153,138 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) if(sf & ISF_LOCATION) { - self.origin_x = ReadCoord(); - self.origin_y = ReadCoord(); - self.origin_z = ReadCoord(); - setorigin(self, self.origin); - self.oldorigin = self.origin; + this.origin_x = ReadCoord(); + this.origin_y = ReadCoord(); + this.origin_z = ReadCoord(); + setorigin(this, this.origin); + this.oldorigin = this.origin; } if(sf & ISF_ANGLES) { - self.angles_x = ReadAngle(); - self.angles_y = ReadAngle(); - self.angles_z = ReadAngle(); - self.move_angles = self.angles; + this.angles_x = ReadAngle(); + this.angles_y = ReadAngle(); + this.angles_z = ReadAngle(); } if(sf & ISF_SIZE) { float use_bigsize = ReadByte(); - setsize(self, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32'); + setsize(this, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32'); } if(sf & ISF_STATUS) // need to read/write status frist so model can handle simple, fb etc. { - self.ItemStatus = ReadByte(); + this.ItemStatus = ReadByte(); - Item_SetAlpha(self); + Item_SetAlpha(this); if(autocvar_cl_fullbright_items) - if(self.ItemStatus & ITS_ALLOWFB) - self.effects |= EF_FULLBRIGHT; + if(this.ItemStatus & ITS_ALLOWFB) + this.effects |= EF_FULLBRIGHT; - if(self.ItemStatus & ITS_POWERUP) + if(this.ItemStatus & ITS_POWERUP) { - if(self.ItemStatus & ITS_AVAILABLE) - self.effects |= (EF_ADDITIVE | EF_FULLBRIGHT); + if(this.ItemStatus & ITS_AVAILABLE) + this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT); else - self.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT); + this.effects &= ~(EF_ADDITIVE | EF_FULLBRIGHT); } } if(sf & ISF_MODEL) { - self.drawmask = MASK_NORMAL; - self.move_movetype = MOVETYPE_TOSS; - self.draw = ItemDraw; - self.solid = SOLID_TRIGGER; - //self.move_flags |= FL_ITEM; + this.drawmask = MASK_NORMAL; + set_movetype(this, MOVETYPE_TOSS); + if (isnew) IL_PUSH(g_drawables, this); + this.draw = ItemDraw; + this.solid = SOLID_TRIGGER; + //this.flags |= FL_ITEM; bool use_bigsize = ReadByte(); - self.fade_end = ReadShort(); - self.fade_start = ReadShort(); - if(self.fade_start && !autocvar_cl_items_nofade) - self.predraw = Item_PreDraw; + this.fade_end = ReadShort(); + this.fade_start = ReadShort(); + if(this.fade_start && !autocvar_cl_items_nofade) + setpredraw(this, Item_PreDraw); - if(self.mdl) - strunzone(self.mdl); + if(this.mdl) + strunzone(this.mdl); - self.mdl = ""; + this.mdl = ""; string _fn = ReadString(); - if(autocvar_cl_simple_items && (self.ItemStatus & ITS_ALLOWSI)) + if(autocvar_cl_simple_items && (this.ItemStatus & ITS_ALLOWSI)) { string _fn2 = substring(_fn, 0 , strlen(_fn) -4); - self.draw = ItemDrawSimple; + this.draw = ItemDrawSimple; if(fexists(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix))) - self.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix)); + this.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix)); else if(fexists(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix))) - self.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix)); + this.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix)); else if(fexists(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix))) - self.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix)); + this.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix)); else if(fexists(sprintf("%s%s.mdl", _fn2, autocvar_cl_simpleitems_postfix))) - self.mdl = strzone(sprintf("%s%s.mdl", _fn2, autocvar_cl_simpleitems_postfix)); + this.mdl = strzone(sprintf("%s%s.mdl", _fn2, autocvar_cl_simpleitems_postfix)); else { - self.draw = ItemDraw; - LOG_TRACE("Simple item requested for ", _fn, " but no model exists for it\n"); + this.draw = ItemDraw; + LOG_TRACE("Simple item requested for ", _fn, " but no model exists for it"); } } - if(self.draw != ItemDrawSimple) - self.mdl = strzone(_fn); + if(this.draw != ItemDrawSimple) + this.mdl = strzone(_fn); - if(self.mdl == "") - LOG_TRACE("^1WARNING!^7 self.mdl is unset for item ", self.classname, ", tell tZork about this!\n"); + if(this.mdl == "") + LOG_TRACE("^1WARNING!^7 this.mdl is unset for item ", this.classname, ", tell tZork about this!"); - precache_model(self.mdl); - _setmodel(self, self.mdl); + precache_model(this.mdl); + _setmodel(this, this.mdl); - setsize(self, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32'); + setsize(this, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32'); } if(sf & ISF_COLORMAP) - self.colormap = ReadShort(); + { + this.colormap = ReadShort(); + this.item_glowmod_x = ReadByte() / 255.0; + this.item_glowmod_y = ReadByte() / 255.0; + this.item_glowmod_z = ReadByte() / 255.0; + } if(sf & ISF_DROP) { - self.gravity = 1; - self.pushable = true; - //self.move_angles = '0 0 0'; - self.move_movetype = MOVETYPE_TOSS; - self.move_velocity_x = ReadCoord(); - self.move_velocity_y = ReadCoord(); - self.move_velocity_z = ReadCoord(); - self.velocity = self.move_velocity; - self.move_origin = self.oldorigin; - - if(!self.move_time) + this.gravity = 1; + this.pushable = true; + //this.angles = '0 0 0'; + set_movetype(this, MOVETYPE_TOSS); + this.velocity_x = ReadCoord(); + this.velocity_y = ReadCoord(); + this.velocity_z = ReadCoord(); + setorigin(this, this.oldorigin); + + if(!this.move_time) { - self.move_time = time; - self.spawntime = time; + this.move_time = time; + this.spawntime = time; } else - self.move_time = max(self.move_time, time); + this.move_time = max(this.move_time, time); } if(autocvar_cl_animate_items) { - if(self.ItemStatus & ITS_ANIMATE1) - self.move_avelocity = '0 180 0'; + if(this.ItemStatus & ITS_ANIMATE1) + this.avelocity = '0 180 0'; - if(self.ItemStatus & ITS_ANIMATE2) - self.move_avelocity = '0 -90 0'; + if(this.ItemStatus & ITS_ANIMATE2) + this.avelocity = '0 -90 0'; } - self.entremove = ItemRemove; + this.entremove = ItemRemove; return true; } @@ -283,7 +294,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) #ifdef SVQC bool ItemSend(entity this, entity to, int sf) { - if(self.gravity) + if(this.gravity) sf |= ISF_DROP; else sf &= ~ISF_DROP; @@ -291,19 +302,19 @@ bool ItemSend(entity this, entity to, int sf) WriteHeader(MSG_ENTITY, ENT_CLIENT_ITEM); WriteByte(MSG_ENTITY, sf); - //WriteByte(MSG_ENTITY, self.cnt); + //WriteByte(MSG_ENTITY, this.cnt); if(sf & ISF_LOCATION) { - WriteCoord(MSG_ENTITY, self.origin.x); - WriteCoord(MSG_ENTITY, self.origin.y); - WriteCoord(MSG_ENTITY, self.origin.z); + WriteCoord(MSG_ENTITY, this.origin.x); + WriteCoord(MSG_ENTITY, this.origin.y); + WriteCoord(MSG_ENTITY, this.origin.z); } if(sf & ISF_ANGLES) { - WriteAngle(MSG_ENTITY, self.angles_x); - WriteAngle(MSG_ENTITY, self.angles_y); - WriteAngle(MSG_ENTITY, self.angles_z); + WriteAngle(MSG_ENTITY, this.angles_x); + WriteAngle(MSG_ENTITY, this.angles_y); + WriteAngle(MSG_ENTITY, this.angles_z); } if(sf & ISF_SIZE) @@ -313,30 +324,35 @@ bool ItemSend(entity this, entity to, int sf) } if(sf & ISF_STATUS) - WriteByte(MSG_ENTITY, self.ItemStatus); + WriteByte(MSG_ENTITY, this.ItemStatus); if(sf & ISF_MODEL) { Pickup p = this.itemdef; WriteByte(MSG_ENTITY, p.instanceOfPowerup || p.instanceOfHealth || p.instanceOfArmor); - WriteShort(MSG_ENTITY, self.fade_end); - WriteShort(MSG_ENTITY, self.fade_start); + WriteShort(MSG_ENTITY, this.fade_end); + WriteShort(MSG_ENTITY, this.fade_start); - if(self.mdl == "") - LOG_TRACE("^1WARNING!^7 self.mdl is unset for item ", self.classname, "exspect a crash just aboute now\n"); + if(this.mdl == "") + LOG_TRACE("^1WARNING!^7 this.mdl is unset for item ", this.classname, "expect a crash just about now"); - WriteString(MSG_ENTITY, self.mdl); + WriteString(MSG_ENTITY, this.mdl); } if(sf & ISF_COLORMAP) - WriteShort(MSG_ENTITY, self.colormap); + { + WriteShort(MSG_ENTITY, this.colormap); + WriteByte(MSG_ENTITY, this.glowmod.x * 255.0); + WriteByte(MSG_ENTITY, this.glowmod.y * 255.0); + WriteByte(MSG_ENTITY, this.glowmod.z * 255.0); + } if(sf & ISF_DROP) { - WriteCoord(MSG_ENTITY, self.velocity.x); - WriteCoord(MSG_ENTITY, self.velocity.y); - WriteCoord(MSG_ENTITY, self.velocity.z); + WriteCoord(MSG_ENTITY, this.velocity.x); + WriteCoord(MSG_ENTITY, this.velocity.y); + WriteCoord(MSG_ENTITY, this.velocity.z); } return true; @@ -350,7 +366,7 @@ void ItemUpdate(entity this) void UpdateItemAfterTeleport(entity this) { - if(this.SendEntity3 == ItemSend) + if(getSendEntity(this) == ItemSend) ItemUpdate(this); } @@ -379,22 +395,22 @@ bool have_pickup_item(entity this) /* float Item_Customize() { - if(self.spawnshieldtime) + if(this.spawnshieldtime) return true; - if(self.weapons & ~other.weapons) + if(this.weapons & ~other.weapons) { - self.colormod = '0 0 0'; - self.glowmod = self.colormod; - self.alpha = 0.5 + 0.5 * g_ghost_items; // halfway more alpha + this.colormod = '0 0 0'; + this.glowmod = this.colormod; + this.alpha = 0.5 + 0.5 * g_ghost_items; // halfway more alpha return true; } else { if(g_ghost_items) { - self.colormod = stov(autocvar_g_ghost_items_color); - self.glowmod = self.colormod; - self.alpha = g_ghost_items; + this.colormod = stov(autocvar_g_ghost_items_color); + this.glowmod = this.colormod; + this.alpha = g_ghost_items; return true; } else @@ -442,7 +458,7 @@ void Item_Show (entity e, float mode) //setmodel(e, "null"); e.solid = SOLID_NOT; e.colormod = '0 0 0'; - e.glowmod = e.colormod; + //e.glowmod = e.colormod; e.spawnshieldtime = 1; e.ItemStatus &= ~ITS_AVAILABLE; }} @@ -465,120 +481,119 @@ void Item_Show (entity e, float mode) e.SendFlags |= ISF_STATUS; } -void Item_Think() -{SELFPARAM(); - self.nextthink = time; - if(self.origin != self.oldorigin) - ItemUpdate(self); +void Item_Think(entity this) +{ + this.nextthink = time; + if(this.origin != this.oldorigin) + ItemUpdate(this); } bool Item_ItemsTime_SpectatorOnly(GameItem it); -bool Item_ItemsTime_Allow(GameItem it, WepSet _weapons); +bool Item_ItemsTime_Allow(GameItem it); float Item_ItemsTime_UpdateTime(entity e, float t); void Item_ItemsTime_SetTime(entity e, float t); void Item_ItemsTime_SetTimesForAllPlayers(); -void Item_Respawn () -{SELFPARAM(); - Item_Show(self, 1); +void Item_Respawn (entity this) +{ + Item_Show(this, 1); // this is ugly... - if(self.items == ITEM_Strength.m_itemid) - 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, SND_SHIELD_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound + if(this.items == ITEM_Strength.m_itemid) + sound (this, CH_TRIGGER, SND_STRENGTH_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound + else if(this.items == ITEM_Shield.m_itemid) + sound (this, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound else - sound (self, CH_TRIGGER, SND_ITEMRESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound - setorigin (self, self.origin); + sound (this, CH_TRIGGER, SND_ITEMRESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound + setorigin(this, this.origin); - if (Item_ItemsTime_Allow(self.itemdef, self.weapons)) + if (Item_ItemsTime_Allow(this.itemdef) || this.weapons & WEPSET_SUPERWEAPONS) { - float t = Item_ItemsTime_UpdateTime(self, 0); - Item_ItemsTime_SetTime(self, t); + float t = Item_ItemsTime_UpdateTime(this, 0); + Item_ItemsTime_SetTime(this, t); Item_ItemsTime_SetTimesForAllPlayers(); } - self.think = Item_Think; - self.nextthink = time; + setthink(this, Item_Think); + this.nextthink = time; - //Send_Effect(EFFECT_ITEM_RESPAWN, self.origin + self.mins_z * '0 0 1' + '0 0 48', '0 0 0', 1); - Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(self), '0 0 0', 1); + //Send_Effect(EFFECT_ITEM_RESPAWN, this.origin + this.mins_z * '0 0 1' + '0 0 48', '0 0 0', 1); + Send_Effect(EFFECT_ITEM_RESPAWN, CENTER_OR_VIEWOFS(this), '0 0 0', 1); } -void Item_RespawnCountdown () -{SELFPARAM(); - if(self.count >= ITEM_RESPAWN_TICKS) +void Item_RespawnCountdown (entity this) +{ + if(this.count >= ITEM_RESPAWN_TICKS) { - if(self.waypointsprite_attached) - WaypointSprite_Kill(self.waypointsprite_attached); - Item_Respawn(); + if(this.waypointsprite_attached) + WaypointSprite_Kill(this.waypointsprite_attached); + Item_Respawn(this); } else { - self.nextthink = time + 1; - self.count += 1; - if(self.count == 1) + this.nextthink = time + 1; + this.count += 1; + if(this.count == 1) { MUTATOR_CALLHOOK(Item_RespawnCountdown, string_null, '0 0 0'); do { { - entity wi = Weapons_from(self.weapon); + entity wi = Weapons_from(this.weapon); if (wi != WEP_Null) { - entity wp = WaypointSprite_Spawn(WP_Weapon, 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_Weapon); + entity wp = WaypointSprite_Spawn(WP_Weapon, 0, 0, this, '0 0 64', NULL, 0, this, waypointsprite_attached, true, RADARICON_Weapon); wp.wp_extra = wi.m_id; break; } } { - entity ii = self.itemdef; + entity ii = this.itemdef; if (ii != NULL) { - entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, self, '0 0 64', world, 0, self, waypointsprite_attached, true, RADARICON_Item); + entity wp = WaypointSprite_Spawn(WP_Item, 0, 0, this, '0 0 64', NULL, 0, this, waypointsprite_attached, true, RADARICON_Item); wp.wp_extra = ii.m_id; break; } } } while (0); - if(self.waypointsprite_attached) + if(this.waypointsprite_attached) { - GameItem def = self.itemdef; + GameItem def = this.itemdef; if (Item_ItemsTime_SpectatorOnly(def)) - WaypointSprite_UpdateRule(self.waypointsprite_attached, 0, SPRITERULE_SPECTATOR); - WaypointSprite_UpdateBuildFinished(self.waypointsprite_attached, time + ITEM_RESPAWN_TICKS); + WaypointSprite_UpdateRule(this.waypointsprite_attached, 0, SPRITERULE_SPECTATOR); + WaypointSprite_UpdateBuildFinished(this.waypointsprite_attached, time + ITEM_RESPAWN_TICKS); } } - if(self.waypointsprite_attached) + if(this.waypointsprite_attached) { - setself(self.waypointsprite_attached); - FOREACH_CLIENT(IS_REAL_CLIENT(it), LAMBDA( - if(self.waypointsprite_visible_for_player(it)) + FOREACH_CLIENT(IS_REAL_CLIENT(it), { + if(this.waypointsprite_attached.waypointsprite_visible_for_player(this.waypointsprite_attached, it, it)) { msg_entity = it; soundto(MSG_ONE, this, CH_TRIGGER, SND(ITEMRESPAWNCOUNTDOWN), VOL_BASE, ATTEN_NORM); // play respawn sound } - )); - setself(this); + }); - WaypointSprite_Ping(self.waypointsprite_attached); - //WaypointSprite_UpdateHealth(self.waypointsprite_attached, self.count); + WaypointSprite_Ping(this.waypointsprite_attached); + //WaypointSprite_UpdateHealth(this.waypointsprite_attached, this.count); } } } -void Item_RespawnThink() -{SELFPARAM(); - self.nextthink = time; - if(self.origin != self.oldorigin) - ItemUpdate(self); +void Item_RespawnThink(entity this) +{ + this.nextthink = time; + if(this.origin != this.oldorigin) + ItemUpdate(this); - if(time >= self.wait) - Item_Respawn(); + if(time >= this.wait) + Item_Respawn(this); } void Item_ScheduleRespawnIn(entity e, float t) { - if (Item_ItemsTime_Allow(e.itemdef, e.weapons)) + // if the respawn time is longer than 10 seconds, show a waypoint, otherwise, just respawn normally + if ((Item_ItemsTime_Allow(e.itemdef) || e.weapons & WEPSET_SUPERWEAPONS) && (t - ITEM_RESPAWN_TICKS) > 0) { - e.think = Item_RespawnCountdown; + setthink(e, Item_RespawnCountdown); e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS); e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS; e.count = 0; @@ -588,7 +603,7 @@ void Item_ScheduleRespawnIn(entity e, float t) } else { - e.think = Item_RespawnThink; + setthink(e, Item_RespawnThink); e.nextthink = time; e.scheduledrespawntime = time + t; e.wait = time + t; @@ -609,7 +624,7 @@ void Item_ScheduleRespawn(entity e) void Item_ScheduleInitialRespawn(entity e) { Item_Show(e, 0); - Item_ScheduleRespawnIn(e, game_starttime - time + ITEM_RESPAWNTIME_INITIAL(e)); + Item_ScheduleRespawnIn(e, game_starttime - time + ((e.respawntimestart) ? e.respawntimestart : ITEM_RESPAWNTIME_INITIAL(e))); } float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax, float mode) @@ -637,7 +652,7 @@ float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax return false; -:YEAH +LABEL(YEAH) switch(mode) { case ITEM_MODE_FUEL: @@ -657,21 +672,30 @@ float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax float Item_GiveTo(entity item, entity player) { - float _switchweapon; float pickedup; // if nothing happens to player, just return without taking the item pickedup = false; - _switchweapon = false; + int _switchweapon = 0; // in case the player has autoswitch enabled do the following: // if the player is using their best weapon before items are given, they // probably want to switch to an even better weapon after items are given - if (player.autoswitch) - if (PS(player).m_switchweapon == w_getbestweapon(player)) - _switchweapon = true; - if (!(player.weapons & WepSet_FromWeapon(PS(player).m_switchweapon))) - _switchweapon = true; + if(player.autoswitch) + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(player.(weaponentity).m_weapon != WEP_Null || slot == 0) + { + if(player.(weaponentity).m_switchweapon == w_getbestweapon(player, weaponentity)) + _switchweapon |= BIT(slot); + + if(!(player.weapons & WepSet_FromWeapon(player.(weaponentity).m_switchweapon))) + _switchweapon |= BIT(slot); + } + } + } pickedup |= Item_GiveAmmoTo(item, player, ammo_fuel, g_pickup_fuel_max, ITEM_MODE_FUEL); pickedup |= Item_GiveAmmoTo(item, player, ammo_shells, g_pickup_shells_max, ITEM_MODE_NONE); @@ -691,16 +715,29 @@ float Item_GiveTo(entity item, entity player) if (w || (item.spawnshieldtime && item.pickup_anyway > 0)) { pickedup = true; - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if(w & (it.m_wepset)) { - W_DropEvent(wr_pickup, player, it.m_id, item); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(player.(weaponentity).m_weapon != WEP_Null || slot == 0) + W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity); + } W_GiveWeapon(player, it.m_id); } - )); + }); } } + if (item.itemdef.instanceOfPowerup) + { + if ((item.itemdef == ITEM_JetpackRegen) && !(player.items & IT_FUEL_REGEN)) + Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_FUELREGEN_GOT); + else if ((item.itemdef == ITEM_Jetpack) && !(player.items & IT_JETPACK)) + Send_Notification(NOTIF_ONE, player, MSG_CENTER, CENTER_ITEM_JETPACK_GOT); + } + int its; if((its = (item.items - (item.items & player.items)) & IT_PICKUPMASK)) { @@ -725,7 +762,7 @@ float Item_GiveTo(entity item, entity player) player.superweapons_finished = max(player.superweapons_finished, time) + item.superweapons_finished; } -:skip +LABEL(skip) // always eat teamed entities if(item.team) @@ -737,45 +774,58 @@ float Item_GiveTo(entity item, entity player) // crude hack to enforce switching weapons if(g_cts && item.itemdef.instanceOfWeaponPickup) { - W_SwitchWeapon_Force(player, Weapons_from(item.weapon)); + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(player.(weaponentity).m_weapon != WEP_Null || slot == 0) + W_SwitchWeapon_Force(player, Weapons_from(item.weapon), weaponentity); + } return 1; } - if (_switchweapon) - if (PS(player).m_switchweapon != w_getbestweapon(player)) - W_SwitchWeapon_Force(player, w_getbestweapon(player)); + if(_switchweapon) + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(_switchweapon & BIT(slot)) + if(player.(weaponentity).m_switchweapon != w_getbestweapon(player, weaponentity)) + W_SwitchWeapon_Force(player, w_getbestweapon(player, weaponentity), weaponentity); + } + } return 1; } -void Item_Touch() +void Item_Touch(entity this, entity toucher) { - SELFPARAM(); // remove the item if it's currnetly in a NODROP brush or hits a NOIMPACT surface (such as sky) if (this.classname == "droppedweapon") { if (ITEM_TOUCH_NEEDKILL()) { - remove(this); + delete(this); return; } } - if(!(other.flags & FL_PICKUPITEMS) - || other.frozen - || other.deadflag + if(!(toucher.flags & FL_PICKUPITEMS) + || STAT(FROZEN, toucher) + || IS_DEAD(toucher) || (this.solid != SOLID_TRIGGER) - || (this.owner == other) + || (this.owner == toucher) || (time < this.item_spawnshieldtime) ) { return; } - switch (MUTATOR_CALLHOOK(ItemTouch, this, other)) + switch (MUTATOR_CALLHOOK(ItemTouch, this, toucher)) { case MUT_ITEMTOUCH_RETURN: { return; } - case MUT_ITEMTOUCH_PICKUP: { goto pickup; } + case MUT_ITEMTOUCH_PICKUP: { toucher = M_ARGV(1, entity); goto pickup; } } + toucher = M_ARGV(1, entity); + if (this.classname == "droppedweapon") { this.strength_finished = max(0, this.strength_finished - time); @@ -783,7 +833,7 @@ void Item_Touch() this.superweapons_finished = max(0, this.superweapons_finished - time); } entity it = this.itemdef; - bool gave = ITEM_HANDLE(Pickup, it, this, other); + bool gave = ITEM_HANDLE(Pickup, it, this, toucher); if (!gave) { if (this.classname == "droppedweapon") @@ -796,30 +846,29 @@ void Item_Touch() return; } - :pickup +LABEL(pickup) - other.last_pickup = time; + toucher.last_pickup = time; Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1); - _sound (other, CH_TRIGGER, (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM); + _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM); if (this.classname == "droppedweapon") - remove (this); + delete (this); else if (this.spawnshieldtime) { entity e; if(this.team) { RandomSelection_Init(); - for(entity head = world; (head = findfloat(head, team, this.team)); ) + IL_EACH(g_items, it.team == this.team, { - if(head.flags & FL_ITEM) - if(head.classname != "item_flag_team" && head.classname != "item_key_team") + if(it.classname != "item_flag_team" && it.classname != "item_kh_key") { - Item_Show(head, -1); - RandomSelection_Add(head, 0, string_null, head.cnt, 0); + Item_Show(it, -1); + RandomSelection_AddEnt(it, it.cnt, 0); } - } + }); e = RandomSelection_chosen_ent; } @@ -836,7 +885,7 @@ void Item_Reset(entity this) if (this.classname != "droppedweapon") { - this.think = Item_Think; + setthink(this, Item_Think); this.nextthink = time; if (this.waypointsprite_attached) @@ -846,49 +895,50 @@ void Item_Reset(entity this) Item_ScheduleInitialRespawn(this); } } -void Item_Reset_self() { SELFPARAM(); Item_Reset(this); } -void Item_FindTeam() -{SELFPARAM(); - entity head, e; +void Item_FindTeam(entity this) +{ + entity e; - if(self.effects & EF_NODRAW) + if(this.effects & EF_NODRAW) { // marker for item team search - LOG_TRACE("Initializing item team ", ftos(self.team), "\n"); + LOG_TRACE("Initializing item team ", ftos(this.team)); RandomSelection_Init(); - for(head = world; (head = findfloat(head, team, self.team)); ) - if(head.flags & FL_ITEM) - if(head.classname != "item_flag_team" && head.classname != "item_key_team") - RandomSelection_Add(head, 0, string_null, head.cnt, 0); + IL_EACH(g_items, it.team == this.team, + { + if(it.classname != "item_flag_team" && it.classname != "item_kh_key") + RandomSelection_AddEnt(it, it.cnt, 0); + }); + e = RandomSelection_chosen_ent; e.state = 0; Item_Show(e, 1); - for(head = world; (head = findfloat(head, team, self.team)); ) - if(head.flags & FL_ITEM) - if(head.classname != "item_flag_team" && head.classname != "item_key_team") + IL_EACH(g_items, it.team == this.team, { - if(head != e) + if(it.classname != "item_flag_team" && it.classname != "item_kh_key") { - // make it a non-spawned item - Item_Show(head, -1); - head.state = 1; // state 1 = initially hidden item + if(it != e) + { + // make it non-spawned + Item_Show(it, -1); + it.state = 1; // state 1 = initially hidden item, apparently + } + it.effects &= ~EF_NODRAW; } - head.effects &= ~EF_NODRAW; - } + }); - Item_Reset(self); + Item_Reset(this); } } // Savage: used for item garbage-collection -// TODO: perhaps nice special effect? -void RemoveItem() -{SELFPARAM(); - if(wasfreed(self) || !self) { return; } - Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(self), '0 0 0', 1); - remove(self); +void RemoveItem(entity this) +{ + if(wasfreed(this) || !this) { return; } + Send_Effect(EFFECT_ITEM_PICKUP, CENTER_OR_VIEWOFS(this), '0 0 0', 1); + delete(this); } // pickup evaluation functions @@ -953,7 +1003,7 @@ float commodity_pickupevalfunc(entity player, entity item) c = 0; // Detect needed ammo - FOREACH(Weapons, it != WEP_Null, LAMBDA( + FOREACH(Weapons, it != WEP_Null, { if(!(player.weapons & (it.m_wepset))) continue; @@ -969,7 +1019,7 @@ float commodity_pickupevalfunc(entity player, entity item) need_plasma = true; else if(it.items & ITEM_JetpackFuel.m_itemid) need_fuel = true; - )); + }); // TODO: figure out if the player even has the weapon this ammo is for? // may not affect strategy much though... @@ -1008,10 +1058,10 @@ float commodity_pickupevalfunc(entity player, entity item) return item.bot_pickupbasevalue * c; } -void Item_Damage(entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) +void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) { if(ITEM_DAMAGE_NEEDKILL(deathtype)) - RemoveItem(); + RemoveItem(this); } void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter) @@ -1049,11 +1099,12 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.weapons = WepSet_FromWeapon(Weapons_from(weaponid)); this.flags = FL_ITEM | itemflags; + IL_PUSH(g_items, this); if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item { startitem_failed = true; - remove(this); + delete(this); return; } @@ -1062,10 +1113,10 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default { this.reset = SUB_Remove; // it's a dropped weapon - this.movetype = MOVETYPE_TOSS; + set_movetype(this, MOVETYPE_TOSS); // Savage: remove thrown items after a certain period of time ("garbage collection") - this.think = RemoveItem; + setthink(this, RemoveItem); this.nextthink = time + 20; this.takedamage = DAMAGE_YES; @@ -1082,7 +1133,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if (trace_dpstartcontents & DPCONTENTS_NODROP) { startitem_failed = true; - remove(this); + delete(this); return; } } @@ -1091,7 +1142,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(!have_pickup_item(this)) { startitem_failed = true; - remove (this); + delete (this); return; } @@ -1103,9 +1154,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(this.spawnflags & 1) this.noalign = 1; if (this.noalign > 0) - this.movetype = MOVETYPE_NONE; + set_movetype(this, MOVETYPE_NONE); else - this.movetype = MOVETYPE_TOSS; + set_movetype(this, MOVETYPE_TOSS); // do item filtering according to game mode and other things if (this.noalign <= 0) { @@ -1116,7 +1167,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.SendFlags |= ISF_SIZE; // note droptofloor returns false if stuck/or would fall too far if (!this.noalign) - WITH(entity, self, this, droptofloor()); + droptofloor(this); waypoint_spawnforitem(this); } @@ -1136,16 +1187,12 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(autocvar_spawn_debug >= 2) { - for(entity otheritem = findradius(this.origin, 3); otheritem; otheritem = otheritem.chain) - { - // why not flags & fl_item? - if(otheritem.is_item) - { - LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin)); - LOG_TRACE(" vs ", otheritem.netname, vtos(otheritem.origin), "\n"); - error("Mapper sucks."); - } - } + // why not flags & fl_item? + FOREACH_ENTITY_RADIUS(this.origin, 3, it.is_item, { + LOG_TRACE("XXX Found duplicated item: ", itemname, vtos(this.origin)); + LOG_TRACE(" vs ", it.netname, vtos(it.origin)); + error("Mapper sucks."); + }); this.is_item = true; } @@ -1169,7 +1216,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.bot_pickupbasevalue = pickupbasevalue; this.mdl = this.model ? this.model : strzone(this.item_model_ent.model_str()); this.netname = itemname; - this.touch = Item_Touch; + settouch(this, Item_Touch); setmodel(this, MDL_Null); // precision set below //this.effects |= EF_LOWPRECISION; @@ -1180,7 +1227,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if (!(this.spawnflags & 1024)) { if(def.instanceOfPowerup) this.ItemStatus |= ITS_ANIMATE1; - + if(this.armorvalue || this.health) this.ItemStatus |= ITS_ANIMATE2; } @@ -1193,7 +1240,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.gravity = 1; if (!(this.spawnflags & 1024)) this.ItemStatus |= ITS_ANIMATE1; - this.ItemStatus |= ISF_COLORMAP; + this.SendFlags |= ISF_COLORMAP; } this.state = 0; @@ -1214,7 +1261,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if (MUTATOR_CALLHOOK(Item_Spawn, this)) { startitem_failed = true; - remove(this); + delete(this); return; } } @@ -1406,92 +1453,95 @@ spawnfunc(item_invincible) // compatibility: spawnfunc(item_quad) { this.classname = "item_strength";spawnfunc_item_strength(this);} -void target_items_use() -{SELFPARAM(); - if(activator.classname == "droppedweapon") +void target_items_use(entity this, entity actor, entity trigger) +{ + if(actor.classname == "droppedweapon") { - EXACTTRIGGER_TOUCH; - remove(activator); + EXACTTRIGGER_TOUCH(this, trigger); + delete(actor); return; } - if (!IS_PLAYER(activator)) + if (!IS_PLAYER(actor)) return; - if(activator.deadflag != DEAD_NO) + if(IS_DEAD(actor)) return; - EXACTTRIGGER_TOUCH; + if(trigger.solid == SOLID_TRIGGER) + { + EXACTTRIGGER_TOUCH(this, trigger); + } - entity e; - for(e = world; (e = find(e, classname, "droppedweapon")); ) - if(e.enemy == activator) - remove(e); + IL_EACH(g_items, it.enemy == actor && it.classname == "droppedweapon", + { + delete(it); + }); - if(GiveItems(activator, 0, tokenize_console(self.netname))) - centerprint(activator, self.message); + if(GiveItems(actor, 0, tokenize_console(this.netname))) + centerprint(actor, this.message); } spawnfunc(target_items) { - float n, i; + int n, j; string s; - self.use = target_items_use; - if(!self.strength_finished) - self.strength_finished = autocvar_g_balance_powerup_strength_time; - if(!self.invincible_finished) - self.invincible_finished = autocvar_g_balance_powerup_invincible_time; - if(!self.superweapons_finished) - self.superweapons_finished = autocvar_g_balance_superweapons_time; + this.use = target_items_use; + if(!this.strength_finished) + this.strength_finished = autocvar_g_balance_powerup_strength_time; + if(!this.invincible_finished) + this.invincible_finished = autocvar_g_balance_powerup_invincible_time; + if(!this.superweapons_finished) + this.superweapons_finished = autocvar_g_balance_superweapons_time; - n = tokenize_console(self.netname); + n = tokenize_console(this.netname); if(argv(0) == "give") { - self.netname = substring(self.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)); + this.netname = substring(this.netname, argv_start_index(1), argv_end_index(-1) - argv_start_index(1)); } else { - for(i = 0; i < n; ++i) + for(j = 0; j < n; ++j) { - if (argv(i) == "unlimited_ammo") self.items |= IT_UNLIMITED_AMMO; - else if(argv(i) == "unlimited_weapon_ammo") self.items |= IT_UNLIMITED_WEAPON_AMMO; - else if(argv(i) == "unlimited_superweapons") self.items |= IT_UNLIMITED_SUPERWEAPONS; - else if(argv(i) == "strength") self.items |= ITEM_Strength.m_itemid; - else if(argv(i) == "invincible") self.items |= ITEM_Shield.m_itemid; - else if(argv(i) == "superweapons") self.items |= IT_SUPERWEAPON; - else if(argv(i) == "jetpack") self.items |= ITEM_Jetpack.m_itemid; - else if(argv(i) == "fuel_regen") self.items |= ITEM_JetpackRegen.m_itemid; + if (argv(j) == "unlimited_ammo") this.items |= IT_UNLIMITED_AMMO; + else if(argv(j) == "unlimited_weapon_ammo") this.items |= IT_UNLIMITED_WEAPON_AMMO; + else if(argv(j) == "unlimited_superweapons") this.items |= IT_UNLIMITED_SUPERWEAPONS; + else if(argv(j) == "strength") this.items |= ITEM_Strength.m_itemid; + else if(argv(j) == "invincible") this.items |= ITEM_Shield.m_itemid; + else if(argv(j) == "superweapons") this.items |= IT_SUPERWEAPON; + else if(argv(j) == "jetpack") this.items |= ITEM_Jetpack.m_itemid; + else if(argv(j) == "fuel_regen") this.items |= ITEM_JetpackRegen.m_itemid; else { - FOREACH(Weapons, it != WEP_Null, LAMBDA( - s = W_UndeprecateName(argv(i)); + FOREACH(Weapons, it != WEP_Null, { + s = W_UndeprecateName(argv(j)); if(s == it.netname) { - self.weapons |= (it.m_wepset); - if(self.spawnflags == 0 || self.spawnflags == 2) + this.weapons |= (it.m_wepset); + if(this.spawnflags == 0 || this.spawnflags == 2) it.wr_init(it); break; } - )); + }); } } string itemprefix, valueprefix; - if(self.spawnflags == 0) + if(this.spawnflags == 0) { itemprefix = ""; valueprefix = ""; } - else if(self.spawnflags == 1) + else if(this.spawnflags == 1) { itemprefix = "max "; valueprefix = "max "; } - else if(self.spawnflags == 2) + else if(this.spawnflags == 2) { itemprefix = "min "; valueprefix = "min "; } - else if(self.spawnflags == 4) + else if(this.spawnflags == 4) { itemprefix = "minus "; valueprefix = "max "; @@ -1502,37 +1552,34 @@ spawnfunc(target_items) itemprefix = valueprefix = string_null; } - self.netname = ""; - self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & IT_UNLIMITED_WEAPON_AMMO), "unlimited_weapon_ammo"); - self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons"); - self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.strength_finished * boolean(self.items & ITEM_Strength.m_itemid), "strength"); - self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.invincible_finished * boolean(self.items & ITEM_Shield.m_itemid), "invincible"); - self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.superweapons_finished * boolean(self.items & IT_SUPERWEAPON), "superweapons"); - self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & ITEM_Jetpack.m_itemid), "jetpack"); - self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, boolean(self.items & ITEM_JetpackRegen.m_itemid), "fuel_regen"); - if(self.ammo_shells != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_shells), "shells"); - if(self.ammo_nails != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_nails), "nails"); - if(self.ammo_rockets != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_rockets), "rockets"); - if(self.ammo_cells != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_cells), "cells"); - if(self.ammo_plasma != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_plasma), "plasma"); - if(self.ammo_fuel != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_fuel), "fuel"); - if(self.health != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.health), "health"); - if(self.armorvalue != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.health), "armor"); - FOREACH(Weapons, it != WEP_Null, LAMBDA(self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.weapons & (it.m_wepset)), it.netname))); - } - self.netname = strzone(self.netname); - //print(self.netname, "\n"); - - n = tokenize_console(self.netname); - for(i = 0; i < n; ++i) - { - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if(argv(i) == it.netname) - { - it.wr_init(it); - break; - } - )); + this.netname = ""; + this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_WEAPON_AMMO), "unlimited_weapon_ammo"); + this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons"); + this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.strength_finished * boolean(this.items & ITEM_Strength.m_itemid), "strength"); + this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.invincible_finished * boolean(this.items & ITEM_Shield.m_itemid), "invincible"); + this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, this.superweapons_finished * boolean(this.items & IT_SUPERWEAPON), "superweapons"); + this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & ITEM_Jetpack.m_itemid), "jetpack"); + this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, boolean(this.items & ITEM_JetpackRegen.m_itemid), "fuel_regen"); + if(this.ammo_shells != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.ammo_shells), "shells"); + if(this.ammo_nails != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.ammo_nails), "nails"); + if(this.ammo_rockets != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.ammo_rockets), "rockets"); + if(this.ammo_cells != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.ammo_cells), "cells"); + if(this.ammo_plasma != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.ammo_plasma), "plasma"); + if(this.ammo_fuel != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.ammo_fuel), "fuel"); + if(this.health != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.health), "health"); + if(this.armorvalue != 0) this.netname = sprintf("%s %s%d %s", this.netname, valueprefix, max(0, this.armorvalue), "armor"); + FOREACH(Weapons, it != WEP_Null, this.netname = sprintf("%s %s%d %s", this.netname, itemprefix, !!(this.weapons & (it.m_wepset)), it.netname)); + } + this.netname = strzone(this.netname); + //print(this.netname, "\n"); + + n = tokenize_console(this.netname); + for(j = 0; j < n; ++j) + { + FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, { + it.wr_init(it); + break; + }); } } @@ -1598,19 +1645,19 @@ float GiveWeapon(entity e, float wpn, float op, float val) return (v0 != v1); } -void GiveSound(entity e, float v0, float v1, float t, string snd_incr, string snd_decr) +void GiveSound(entity e, float v0, float v1, float t, Sound snd_incr, Sound snd_decr) { if(v1 == v0) return; if(v1 <= v0 - t) { - if(snd_decr != "") - _sound (e, CH_TRIGGER, snd_decr, VOL_BASE, ATTEN_NORM); + if(snd_decr != NULL) + 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); + if(snd_incr != NULL) + sound (e, CH_TRIGGER, snd_incr, VOL_BASE, ATTEN_NORM); } } @@ -1622,9 +1669,8 @@ void GiveRot(entity e, float v0, float v1, .float rotfield, float rottime, .floa e.(regenfield) = max(e.(regenfield), time + regentime); } float GiveItems(entity e, float beginarg, float endarg) -{SELFPARAM(); +{ float got, i, val, op; - float _switchweapon; string cmd; val = 999; @@ -1632,10 +1678,18 @@ float GiveItems(entity e, float beginarg, float endarg) got = 0; - _switchweapon = false; - if (e.autoswitch) - if (PS(e).m_switchweapon == w_getbestweapon(e)) - _switchweapon = true; + int _switchweapon = 0; + + if(e.autoswitch) + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(e.(weaponentity).m_weapon != WEP_Null || slot == 0) + if(e.(weaponentity).m_switchweapon == w_getbestweapon(e, weaponentity)) + _switchweapon |= BIT(slot); + } + } e.strength_finished = max(0, e.strength_finished - time); e.invincible_finished = max(0, e.invincible_finished - time); @@ -1693,10 +1747,7 @@ float GiveItems(entity e, float beginarg, float endarg) got += GiveValue(e, health, op, val); got += GiveValue(e, armorvalue, op, val); case "allweapons": - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if(!(it.spawnflags & WEP_FLAG_MUTATORBLOCKED)) - got += GiveWeapon(e, it.m_id, op, val); - )); + FOREACH(Weapons, it != WEP_Null && !(it.spawnflags & WEP_FLAG_MUTATORBLOCKED), got += GiveWeapon(e, it.m_id, op, val)); case "allammo": got += GiveValue(e, ammo_cells, op, val); got += GiveValue(e, ammo_plasma, op, val); @@ -1755,42 +1806,39 @@ float GiveItems(entity e, float beginarg, float endarg) got += GiveValue(e, ammo_fuel, op, val); break; default: - FOREACH(Weapons, it != WEP_Null, LAMBDA( - if(cmd == it.netname) - { - got += GiveWeapon(e, it.m_id, op, val); - break; - } - )); + FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(cmd) == it.netname, { + got += GiveWeapon(e, it.m_id, op, val); + break; + }); break; } val = 999; op = OP_SET; } - 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); - FOREACH(Weapons, it != WEP_Null, LAMBDA( - POSTGIVE_WEAPON(e, it, SND(WEAPONPICKUP), string_null); + POSTGIVE_BIT(e, items, ITEM_JetpackRegen.m_itemid, SND_ITEMPICKUP, SND_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, SND_Null); + FOREACH(Weapons, it != WEP_Null, { + POSTGIVE_WEAPON(e, it, SND_WEAPONPICKUP, SND_Null); if(!(save_weapons & (it.m_wepset))) if(e.weapons & (it.m_wepset)) it.wr_init(it); - )); - 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); + }); + POSTGIVE_VALUE(e, strength_finished, 1, SND_POWERUP, SND_POWEROFF); + POSTGIVE_VALUE(e, invincible_finished, 1, SND_Shield, SND_POWEROFF); + POSTGIVE_VALUE(e, ammo_nails, 0, SND_ITEMPICKUP, SND_Null); + POSTGIVE_VALUE(e, ammo_cells, 0, SND_ITEMPICKUP, SND_Null); + POSTGIVE_VALUE(e, ammo_plasma, 0, SND_ITEMPICKUP, SND_Null); + POSTGIVE_VALUE(e, ammo_shells, 0, SND_ITEMPICKUP, SND_Null); + POSTGIVE_VALUE(e, ammo_rockets, 0, SND_ITEMPICKUP, SND_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, SND_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, SND_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, SND_Null); if(e.superweapons_finished <= 0) - if(self.weapons & WEPSET_SUPERWEAPONS) + if(e.weapons & WEPSET_SUPERWEAPONS) e.superweapons_finished = autocvar_g_balance_superweapons_time; if(e.strength_finished <= 0) @@ -1806,10 +1854,23 @@ float GiveItems(entity e, float beginarg, float endarg) else e.superweapons_finished += time; - if (!(e.weapons & WepSet_FromWeapon(PS(e).m_switchweapon))) - _switchweapon = true; + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(e.(weaponentity).m_weapon != WEP_Null || slot == 0) + if(!(e.weapons & WepSet_FromWeapon(e.(weaponentity).m_switchweapon))) + _switchweapon |= BIT(slot); + } + if(_switchweapon) - W_SwitchWeapon_Force(e, w_getbestweapon(e)); + { + for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) + { + .entity weaponentity = weaponentities[slot]; + if(_switchweapon & BIT(slot)) + W_SwitchWeapon_Force(e, w_getbestweapon(e, weaponentity), weaponentity); + } + } return got; }