X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Ft_items.qc;h=4c0125afb687c923ac92e1fcd068232e03e19482;hp=b6f405fec019b5cb8ef6249b3c07a77f02c7fc32;hb=e110811d01fc7895d1e6c7a3dad41ff8acbdb835;hpb=3ee342eac91e8a0cc50f5e7517bb4c4d640a4774 diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index b6f405fec0..4c0125afb6 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -58,12 +58,13 @@ void Item_SetAlpha(entity this) this.alpha = -1; } - if(!veh_hud) - if(this.ItemStatus & ITS_STAYWEP) + if((!veh_hud) && (this.ItemStatus & ITS_STAYWEP)) { this.colormod = this.glowmod = autocvar_cl_weapon_stay_color; this.alpha = autocvar_cl_weapon_stay_alpha; } + + this.drawmask = ((this.alpha <= 0) ? 0 : MASK_NORMAL); } void ItemDraw(entity this) @@ -128,17 +129,22 @@ void Item_PreDraw(entity this) { if(warpzone_warpzones_exist) { - // just incase warpzones were initialized last, reset these - //this.alpha = 1; // alpha is already set by the draw function - this.drawmask = MASK_NORMAL; + setpredraw(this, func_null); // no need to keep running this return; } float alph; vector org = getpropertyvec(VF_ORIGIN); - if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones - alph = 0; - else if(this.fade_start) - alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1); + //if(!checkpvs(org, this)) // this makes sense as long as we don't support recursive warpzones + //alph = 0; // this shouldn't be needed, since items behind walls are culled anyway + if(this.fade_start) + { + if(vdist(org - this.origin, >, this.fade_end)) + alph = 0; // save on some processing + else if(vdist(org - this.origin, <, this.fade_start)) + alph = 1; // more processing saved + else + alph = bound(0, (this.fade_end - vlen(org - this.origin - 0.5 * (this.mins + this.maxs))) / (this.fade_end - this.fade_start), 1); + } else alph = 1; //printf("%v <-> %v\n", view_origin, this.origin + 0.5 * (this.mins + this.maxs)); @@ -146,8 +152,8 @@ void Item_PreDraw(entity this) this.alpha = alph; if(alph <= 0) this.drawmask = 0; - else - this.drawmask = MASK_NORMAL; + //else + //this.drawmask = MASK_NORMAL; // reset by the setalpha function } void ItemRemove(entity this) @@ -182,7 +188,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) setsize(this, '-16 -16 0', (use_bigsize) ? '16 16 48' : '16 16 32'); } - if(sf & ISF_STATUS) // need to read/write status frist so model can handle simple, fb etc. + if(sf & ISF_STATUS) // need to read/write status first so model can handle simple, fb etc. { this.ItemStatus = ReadByte(); @@ -214,7 +220,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) this.fade_end = ReadShort(); this.fade_start = ReadShort(); - if(this.fade_start && !autocvar_cl_items_nofade) + if(!warpzone_warpzones_exist && this.fade_start && !autocvar_cl_items_nofade) setpredraw(this, Item_PreDraw); if(this.mdl) @@ -228,14 +234,14 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) string _fn2 = substring(_fn, 0 , strlen(_fn) -4); this.draw = ItemDrawSimple; - if(fexists(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix))) - this.mdl = strzone(sprintf("%s%s.md3", _fn2, autocvar_cl_simpleitems_postfix)); - else if(fexists(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix))) - this.mdl = strzone(sprintf("%s%s.dpm", _fn2, autocvar_cl_simpleitems_postfix)); - else if(fexists(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix))) - this.mdl = strzone(sprintf("%s%s.iqm", _fn2, autocvar_cl_simpleitems_postfix)); - else if(fexists(sprintf("%s%s.mdl", _fn2, autocvar_cl_simpleitems_postfix))) - this.mdl = strzone(sprintf("%s%s.mdl", _fn2, autocvar_cl_simpleitems_postfix)); + if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".md3"))) + this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".md3")); + else if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".dpm"))) + this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".dpm")); + else if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".iqm"))) + this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".iqm")); + else if(fexists(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".mdl"))) + this.mdl = strzone(strcat(_fn2, autocvar_cl_simpleitems_postfix, ".mdl")); else { this.draw = ItemDraw; @@ -449,28 +455,30 @@ void Item_Show (entity e, float mode) e.spawnshieldtime = 1; e.ItemStatus &= ~ITS_AVAILABLE; } - else { - bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.weapons & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons - || e.team // weapon stay isn't supported for teamed weapons - ; - if(def.instanceOfWeaponPickup && !nostay && g_weapon_stay) - { - // make the item translucent and not touchable - e.model = e.mdl; - e.solid = SOLID_TRIGGER; // can STILL be picked up! - e.effects |= EF_STARDUST; - e.spawnshieldtime = 0; // field indicates whether picking it up may give you anything other than the weapon - e.ItemStatus |= (ITS_AVAILABLE | ITS_STAYWEP); - } else { - //setmodel(e, "null"); - e.solid = SOLID_NOT; - e.colormod = '0 0 0'; - //e.glowmod = e.colormod; - e.spawnshieldtime = 1; - e.ItemStatus &= ~ITS_AVAILABLE; - }} + bool nostay = def.instanceOfWeaponPickup ? !!(def.m_weapon.weapons & WEPSET_SUPERWEAPONS) : false // no weapon-stay on superweapons + || e.team // weapon stay isn't supported for teamed weapons + ; + if(def.instanceOfWeaponPickup && !nostay && g_weapon_stay) + { + // make the item translucent and not touchable + e.model = e.mdl; + e.solid = SOLID_TRIGGER; // can STILL be picked up! + e.effects |= EF_STARDUST; + e.spawnshieldtime = 0; // field indicates whether picking it up may give you anything other than the weapon + e.ItemStatus |= (ITS_AVAILABLE | ITS_STAYWEP); + } + else + { + //setmodel(e, "null"); + e.solid = SOLID_NOT; + e.colormod = '0 0 0'; + //e.glowmod = e.colormod; + e.spawnshieldtime = 1; + e.ItemStatus &= ~ITS_AVAILABLE; + } + } if (def.m_glow) e.ItemStatus |= ITS_GLOW; @@ -509,7 +517,7 @@ void Item_Respawn (entity this) sound(this, CH_TRIGGER, this.itemdef.m_respawnsound, VOL_BASE, ATTEN_NORM); // play respawn sound setorigin(this, this.origin); - if (Item_ItemsTime_Allow(this.itemdef) || this.weapons & WEPSET_SUPERWEAPONS) + if (Item_ItemsTime_Allow(this.itemdef) || (this.weapons & WEPSET_SUPERWEAPONS)) { float t = Item_ItemsTime_UpdateTime(this, 0); Item_ItemsTime_SetTime(this, t); @@ -537,7 +545,6 @@ void Item_RespawnCountdown (entity this) this.count += 1; if(this.count == 1) { - MUTATOR_CALLHOOK(Item_RespawnCountdown, string_null, '0 0 0'); do { { entity wi = Weapons_from(this.weapon); @@ -556,10 +563,11 @@ void Item_RespawnCountdown (entity this) } } } while (0); + bool mutator_returnvalue = MUTATOR_CALLHOOK(Item_RespawnCountdown, this); if(this.waypointsprite_attached) { GameItem def = this.itemdef; - if (Item_ItemsTime_SpectatorOnly(def)) + if (Item_ItemsTime_SpectatorOnly(def) && !mutator_returnvalue) WaypointSprite_UpdateRule(this.waypointsprite_attached, 0, SPRITERULE_SPECTATOR); WaypointSprite_UpdateBuildFinished(this.waypointsprite_attached, time + ITEM_RESPAWN_TICKS); } @@ -594,15 +602,18 @@ void Item_RespawnThink(entity this) void Item_ScheduleRespawnIn(entity e, float t) { // if the respawn time is longer than 10 seconds, show a waypoint, otherwise, just respawn normally - if ((Item_ItemsTime_Allow(e.itemdef) || e.weapons & WEPSET_SUPERWEAPONS) && (t - ITEM_RESPAWN_TICKS) > 0) + if ((Item_ItemsTime_Allow(e.itemdef) || (e.weapons & WEPSET_SUPERWEAPONS) || MUTATOR_CALLHOOK(Item_ScheduleRespawn, e, t)) && (t - ITEM_RESPAWN_TICKS) > 0) { setthink(e, Item_RespawnCountdown); e.nextthink = time + max(0, t - ITEM_RESPAWN_TICKS); e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS; e.count = 0; - t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime); - Item_ItemsTime_SetTime(e, t); - Item_ItemsTime_SetTimesForAllPlayers(); + if(Item_ItemsTime_Allow(e.itemdef) || (e.weapons & WEPSET_SUPERWEAPONS)) + { + t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime); + Item_ItemsTime_SetTime(e, t); + Item_ItemsTime_SetTimesForAllPlayers(); + } } else { @@ -610,6 +621,13 @@ void Item_ScheduleRespawnIn(entity e, float t) e.nextthink = time; e.scheduledrespawntime = time + t; e.wait = time + t; + + if(Item_ItemsTime_Allow(e.itemdef) || (e.weapons & WEPSET_SUPERWEAPONS)) + { + t = Item_ItemsTime_UpdateTime(e, e.scheduledrespawntime); + Item_ItemsTime_SetTime(e, t); + Item_ItemsTime_SetTimesForAllPlayers(); + } } } @@ -627,7 +645,151 @@ void Item_ScheduleRespawn(entity e) void Item_ScheduleInitialRespawn(entity e) { Item_Show(e, 0); - Item_ScheduleRespawnIn(e, game_starttime - time + ((e.respawntimestart) ? e.respawntimestart : ITEM_RESPAWNTIME_INITIAL(e))); + Item_ScheduleRespawnIn(e, max(0, game_starttime - time) + ((e.respawntimestart) ? e.respawntimestart : ITEM_RESPAWNTIME_INITIAL(e))); +} + +void GivePlayerHealth(entity player, float amount) +{ + if (amount == 0) + { + return; + } + player.health = bound(player.health, player.health + amount, + g_pickup_healthmega_max); + player.pauserothealth_finished = max(player.pauserothealth_finished, time + + autocvar_g_balance_pause_health_rot); +} + +void GivePlayerArmor(entity player, float amount) +{ + if (amount == 0) + { + return; + } + player.armorvalue = bound(player.armorvalue, player.armorvalue + amount, + g_pickup_armormega_max); + player.pauserotarmor_finished = max(player.pauserotarmor_finished, time + + autocvar_g_balance_pause_armor_rot); +} + +void GivePlayerAmmo(entity player, .float ammotype, float amount) +{ + float maxvalue = 999; + switch (ammotype) + { + case ammo_shells: + { + maxvalue = g_pickup_shells_max; + break; + } + case ammo_cells: + { + maxvalue = g_pickup_cells_max; + break; + } + case ammo_rockets: + { + maxvalue = g_pickup_rockets_max; + break; + } + case ammo_plasma: + { + maxvalue = g_pickup_plasma_max; + break; + } + case ammo_nails: + { + maxvalue = g_pickup_nails_max; + break; + } + case ammo_fuel: + { + maxvalue = g_pickup_fuel_max; + break; + } + } + player.(ammotype) = min(player.(ammotype) + amount, maxvalue); +} + +void GivePlayerRandomWeapons(entity player, int num_weapons, + string weapon_names, float shells, float bullets, float rockets, + float cells, float plasma) +{ + if (num_weapons == 0) + { + return; + } + int num_potential_weapons = tokenize_console(weapon_names); + for (int i = 0; i < num_weapons; ++i) + { + RandomSelection_Init(); + for (int j = 0; j < num_potential_weapons; ++j) + { + string weapon = argv(j); + FOREACH(Weapons, it != WEP_Null, + { + // Finding a weapon which player doesn't have. + if (!(player.weapons & it.m_wepset) && (it.netname == weapon)) + { + RandomSelection_AddEnt(it, 1, 1); + break; + } + }); + } + if (RandomSelection_chosen_ent == NULL) + { + return; + } + player.weapons |= RandomSelection_chosen_ent.m_wepset; + switch (RandomSelection_chosen_ent.ammo_field) + { + case (ammo_shells): + { + if (player.ammo_shells != 0) + { + break; + } + GivePlayerAmmo(player, ammo_shells, shells); + break; + } + case (ammo_nails): + { + if (player.ammo_nails != 0) + { + break; + } + GivePlayerAmmo(player, ammo_nails, bullets); + break; + } + case (ammo_rockets): + { + if (player.ammo_rockets != 0) + { + break; + } + GivePlayerAmmo(player, ammo_rockets, rockets); + break; + } + case (ammo_cells): + { + if (player.ammo_cells != 0) + { + break; + } + GivePlayerAmmo(player, ammo_cells, cells); + break; + } + case (ammo_plasma): + { + if (player.ammo_plasma != 0) + { + break; + } + GivePlayerAmmo(player, ammo_plasma, plasma); + break; + } + } + } } float Item_GiveAmmoTo(entity item, entity player, .float ammotype, float ammomax, float mode) @@ -684,7 +846,7 @@ float Item_GiveTo(entity item, entity player) // if the player is using their best weapon before items are given, they // probably want to switch to an even better weapon after items are given - if(player.autoswitch) + if(CS(player).autoswitch) { for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { @@ -857,7 +1019,7 @@ LABEL(pickup) _sound (toucher, (this.itemdef.instanceOfPowerup ? CH_TRIGGER_SINGLE : CH_TRIGGER), (this.item_pickupsound ? this.item_pickupsound : Sound_fixpath(this.item_pickupsound_ent)), VOL_BASE, ATTEN_NORM); if (this.classname == "droppedweapon") - delete (this); + delete(this); else if (this.spawnshieldtime) { entity e; @@ -873,7 +1035,7 @@ LABEL(pickup) } }); e = RandomSelection_chosen_ent; - + Item_Show(e, 1); // reset its state so it is visible (extra sendflags doesn't matter, this happens anyway) } else e = this; @@ -1002,7 +1164,6 @@ float ammo_pickupevalfunc(entity player, entity item) switch(it.ammo_field) { - case ammo_shells: need_shells = true; break; case ammo_shells: need_shells = true; break; case ammo_nails: need_nails = true; break; case ammo_rockets: need_rockets = true; break; @@ -1014,32 +1175,27 @@ float ammo_pickupevalfunc(entity player, entity item) rating = item.bot_pickupbasevalue; } - if (need_shells) - if (item.ammo_shells) - if (player.ammo_shells < g_pickup_shells_max) - c = item.ammo_shells / player.ammo_shells; - if (need_nails) - if (item.ammo_nails) - if (player.ammo_nails < g_pickup_nails_max) - c = item.ammo_nails / player.ammo_nails; - if (need_rockets) - if (item.ammo_rockets) - if (player.ammo_rockets < g_pickup_rockets_max) - c = item.ammo_rockets / player.ammo_rockets; - if (need_cells) - if (item.ammo_cells) - if (player.ammo_cells < g_pickup_cells_max) - c = item.ammo_cells / player.ammo_cells; - if (need_plasma) - if (item.ammo_plasma) - if (player.ammo_plasma < g_pickup_plasma_max) - c = item.ammo_plasma / player.ammo_plasma; - if (need_fuel) - if (item.ammo_fuel) - if (player.ammo_fuel < g_pickup_fuel_max) - c = item.ammo_fuel / player.ammo_fuel; + float noammorating = 0.5; - rating *= min(2, c); + if ((need_shells) && (item.ammo_shells) && (player.ammo_shells < g_pickup_shells_max)) + c = item.ammo_shells / max(noammorating, player.ammo_shells); + + if ((need_nails) && (item.ammo_nails) && (player.ammo_nails < g_pickup_nails_max)) + c = item.ammo_nails / max(noammorating, player.ammo_nails); + + if ((need_rockets) && (item.ammo_rockets) && (player.ammo_rockets < g_pickup_rockets_max)) + c = item.ammo_rockets / max(noammorating, player.ammo_rockets); + + if ((need_cells) && (item.ammo_cells) && (player.ammo_cells < g_pickup_cells_max)) + c = item.ammo_cells / max(noammorating, player.ammo_cells); + + if ((need_plasma) && (item.ammo_plasma) && (player.ammo_plasma < g_pickup_plasma_max)) + c = item.ammo_plasma / max(noammorating, player.ammo_plasma); + + if ((need_fuel) && (item.ammo_fuel) && (player.ammo_fuel < g_pickup_fuel_max)) + c = item.ammo_fuel / max(noammorating, player.ammo_fuel); + + rating *= min(c, 2); if(wpn) rating += wpn.bot_pickupbasevalue * 0.1; return rating; @@ -1054,16 +1210,17 @@ float healtharmor_pickupevalfunc(entity player, entity item) float itemarmor = item.armorvalue; float itemhealth = item.health; + if(item.item_group) { itemarmor *= min(4, item.item_group_count); itemhealth *= min(4, item.item_group_count); } - if (itemarmor) - if (player.armorvalue < item.max_armorvalue) + + if (itemarmor && (player.armorvalue < item.max_armorvalue)) c = itemarmor / max(1, player.armorvalue * 2/3 + player.health * 1/3); - if (itemhealth) - if (player.health < item.max_health) + + if (itemhealth && (player.health < item.max_health)) c = itemhealth / max(1, player.health); rating *= min(2, c); @@ -1166,7 +1323,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default if(!have_pickup_item(this)) { startitem_failed = true; - delete (this); + delete(this); return; } @@ -1204,7 +1361,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default // target_give not yet supported; maybe later print("removed targeted ", this.classname, "\n"); startitem_failed = true; - remove (this); + delete(this); return; } */ @@ -1332,7 +1489,7 @@ void setItemGroup(entity this) { int grY = it.item_group; // move all items of item_group Y to item_group X - FOREACH_ENTITY(IS_SMALL(it.itemdef), + IL_EACH(g_items, IS_SMALL(it.itemdef), { if(it.item_group == grY) it.item_group = this.item_group; @@ -1347,9 +1504,9 @@ void setItemGroupCount() for (int k = 1; k <= group_count; k++) { int count = 0; - FOREACH_ENTITY(IS_SMALL(it.itemdef) && it.item_group == k, { count++; }); + IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == k, { count++; }); if (count) - FOREACH_ENTITY(IS_SMALL(it.itemdef) && it.item_group == k, { it.item_group_count = count; }); + IL_EACH(g_items, IS_SMALL(it.itemdef) && it.item_group == k, { it.item_group_count = count; }); } } @@ -1360,9 +1517,8 @@ spawnfunc(item_rockets) spawnfunc(item_bullets) { - if(!weaponswapping) - if(autocvar_sv_q3acompat_machineshotgunswap) - if(this.classname != "droppedweapon") + if(!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap && + (this.classname != "droppedweapon")) { weaponswapping = true; spawnfunc_item_shells(this); @@ -1385,9 +1541,8 @@ spawnfunc(item_plasma) spawnfunc(item_shells) { - if(!weaponswapping) - if(autocvar_sv_q3acompat_machineshotgunswap) - if(this.classname != "droppedweapon") + if(!weaponswapping && autocvar_sv_q3acompat_machineshotgunswap && + (this.classname != "droppedweapon")) { weaponswapping = true; spawnfunc_item_bullets(this); @@ -1469,10 +1624,9 @@ void target_items_use(entity this, entity actor, entity trigger) return; } - if (!IS_PLAYER(actor)) - return; - if(IS_DEAD(actor)) + if (!IS_PLAYER(actor) || IS_DEAD(actor)) return; + if(trigger.solid == SOLID_TRIGGER) { EXACTTRIGGER_TOUCH(this, trigger); @@ -1489,7 +1643,7 @@ void target_items_use(entity this, entity actor, entity trigger) spawnfunc(target_items) { - int n, j; + int n; string s; this.use = target_items_use; @@ -1507,7 +1661,7 @@ spawnfunc(target_items) } else { - for(j = 0; j < n; ++j) + for(int j = 0; j < n; ++j) { if (argv(j) == "unlimited_ammo") this.items |= IT_UNLIMITED_AMMO; else if(argv(j) == "unlimited_weapon_ammo") this.items |= IT_UNLIMITED_WEAPON_AMMO; @@ -1591,7 +1745,7 @@ spawnfunc(target_items) //print(this.netname, "\n"); n = tokenize_console(this.netname); - for(j = 0; j < n; ++j) + for(int j = 0; j < n; ++j) { FOREACH(Weapons, it != WEP_Null && W_UndeprecateName(argv(j)) == it.netname, { it.wr_init(it); @@ -1720,7 +1874,7 @@ float GiveItems(entity e, float beginarg, float endarg) int _switchweapon = 0; - if(e.autoswitch) + if(CS(e).autoswitch) { for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { @@ -1916,7 +2070,11 @@ float GiveItems(entity e, float beginarg, float endarg) { .entity weaponentity = weaponentities[slot]; if(_switchweapon & BIT(slot)) - W_SwitchWeapon_Force(e, w_getbestweapon(e, weaponentity), weaponentity); + { + Weapon wep = w_getbestweapon(e, weaponentity); + if(wep != e.(weaponentity).m_switchweapon) + W_SwitchWeapon_Force(e, wep, weaponentity); + } } }