]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/t_items.qc
Merge remote branch 'origin/terencehill/powerups_respawntime_fix'
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / t_items.qc
index 828c8104999d3fc0b0a1abfb85a74dc16881fa01..b26c840ff0c8834ba446c01939fe8760095a95c1 100644 (file)
@@ -168,7 +168,7 @@ void Item_Show (entity e, float mode)
                e.spawnshieldtime = 1;
        }
 
-       if (e.strength_finished || e.invincible_finished)
+       if (e.items & (IT_STRENGTH | IT_INVINCIBLE))
                e.effects |= EF_ADDITIVE | EF_FULLBRIGHT;
        if (autocvar_g_nodepthtestitems)
                e.effects |= EF_NODEPTHTEST;
@@ -239,7 +239,7 @@ void Item_RespawnCountdown (void)
                                if(wi)
                                {
                                        name = wi.model2;
-                                       rgb = '0 0 0';
+                                       rgb = '1 0 0';
                                }
                        }
                        if(!name)
@@ -440,7 +440,7 @@ float Item_GiveTo(entity item, entity player)
                pickedup |= Item_GiveAmmoTo(item, player, armorvalue, item.max_armorvalue, ITEM_MODE_ARMOR);
 
                if (item.flags & FL_WEAPON)
-               if ((it = item.weapons - (item.weapons & player.weapons)) || (item.spawnshieldtime && g_pickup_weapons_anyway))
+               if ((it = item.weapons - (item.weapons & player.weapons)) || (item.spawnshieldtime && self.pickup_anyway))
                {
                        pickedup = TRUE;
                        for(i = WEP_FIRST; i <= WEP_LAST; ++i)
@@ -483,7 +483,6 @@ float Item_GiveTo(entity item, entity player)
        if (!pickedup)
                return 0;
 
-       sound (player, CH_TRIGGER, item.item_pickupsound, VOL_BASE, ATTN_NORM);
        if (_switchweapon)
                if (player.switchweapon != w_getbestweapon(player))
                        W_SwitchWeapon_Force(player, w_getbestweapon(player));
@@ -510,12 +509,29 @@ void Item_Touch (void)
        if (self.owner == other)
                return;
 
+       if (self.classname == "droppedweapon")
+       {
+               self.strength_finished = max(0, self.strength_finished - time);
+               self.invincible_finished = max(0, self.invincible_finished - time);
+               self.superweapons_finished = max(0, self.superweapons_finished - time);
+       }
+
        if(!Item_GiveTo(self, other))
+       {
+               if (self.classname == "droppedweapon")
+               {
+                       // undo what we did above
+                       self.strength_finished += time;
+                       self.invincible_finished += time;
+                       self.superweapons_finished += time;
+               }
                return;
+       }
 
        other.last_pickup = time;
 
        pointparticles(particleeffectnum("item_pickup"), self.origin, '0 0 0', 1);
+       sound (other, CH_TRIGGER, self.item_pickupsound, VOL_BASE, ATTN_NORM);
 
        if (self.classname == "droppedweapon")
                remove (self);
@@ -542,6 +558,24 @@ void Item_Touch (void)
        }
 }
 
+void Item_Reset()
+{
+       Item_Show(self, !self.state);
+       setorigin (self, self.origin);
+
+       if(self.classname != "droppedweapon")
+       {
+               self.think = SUB_Null;
+               self.nextthink = 0;
+
+               if(self.waypointsprite_attached)
+                       WaypointSprite_Kill(self.waypointsprite_attached);
+
+               if((self.flags & FL_POWERUP) | (self.weapons & WEPBIT_SUPERWEAPONS)) // do not spawn powerups initially!
+                       Item_ScheduleInitialRespawn(self);
+       }
+}
+
 void Item_FindTeam()
 {
        entity head, e;
@@ -568,22 +602,10 @@ void Item_FindTeam()
                        head.effects &~= EF_NODRAW;
                }
 
-               if(e.flags & FL_POWERUP) // do not spawn powerups initially!
-                       Item_ScheduleInitialRespawn(e);
+               Item_Reset();
        }
 }
 
-void Item_Reset()
-{
-       Item_Show(self, !self.state);
-       setorigin (self, self.origin);
-       self.think = SUB_Null;
-       self.nextthink = 0;
-
-       if(self.flags & FL_POWERUP) // do not spawn powerups initially!
-               Item_ScheduleInitialRespawn(self);
-}
-
 // Savage: used for item garbage-collection
 // TODO: perhaps nice special effect?
 void RemoveItem(void)
@@ -655,7 +677,7 @@ float weapon_pickupevalfunc(entity player, entity item)
 
 float commodity_pickupevalfunc(entity player, entity item)
 {
-       float c, i, need_shells, need_nails, need_rockets, need_cells;
+       float c, i, need_shells, need_nails, need_rockets, need_cells, need_fuel;
        entity wi;
        c = 0;
 
@@ -675,6 +697,8 @@ float commodity_pickupevalfunc(entity player, entity item)
                        need_rockets = TRUE;
                else if(wi.items & IT_CELLS)
                        need_cells = TRUE;
+               else if(wi.items & IT_FUEL)
+                       need_cells = TRUE;
        }
 
        // TODO: figure out if the player even has the weapon this ammo is for?
