]> git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
allow throwing superweapons
authorRudolf Polzer <divverent@alientrap.org>
Mon, 16 Jan 2012 11:53:24 +0000 (12:53 +0100)
committerRudolf Polzer <divverent@alientrap.org>
Mon, 16 Jan 2012 11:53:24 +0000 (12:53 +0100)
qcsrc/server/cl_weapons.qc
qcsrc/server/t_items.qc

index 8b3b5e596873de645f6667d21d48c9fa91fc6677..73d610b6c65a41c69eb4e00defc8128b3421f190 100644 (file)
@@ -173,11 +173,17 @@ float W_AmmoItemCode(float wpn)
        return (get_weaponinfo(wpn)).items & IT_AMMO;
 }
 
+.float savenextthink;
 void thrown_wep_think()
 {
-       self.solid = SOLID_TRIGGER;
        self.owner = world;
-       SUB_SetFade(self, time + 20, 1);
+       float timeleft = self.savenextthink - time;
+       if(timeleft > 1)
+               SUB_SetFade(self, self.savenextthink - 1, 1);
+       else if(timeleft > 0)
+               SUB_SetFade(self, time, timeleft);
+       else
+               SUB_VanishOrRemove(self);
 }
 
 // returns amount of ammo used as string, or -1 for failure, or 0 for no ammo count
@@ -197,6 +203,33 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
        wep.flags |= FL_TOSSED;
        wep.colormap = own.colormap;
 
+       if(W_WeaponBit(wpn) & WEPBIT_SUPERWEAPONS)
+       {
+               if(self.items & IT_UNLIMITED_SUPERWEAPONS)
+               {
+                       wep.superweapons_finished = time + autocvar_g_balance_superweapons_time;
+               }
+               else
+               {
+                       float superweapons = 0;
+                       for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+                               if(self.weapons & WEPBIT_SUPERWEAPONS & W_WeaponBit(i))
+                                       ++superweapons;
+                       if(superweapons <= 1)
+                       {
+                               wep.superweapons_finished = self.superweapons_finished;
+                               self.superweapons_finished = 0;
+                       }
+                       else
+                       {
+                               float timeleft = self.superweapons_finished - time;
+                               float weptimeleft = timeleft / superweapons;
+                               wep.superweapons_finished = time + weptimeleft;
+                               self.superweapons_finished -= weptimeleft;
+                       }
+               }
+       }
+
        wa = W_AmmoItemCode(wpn);
        if(wa == 0)
        {
@@ -208,7 +241,9 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
                        return string_null;
                wep.glowmod = own.weaponentity_glowmod;
                wep.think = thrown_wep_think;
-               wep.nextthink = time + 0.5;
+               wep.savenextthink = wep.nextthink;
+               wep.nextthink = min(wep.nextthink, time + 0.5);
+               wep.pickup_anyway = TRUE; // these are ALWAYS pickable
                return "";
        }
        else
@@ -262,7 +297,8 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto
                }
                wep.glowmod = own.weaponentity_glowmod;
                wep.think = thrown_wep_think;
-               wep.nextthink = time + 0.5;
+               wep.savenextthink = wep.nextthink;
+               wep.nextthink = min(wep.nextthink, time + 0.5);
                wep.pickup_anyway = TRUE; // these are ALWAYS pickable
                return s;
        }
@@ -288,9 +324,6 @@ float W_IsWeaponThrowable(float w)
        wb = W_WeaponBit(w);
        if(!wb)
                return 0;
-       if(!g_minstagib)
-               if(wb & WEPBIT_SUPERWEAPONS) // can't throw a superweapon, they don't work
-                       return 0;
        wa = W_AmmoItemCode(w);
        if(start_weapons & wb)
        {
index 11688ae36a67cbdca3117edb78df76df93f94786..dcc5c15c881722183941775bc6e346174298e8c2 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;
@@ -510,8 +510,24 @@ 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))
-               return;
+       {
+               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;
 
@@ -546,11 +562,15 @@ void Item_Reset()
 {
        Item_Show(self, !self.state);
        setorigin (self, self.origin);
-       self.think = SUB_Null;
-       self.nextthink = 0;
 
-       if((self.flags & FL_POWERUP) | (self.weapons & WEPBIT_SUPERWEAPONS)) // do not spawn powerups initially!
-               Item_ScheduleInitialRespawn(self);
+       if(self.classname != "droppedweapon")
+       {
+               self.think = SUB_Null;
+               self.nextthink = 0;
+
+               if((self.flags & FL_POWERUP) | (self.weapons & WEPBIT_SUPERWEAPONS)) // do not spawn powerups initially!
+                       Item_ScheduleInitialRespawn(self);
+       }
 }
 
 void Item_FindTeam()
@@ -654,7 +674,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;
 
@@ -674,6 +694,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?
@@ -695,6 +717,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);
@@ -721,9 +747,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;
+
+               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)
@@ -856,7 +901,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)
        {