X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Ft_items.qc;h=b26c840ff0c8834ba446c01939fe8760095a95c1;hp=c507581de5d0d53e679feec6dcd2ad93777f0026;hb=dbdc35464a18f62bf550a20eddac9ec16b0eacee;hpb=89cc5b3274a190460a77cc03083e3fb7c532b19a diff --git a/qcsrc/server/t_items.qc b/qcsrc/server/t_items.qc index c507581de5..b26c840ff0 100644 --- a/qcsrc/server/t_items.qc +++ b/qcsrc/server/t_items.qc @@ -131,7 +131,7 @@ void Item_Show (entity e, float mode) e.spawnshieldtime = 1; } - else if((e.flags & FL_WEAPON) && g_weapon_stay) + else if((e.flags & FL_WEAPON) && !(e.flags & FL_NO_WEAPON_STAY) && g_weapon_stay) { // make the item translucent and not touchable e.model = e.mdl; @@ -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; @@ -233,6 +233,15 @@ void Item_RespawnCountdown (void) case IT_FUEL_REGEN: name = "item-fuelregen"; rgb = '1 0.5 0'; break; case IT_JETPACK: name = "item-jetpack"; rgb = '0.5 0.5 0.5'; break; } + if(self.flags & FL_WEAPON) + { + entity wi = get_weaponinfo(self.weapon); + if(wi) + { + name = wi.model2; + rgb = '1 0 0'; + } + } if(!name) { print("Unknown powerup-marked item is wanting to respawn\n"); @@ -256,7 +265,7 @@ void Item_RespawnCountdown (void) void Item_ScheduleRespawnIn(entity e, float t) { - if(e.flags & FL_POWERUP) + if((e.flags & FL_POWERUP) || (e.weapons & WEPBIT_SUPERWEAPONS)) { e.think = Item_RespawnCountdown; e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS); @@ -431,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) @@ -452,12 +461,17 @@ float Item_GiveTo(entity item, entity player) if (item.strength_finished) { pickedup = TRUE; - player.strength_finished = max(player.strength_finished, time) + autocvar_g_balance_powerup_strength_time; + player.strength_finished = max(player.strength_finished, time) + item.strength_finished; } if (item.invincible_finished) { pickedup = TRUE; - player.invincible_finished = max(player.invincible_finished, time) + autocvar_g_balance_powerup_invincible_time; + player.invincible_finished = max(player.invincible_finished, time) + item.invincible_finished; + } + if (item.superweapons_finished) + { + pickedup = TRUE; + player.superweapons_finished = max(player.superweapons_finished, time) + item.superweapons_finished; } } @@ -469,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)); @@ -496,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); @@ -528,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; @@ -554,25 +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.waypointsprite_attached) - WaypointSprite_Kill(self.waypointsprite_attached); - - 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) @@ -644,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; @@ -664,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? @@ -685,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); @@ -711,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) @@ -739,6 +797,11 @@ void StartItem (string itemmodel, string pickupsound, float defaultrespawntime, return; } + if(self.model != "") + itemmodel = self.model; + if(self.item_pickupsound != "") + pickupsound = self.item_pickupsound; + self.reset = Item_Reset; // it's a level item if(self.spawnflags & 1) @@ -813,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 { @@ -837,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) { @@ -846,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 @@ -882,7 +948,8 @@ void minstagib_items (float itemid) // replace with invis if (itemid == IT_STRENGTH) { - self.strength_finished = 30; + if(!self.strength_finished) + self.strength_finished = autocvar_g_balance_powerup_strength_time; StartItem ("models/items/g_strength.md3", "misc/powerup.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Invisibility", IT_STRENGTH, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_MID); @@ -898,7 +965,8 @@ void minstagib_items (float itemid) // replace with speed if (itemid == IT_INVINCIBLE) { - self.invincible_finished = 30; + if(!self.invincible_finished) + self.invincible_finished = autocvar_g_balance_powerup_invincible_time; StartItem ("models/items/g_invincible.md3", "misc/powerup_shield.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Speed", IT_INVINCIBLE, 0, FL_POWERUP, generic_pickupevalfunc, BOT_PICKUP_RATING_MID); @@ -922,23 +990,7 @@ void weapon_defaultspawnfunc(float wpn) string s; entity oldself; float i, j; - - // set the respawntime in advance (so replaced weapons can copy it) - - if(!self.respawntime) - { - e = get_weaponinfo(wpn); - if(e.items == IT_SUPERWEAPON) - { - self.respawntime = g_pickup_respawntime_powerup; - self.respawntimejitter = g_pickup_respawntimejitter_powerup; - } - else - { - self.respawntime = g_pickup_respawntime_weapon; - self.respawntimejitter = g_pickup_respawntimejitter_weapon; - } - } + float f; if(self.classname != "droppedweapon" && self.classname != "replacedweapon") { @@ -1005,7 +1057,25 @@ void weapon_defaultspawnfunc(float wpn) e = get_weaponinfo(wpn); - if(e.items && e.items != IT_SUPERWEAPON) + if(!self.respawntime) + { + if(e.weapons & WEPBIT_SUPERWEAPONS) + { + self.respawntime = g_pickup_respawntime_superweapon; + self.respawntimejitter = g_pickup_respawntimejitter_superweapon; + } + else + { + self.respawntime = g_pickup_respawntime_weapon; + self.respawntimejitter = g_pickup_respawntimejitter_weapon; + } + } + + if(e.weapons & WEPBIT_SUPERWEAPONS) + if(!self.superweapons_finished) + self.superweapons_finished = autocvar_g_balance_superweapons_time; + + if(e.items) { for(i = 0, j = 1; i < 24; ++i, j *= 2) { @@ -1017,16 +1087,22 @@ void weapon_defaultspawnfunc(float wpn) } } } - else - { - self.flags |= FL_NO_WEAPON_STAY; - } + + // pickup anyway + if(g_pickup_weapons_anyway) + self.pickup_anyway = TRUE; + + f = FL_WEAPON; + + // no weapon-stay on superweapons + 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); } @@ -1237,7 +1313,8 @@ void spawnfunc_item_strength (void) { minstagib_items(IT_STRENGTH); } else { precache_sound("weapons/strength_fire.wav"); - self.strength_finished = 30; + if(!self.strength_finished) + self.strength_finished = autocvar_g_balance_powerup_strength_time; StartItem ("models/items/g_strength.md3", "misc/powerup.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Strength Powerup", IT_STRENGTH, 0, FL_POWERUP, generic_pickupevalfunc, 100000); } } @@ -1246,7 +1323,8 @@ void spawnfunc_item_invincible (void) { if(g_minstagib) { minstagib_items(IT_INVINCIBLE); } else { - self.invincible_finished = 30; + if(!self.invincible_finished) + self.invincible_finished = autocvar_g_balance_powerup_invincible_time; StartItem ("models/items/g_invincible.md3", "misc/powerup_shield.wav", g_pickup_respawntime_powerup, g_pickup_respawntimejitter_powerup, "Shield", IT_INVINCIBLE, 0, FL_POWERUP, generic_pickupevalfunc, 100000); } } @@ -1299,6 +1377,8 @@ void spawnfunc_target_items (void) 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; precache_sound("misc/itempickup.wav"); precache_sound("misc/megahealth.wav"); @@ -1321,6 +1401,7 @@ void spawnfunc_target_items (void) else if(argv(i) == "unlimited_superweapons") self.items |= IT_UNLIMITED_SUPERWEAPONS; else if(argv(i) == "strength") self.items |= IT_STRENGTH; else if(argv(i) == "invincible") self.items |= IT_INVINCIBLE; + else if(argv(i) == "superweapons") self.items |= IT_SUPERWEAPON; else if(argv(i) == "jetpack") self.items |= IT_JETPACK; else if(argv(i) == "fuel_regen") self.items |= IT_FUEL_REGEN; else @@ -1368,6 +1449,7 @@ void spawnfunc_target_items (void) self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_UNLIMITED_SUPERWEAPONS), "unlimited_superweapons"); self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.strength_finished * !!(self.items & IT_STRENGTH), "strength"); self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.invincible_finished * !!(self.items & IT_INVINCIBLE), "invincible"); + self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, self.superweapons_finished * !!(self.items & IT_SUPERWEAPON), "superweapons"); self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_JETPACK), "jetpack"); self.netname = sprintf("%s %s%d %s", self.netname, itemprefix, !!(self.items & IT_FUEL_REGEN), "fuel_regen"); if(self.ammo_shells != 0) self.netname = sprintf("%s %s%d %s", self.netname, valueprefix, max(0, self.ammo_shells), "shells"); @@ -1546,11 +1628,13 @@ float GiveItems(entity e, float beginarg, float endarg) e.strength_finished = max(0, e.strength_finished - time); e.invincible_finished = max(0, e.invincible_finished - time); + e.superweapons_finished = max(0, e.superweapons_finished - time); PREGIVE(e, items); PREGIVE(e, weapons); PREGIVE(e, strength_finished); PREGIVE(e, invincible_finished); + PREGIVE(e, superweapons_finished); PREGIVE(e, ammo_nails); PREGIVE(e, ammo_cells); PREGIVE(e, ammo_shells); @@ -1588,8 +1672,9 @@ float GiveItems(entity e, float beginarg, float endarg) continue; case "ALL": got += GiveBit(e, items, IT_FUEL_REGEN, op, val); - got += GiveValue(e, strength_finished, op, time); - got += GiveValue(e, invincible_finished, op, time); + got += GiveValue(e, strength_finished, op, val); + got += GiveValue(e, invincible_finished, op, val); + got += GiveValue(e, superweapons_finished, op, val); got += GiveBit(e, items, IT_UNLIMITED_AMMO, op, val); case "all": got += GiveBit(e, items, IT_JETPACK, op, val); @@ -1630,6 +1715,9 @@ float GiveItems(entity e, float beginarg, float endarg) case "invincible": got += GiveValue(e, invincible_finished, op, val); break; + case "superweapons": + got += GiveValue(e, superweapons_finished, op, val); + break; case "cells": got += GiveValue(e, ammo_cells, op, val); break; @@ -1695,6 +1783,10 @@ float GiveItems(entity e, float beginarg, float endarg) POSTGIVE_VALUE_ROT(e, armorvalue, 1, pauserotarmor_finished, autocvar_g_balance_pause_armor_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, "misc/armor25.wav", string_null); POSTGIVE_VALUE_ROT(e, health, 1, pauserothealth_finished, autocvar_g_balance_pause_health_rot, pauseregen_finished, autocvar_g_balance_pause_health_regen, "misc/megahealth.wav", string_null); + if(e.superweapons_finished <= 0) + if(self.weapons & WEPBIT_SUPERWEAPONS) + e.superweapons_finished = autocvar_g_balance_superweapons_time; + if (g_minstagib) { e.health = bound(0, e.health, 100); @@ -1709,6 +1801,10 @@ float GiveItems(entity e, float beginarg, float endarg) e.invincible_finished = 0; else e.invincible_finished += time; + if(e.superweapons_finished <= 0) + e.superweapons_finished = 0; + else + e.superweapons_finished += time; if not(e.weapons & W_WeaponBit(e.switchweapon)) _switchweapon = TRUE;