@@ -696,6 +720,10 @@ float commodity_pickupevalfunc(entity player, entity item)
        if (item.ammo_cells)
        if (player.ammo_cells < g_pickup_cells_max)
                c = c + max(0, 1 - player.ammo_cells / g_pickup_cells_max);
+       if (need_fuel)
+       if (item.ammo_fuel)
+       if (player.ammo_fuel < g_pickup_fuel_max)
+               c = c + max(0, 1 - player.ammo_fuel / g_pickup_fuel_max);
        if (item.armorvalue)
        if (player.armorvalue < item.max_armorvalue)
                c = c + max(0, 1 - player.armorvalue / item.max_armorvalue);
@@ -722,9 +750,28 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                self.reset = SUB_Remove;
                // it's a dropped weapon
                self.movetype = MOVETYPE_TOSS;
+
                // Savage: remove thrown items after a certain period of time ("garbage collection")
                self.think = RemoveItem;
-               self.nextthink = time + 60;
+               self.nextthink = time + 20;
+
+               if(self.strength_finished || self.invincible_finished || self.superweapons_finished)
+               /*
+               if(self.items == 0)
+               if(self.weapons == (self.weapons & WEPBIT_SUPERWEAPONS)) // only superweapons
+               if(self.ammo_nails == 0)
+               if(self.ammo_cells == 0)
+               if(self.ammo_rockets == 0)
+               if(self.ammo_shells == 0)
+               if(self.ammo_fuel == 0)
+               if(self.health == 0)
+               if(self.armorvalue == 0)
+               */
+               {
+                       // if item is worthless after a timer, have it expire then
+                       self.nextthink = max(self.strength_finished, self.invincible_finished, self.superweapons_finished);
+               }
+
                // don't drop if in a NODROP zone (such as lava)
                traceline(self.origin, self.origin, MOVE_NORMAL, self);
                if (trace_dpstartcontents & DPCONTENTS_NODROP)
@@ -829,6 +876,10 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
        self.bot_pickupbasevalue = pickupbasevalue;
        self.mdl = itemmodel;
        self.item_pickupsound = pickupsound;
+       if(self.weapons)
+               self.weapon = WEP_FIRST + log2of(lowestbit(self.weapons));
+       else
+               self.weapon = 0;
        // let mappers override respawntime
        if(!self.respawntime) // both set
        {
@@ -853,7 +904,6 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                self.colormap = 1024; // color shirt=0 pants=0 grey
        }
 
-       Item_Show(self, 1);
        self.state = 0;
        if(self.team)
        {
@@ -862,8 +912,8 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime,
                self.effects = self.effects | EF_NODRAW; // marker for item team search
                InitializeEntity(self, Item_FindTeam, INITPRIO_FINDTARGET);
        }
-       else if(self.flags & FL_POWERUP) // do not spawn powerups initially!
-               Item_ScheduleInitialRespawn(self);
+       else
+               Item_Reset();
 }
 
 /* replace items in minstagib
@@ -940,6 +990,7 @@ void weapon_defaultspawnfunc(float wpn)
        string s;
        entity oldself;
        float i, j;
+       float f;
 
        if(self.classname != "droppedweapon" && self.classname != "replacedweapon")
        {
@@ -1008,7 +1059,7 @@ void weapon_defaultspawnfunc(float wpn)
 
        if(!self.respawntime)
        {
-               if(self.weapons & WEPBIT_SUPERWEAPONS)
+               if(e.weapons & WEPBIT_SUPERWEAPONS)
                {
                        self.respawntime = g_pickup_respawntime_superweapon;
                        self.respawntimejitter = g_pickup_respawntimejitter_superweapon;
@@ -1020,7 +1071,7 @@ void weapon_defaultspawnfunc(float wpn)
                }
        }
 
-       if(self.weapons & WEPBIT_SUPERWEAPONS)
+       if(e.weapons & WEPBIT_SUPERWEAPONS)
                if(!self.superweapons_finished)
                        self.superweapons_finished = autocvar_g_balance_superweapons_time;
 
@@ -1037,15 +1088,21 @@ void weapon_defaultspawnfunc(float wpn)
                }
        }
 
+       // pickup anyway
+       if(g_pickup_weapons_anyway)
+               self.pickup_anyway = TRUE;
+
+       f = FL_WEAPON;
+
        // no weapon-stay on superweapons
-       if(self.weapons & WEPBIT_SUPERWEAPONS)
-               self.flags |= FL_NO_WEAPON_STAY;
+       if(e.weapons & WEPBIT_SUPERWEAPONS)
+               f |= FL_NO_WEAPON_STAY;
 
        // weapon stay isn't supported for teamed weapons
        if(self.team)
-               self.flags |= FL_NO_WEAPON_STAY;
+               f |= FL_NO_WEAPON_STAY;
 
-       StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapons, FL_WEAPON, weapon_pickupevalfunc, e.bot_pickupbasevalue);
+       StartItem(e.model, "weapons/weaponpickup.wav", self.respawntime, self.respawntimejitter, e.message, 0, e.weapons, f, weapon_pickupevalfunc, e.bot_pickupbasevalue);
        if (self.modelindex) // don't precache if self was removed
                weapon_action(e.weapon, WR_PRECACHE);
 }