X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Ft_items.qc;h=b506141e8c8e6fb39c4694823f26824746bc5312;hp=ebc971141447e77c2a5a72ad18f11e05746b392b;hb=8864567ea710555af39cac30456582afcc7ab4af;hpb=e424ba544c41fc40b241b17bd7c1d9c2fc930705 diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index ebc971141..b506141e8 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -18,7 +18,7 @@ #include "triggers/subs.qh" #include "util.qh" - #include + #include #include @@ -82,6 +82,11 @@ void ItemDraw(entity this) if(this.ItemStatus & ITS_ANIMATE2) this.avelocity = '0 -90 0'; } + + // delay is for blocking item's position for a while; + // it's a workaround for dropped weapons that receive the position + // another time right after they spawn overriding animation position + this.onground_time = time + 0.5; } } else if (autocvar_cl_animate_items) @@ -89,13 +94,15 @@ void ItemDraw(entity this) if(this.ItemStatus & ITS_ANIMATE1) { this.angles += this.avelocity * frametime; - setorigin(this, '0 0 10' + this.oldorigin + '0 0 8' * sin(time * 2)); + float fade_in = bound(0, time - this.onground_time, 1); + setorigin(this, this.oldorigin + fade_in * ('0 0 10' + '0 0 8' * sin((time - this.onground_time) * 2))); } if(this.ItemStatus & ITS_ANIMATE2) { this.angles += this.avelocity * frametime; - setorigin(this, '0 0 8' + this.oldorigin + '0 0 4' * sin(time * 3)); + float fade_in = bound(0, time - this.onground_time, 1); + setorigin(this, this.oldorigin + fade_in * ('0 0 8' + '0 0 4' * sin((time - this.onground_time) * 3))); } } @@ -183,7 +190,7 @@ NET_HANDLE(ENT_CLIENT_ITEM, bool isnew) if(this.ItemStatus & ITS_ALLOWFB) this.effects |= EF_FULLBRIGHT; - if(this.ItemStatus & ITS_POWERUP) + if(this.ItemStatus & ITS_GLOW) { if(this.ItemStatus & ITS_AVAILABLE) this.effects |= (EF_ADDITIVE | EF_FULLBRIGHT); @@ -423,6 +430,7 @@ void Item_Show (entity e, float mode) { e.effects &= ~(EF_ADDITIVE | EF_STARDUST | EF_FULLBRIGHT | EF_NODEPTHTEST); e.ItemStatus &= ~ITS_STAYWEP; + entity def = e.itemdef; if (mode > 0) { // make the item look normal, and be touchable @@ -440,7 +448,6 @@ void Item_Show (entity e, float mode) e.ItemStatus &= ~ITS_AVAILABLE; } else { - entity def = e.itemdef; 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 ; @@ -463,8 +470,8 @@ void Item_Show (entity e, float mode) e.ItemStatus &= ~ITS_AVAILABLE; }} - if (e.items & ITEM_Strength.m_itemid || e.items & ITEM_Shield.m_itemid) - e.ItemStatus |= ITS_POWERUP; + if (def.m_glow) + e.ItemStatus |= ITS_GLOW; if (autocvar_g_nodepthtestitems) e.effects |= EF_NODEPTHTEST; @@ -497,13 +504,7 @@ void Item_ItemsTime_SetTimesForAllPlayers(); void Item_Respawn (entity this) { Item_Show(this, 1); - // this is ugly... - if(this.items == ITEM_Strength.m_itemid) - sound (this, CH_TRIGGER, SND_STRENGTH_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound - else if(this.items == ITEM_Shield.m_itemid) - sound (this, CH_TRIGGER, SND_SHIELD_RESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound - else - sound (this, CH_TRIGGER, SND_ITEMRESPAWN, VOL_BASE, ATTEN_NORM); // play respawn sound + 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) @@ -835,13 +836,12 @@ LABEL(pickup) if(this.team) { RandomSelection_Init(); - FOREACH_ENTITY_FLAGS(flags, FL_ITEM, + IL_EACH(g_items, it.team == this.team, { - if(it.team == this.team) - if(it.classname != "item_flag_team" && it.classname != "item_key_team") + if(it.itemdef) // is a registered item { Item_Show(it, -1); - RandomSelection_Add(it, 0, string_null, it.cnt, 0); + RandomSelection_AddEnt(it, it.cnt, 0); } }); e = RandomSelection_chosen_ent; @@ -880,21 +880,19 @@ void Item_FindTeam(entity this) // marker for item team search LOG_TRACE("Initializing item team ", ftos(this.team)); RandomSelection_Init(); - FOREACH_ENTITY_FLOAT(team, this.team, + IL_EACH(g_items, it.team == this.team, { - if(it.flags & FL_ITEM) - if(it.classname != "item_flag_team" && it.classname != "item_key_team") - RandomSelection_Add(it, 0, string_null, it.cnt, 0); + if(it.itemdef) // is a registered item + RandomSelection_AddEnt(it, it.cnt, 0); }); e = RandomSelection_chosen_ent; e.state = 0; Item_Show(e, 1); - FOREACH_ENTITY_FLOAT(team, this.team, + IL_EACH(g_items, it.team == this.team, { - if(it.flags & FL_ITEM) - if(it.classname != "item_flag_team" && it.classname != "item_key_team") + if(it.itemdef) // is a registered item { if(it != e) { @@ -928,7 +926,7 @@ float weapon_pickupevalfunc(entity player, entity item) float c; // See if I have it already - if(item.weapons & ~player.weapons) + if(player.weapons & item.weapons) { // If I can pick it up if(!item.spawnshieldtime) @@ -944,30 +942,50 @@ float weapon_pickupevalfunc(entity player, entity item) else c = 1; + if (c <= 0) + return 0; + // If custom weapon priorities for bots is enabled rate most wanted weapons higher - if( bot_custom_weapon && c ) - { - // Find the highest position on any range - int position = -1; - for (int j = 0; j < WEP_LAST ; ++j){ - if( - bot_weapons_far[j] == item.weapon || - bot_weapons_mid[j] == item.weapon || - bot_weapons_close[j] == item.weapon - ) + if(bot_custom_weapon) + { + int best_ratio = 0; + int missing = 0; + + // evaluate weapon usefulness in all ranges + for(int list = 0; list < 3; list++) + { + int position = -1; + int wep_count = 0; + int wpn = item.weapon; + for (int j = 0; j < WEP_LAST; ++j) { - position = j; - break; + int list_wpn = 0; + if (list == 0) list_wpn = bot_weapons_far[j]; + else if (list == 1) list_wpn = bot_weapons_mid[j]; + else list_wpn = bot_weapons_close[j]; + + if (weaponsInMap & Weapons_from(list_wpn).m_wepset) // only if available + { + if (list_wpn > 0) + wep_count++; + if (position == -1 && list_wpn == wpn) + position = wep_count; + } + } + if (position == -1) + { + missing++; + position = wep_count; // if missing assume last + } + if (wep_count) + { + if (!best_ratio || position / wep_count < best_ratio) + best_ratio = position / wep_count; } } - // Rate it - if (position >= 0 ) - { - position = WEP_LAST - position; - // item.bot_pickupbasevalue is overwritten here - return (BOT_PICKUP_RATING_LOW + ( (BOT_PICKUP_RATING_HIGH - BOT_PICKUP_RATING_LOW) * (position / WEP_LAST ))) * c; - } + if (missing < 3 && best_ratio) + return (BOT_PICKUP_RATING_HIGH - ( (BOT_PICKUP_RATING_HIGH - BOT_PICKUP_RATING_LOW) * best_ratio )) * c; } return item.bot_pickupbasevalue * c; @@ -975,27 +993,23 @@ float weapon_pickupevalfunc(entity player, entity item) float commodity_pickupevalfunc(entity player, entity item) { - float c; - float need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false; - c = 0; + bool need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false; + float c = 0; // Detect needed ammo FOREACH(Weapons, it != WEP_Null, { if(!(player.weapons & (it.m_wepset))) continue; - if(it.items & ITEM_Shells.m_itemid) - need_shells = true; - else if(it.items & ITEM_Bullets.m_itemid) - need_nails = true; - else if(it.items & ITEM_Rockets.m_itemid) - need_rockets = true; - else if(it.items & ITEM_Cells.m_itemid) - need_cells = true; - else if(it.items & ITEM_Plasma.m_itemid) - need_plasma = true; - else if(it.items & ITEM_JetpackFuel.m_itemid) - need_fuel = true; + switch(it.ammo_field) + { + case ammo_shells: need_shells = true; break; + case ammo_nails: need_nails = true; break; + case ammo_rockets: need_rockets = true; break; + case ammo_cells: need_cells = true; break; + case ammo_plasma: need_plasma = true; break; + case ammo_fuel: need_fuel = true; break; + } }); // TODO: figure out if the player even has the weapon this ammo is for? @@ -1076,6 +1090,7 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.weapons = WepSet_FromWeapon(Weapons_from(weaponid)); this.flags = FL_ITEM | itemflags; + IL_PUSH(g_items, this); if(MUTATOR_CALLHOOK(FilterItem, this)) // error means we do not want the item { @@ -1347,17 +1362,17 @@ spawnfunc(item_armor_big) this.max_armorvalue = g_pickup_armorbig_max; if(!this.pickup_anyway) this.pickup_anyway = g_pickup_armorbig_anyway; - StartItem(this, ITEM_ArmorLarge); + StartItem(this, ITEM_ArmorBig); } -spawnfunc(item_armor_large) +spawnfunc(item_armor_mega) { if(!this.armorvalue) - this.armorvalue = g_pickup_armorlarge; + this.armorvalue = g_pickup_armormega; if(!this.max_armorvalue) - this.max_armorvalue = g_pickup_armorlarge_max; + this.max_armorvalue = g_pickup_armormega_max; if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_armorlarge_anyway; + this.pickup_anyway = g_pickup_armormega_anyway; StartItem(this, ITEM_ArmorMega); } @@ -1383,15 +1398,15 @@ spawnfunc(item_health_medium) StartItem(this, ITEM_HealthMedium); } -spawnfunc(item_health_large) +spawnfunc(item_health_big) { if(!this.max_health) - this.max_health = g_pickup_healthlarge_max; + this.max_health = g_pickup_healthbig_max; if(!this.health) - this.health = g_pickup_healthlarge; + this.health = g_pickup_healthbig; if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_healthlarge_anyway; - StartItem(this, ITEM_HealthLarge); + this.pickup_anyway = g_pickup_healthbig_anyway; + StartItem(this, ITEM_HealthBig); } spawnfunc(item_health_mega) @@ -1407,9 +1422,11 @@ spawnfunc(item_health_mega) // support old misnamed entities spawnfunc(item_armor1) { spawnfunc_item_armor_small(this); } // FIXME: in Quake this is green armor, in Xonotic maps it is an armor shard -spawnfunc(item_armor25) { spawnfunc_item_armor_large(this); } +spawnfunc(item_armor25) { spawnfunc_item_armor_mega(this); } +spawnfunc(item_armor_large) { spawnfunc_item_armor_mega(this); } spawnfunc(item_health1) { spawnfunc_item_health_small(this); } spawnfunc(item_health25) { spawnfunc_item_health_medium(this); } +spawnfunc(item_health_large) { spawnfunc_item_health_big(this); } spawnfunc(item_health100) { spawnfunc_item_health_mega(this); } spawnfunc(item_strength) @@ -1447,10 +1464,9 @@ void target_items_use(entity this, entity actor, entity trigger) EXACTTRIGGER_TOUCH(this, trigger); } - FOREACH_ENTITY_ENT(enemy, actor, + IL_EACH(g_items, it.enemy == actor && it.classname == "droppedweapon", { - if(it.classname == "droppedweapon") - delete(it); + delete(it); }); if(GiveItems(actor, 0, tokenize_console(this.netname))) @@ -1798,6 +1814,7 @@ float GiveItems(entity e, float beginarg, float endarg) }); POSTGIVE_VALUE(e, strength_finished, 1, SND_POWERUP, SND_POWEROFF); POSTGIVE_VALUE(e, invincible_finished, 1, SND_Shield, SND_POWEROFF); + //POSTGIVE_VALUE(e, superweapons_finished, 1, SND_Null, SND_Null); POSTGIVE_VALUE(e, ammo_nails, 0, SND_ITEMPICKUP, SND_Null); POSTGIVE_VALUE(e, ammo_cells, 0, SND_ITEMPICKUP, SND_Null); POSTGIVE_VALUE(e, ammo_plasma, 0, SND_ITEMPICKUP, SND_Null);