From: Rudolf Polzer Date: Mon, 16 Jan 2012 11:53:24 +0000 (+0100) Subject: allow throwing superweapons X-Git-Tag: xonotic-v0.6.0~157^2~9 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=9c2ce91100ccb6e1b272488411744bf1fe4d4277;p=xonotic%2Fxonotic-data.pk3dir.git allow throwing superweapons --- diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index 8b3b5e596..73d610b6c 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -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) { diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index 11688ae36..dcc5c15c8 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -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) {