X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_weapons.qc;h=236c0923fdc330834469234bc9eb2285a1f6bb26;hb=dbcdd58814a7281aef637c8c07a02242331c4c86;hp=edf5b1f5e5c697d07087509075ef53edc2af5bd0;hpb=5836f4f65fb9b51c0f48b47b936033c7a799f273;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_weapons.qc b/qcsrc/server/cl_weapons.qc index edf5b1f5e..236c0923f 100644 --- a/qcsrc/server/cl_weapons.qc +++ b/qcsrc/server/cl_weapons.qc @@ -163,21 +163,22 @@ string W_Name(float weaponid) return (get_weaponinfo(weaponid)).message; } -float W_WeaponBit(float wpn) -{ - return (get_weaponinfo(wpn)).weapons; -} - float W_AmmoItemCode(float wpn) { - return (get_weaponinfo(wpn)).items; + 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,8 +198,36 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto wep.flags |= FL_TOSSED; wep.colormap = own.colormap; + if(WEPSET_CONTAINS_AW(WEPBIT_SUPERWEAPONS, wpn)) + { + if(own.items & IT_UNLIMITED_SUPERWEAPONS) + { + wep.superweapons_finished = time + autocvar_g_balance_superweapons_time; + } + else + { + float superweapons = 1; + for(i = WEP_FIRST; i <= WEP_LAST; ++i) + if(WEPSET_CONTAINS_AW(WEPBIT_SUPERWEAPONS, i)) + if(WEPSET_CONTAINS_EW(own, i)) + ++superweapons; + if(superweapons <= 1) + { + wep.superweapons_finished = own.superweapons_finished; + own.superweapons_finished = 0; + } + else + { + float timeleft = own.superweapons_finished - time; + float weptimeleft = timeleft / superweapons; + wep.superweapons_finished = time + weptimeleft; + own.superweapons_finished -= weptimeleft; + } + } + } + wa = W_AmmoItemCode(wpn); - if(wa == IT_SUPERWEAPON || wa == 0) + if(wa == 0) { oldself = self; self = wep; @@ -208,7 +237,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 @@ -220,17 +251,13 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto self = oldself; if(startitem_failed) return string_null; - if(doreduce) + if(doreduce && g_weapon_stay == 2) { for(i = 0, j = 1; i < 24; ++i, j *= 2) { if(wa & j) { ammofield = Item_CounterField(j); - thisammo = min(own.ammofield, wep.ammofield); - wep.ammofield = thisammo; - own.ammofield -= thisammo; - s = strcat(s, " and ", ftos(thisammo), " ", Item_CounterFieldName(j)); // if our weapon is loaded, give its load back to the player if(self.(weapon_load[self.weapon]) > 0) @@ -238,20 +265,46 @@ string W_ThrowNewWeapon(entity own, float wpn, float doreduce, vector org, vecto own.ammofield += self.(weapon_load[self.weapon]); self.(weapon_load[self.weapon]) = -1; // schedule the weapon for reloading } + + wep.ammofield = 0; + } + } + } + else if(doreduce) + { + for(i = 0, j = 1; i < 24; ++i, j *= 2) + { + if(wa & j) + { + ammofield = Item_CounterField(j); + + // if our weapon is loaded, give its load back to the player + if(self.(weapon_load[self.weapon]) > 0) + { + own.ammofield += self.(weapon_load[self.weapon]); + self.(weapon_load[self.weapon]) = -1; // schedule the weapon for reloading + } + + thisammo = min(own.ammofield, wep.ammofield); + wep.ammofield = thisammo; + own.ammofield -= thisammo; + s = strcat(s, " and ", ftos(thisammo), " ", Item_CounterFieldName(j)); } } s = substring(s, 5, -1); } 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; } } float W_IsWeaponThrowable(float w) { - float wb, wa; + float wa; if (!autocvar_g_pickup_items) return 0; @@ -265,18 +318,15 @@ float W_IsWeaponThrowable(float w) return 0; if (g_nexball && w == WEP_GRENADE_LAUNCHER) return 0; - - wb = W_WeaponBit(w); - if(!wb) - return 0; + if(w == 0) + return 0; + wa = W_AmmoItemCode(w); - if(start_weapons & wb) + if(WEPSET_CONTAINS_AW(start_weapons, w)) { - if(wa == IT_SUPERWEAPON && start_items & IT_UNLIMITED_SUPERWEAPONS) - return 0; - if(wa != IT_SUPERWEAPON && start_items & IT_UNLIMITED_WEAPON_AMMO) - return 0; // start weapons that take no ammo can't be dropped (this prevents dropping the laser, as long as it continues to use no ammo) + if(start_items & IT_UNLIMITED_WEAPON_AMMO) + return 0; if(wa == 0) return 0; } @@ -287,7 +337,7 @@ float W_IsWeaponThrowable(float w) // toss current weapon void W_ThrowWeapon(vector velo, vector delta, float doreduce) { - float w, wb; + float w; string a; w = self.weapon; @@ -297,18 +347,15 @@ void W_ThrowWeapon(vector velo, vector delta, float doreduce) return; if(!autocvar_g_weapon_throwable) return; - if(autocvar_g_weapon_stay == 1) - return; if(self.weaponentity.state != WS_READY) return; if(!W_IsWeaponThrowable(w)) return; - wb = W_WeaponBit(w); - if(self.weapons & wb != wb) + if(!WEPSET_CONTAINS_EW(self, w)) return; + WEPSET_ANDNOT_EW(self, w); - self.weapons &~= wb; W_SwitchWeapon_Force(self, w_getbestweapon(self)); a = W_ThrowNewWeapon(self, w, doreduce, self.origin + delta, velo); if not(a) @@ -408,8 +455,8 @@ void W_WeaponFrame() //if (self.button0) // print(ftos(frametime), " ", ftos(time), " >= ", ftos(ATTACK_FINISHED(self)), " >= ", ftos(self.weapon_nextthink), "\n"); - float wb; - wb = W_WeaponBit(self.weapon); + float w; + w = self.weapon; // call the think code which may fire the weapon // and do so multiple times to resolve framerate dependency issues if the @@ -419,18 +466,18 @@ void W_WeaponFrame() while (c < W_TICSPERFRAME) { c = c + 1; - if(wb && ((self.weapons & wb) == 0)) + if(w && !WEPSET_CONTAINS_EW(self, w)) { if(self.weapon == self.switchweapon) W_SwitchWeapon_Force(self, w_getbestweapon(self)); - wb = 0; + w = 0; } v_forward = fo; v_right = ri; v_up = up; - if(wb) + if(w) weapon_action(self.weapon, WR_THINK); else weapon_action(self.weapon, WR_GONETHINK); @@ -470,3 +517,20 @@ void W_WeaponFrame() self.currentammo = 1; #endif } + +string W_Apply_Weaponreplace(string in) +{ + float n = tokenize_console(in); + string out = ""; + float i; + for(i = 0; i < n; ++i) + { + string s = argv(i); + string r = cvar_string(strcat("g_weaponreplace_", s)); + if(r == "") + out = strcat(out, " ", s); + else if(r != "0") + out = strcat(out, " ", r); + } + return substring(out, 1, -1); +}