X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fcommon%2Ft_items.qc;h=6d4fa7720f16da31197a59bcb30c239e12cdf7da;hp=116fbfcd5a4768f4d4eb4c03f2f681cece9a1241;hb=6147159b612c6950ca2177b732028d1116201220;hpb=f03ecd022b871d302176764d819b1a07eeda7997 diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc index 116fbfcd5a..6d4fa7720f 100644 --- a/qcsrc/common/t_items.qc +++ b/qcsrc/common/t_items.qc @@ -949,133 +949,123 @@ float generic_pickupevalfunc(entity player, entity item) {return item.bot_pickup float weapon_pickupevalfunc(entity player, entity item) { - float c; - int rating = item.bot_pickupbasevalue; - // See if I have it already if(player.weapons & item.weapons) { // If I can pick it up if(!item.spawnshieldtime) - c = 0; - else if(player.ammo_cells || player.ammo_shells || player.ammo_plasma || player.ammo_nails || player.ammo_rockets) - { - if (rating > 0) - rating = BOT_PICKUP_RATING_LOW * 0.5 * (1 + rating / BOT_PICKUP_RATING_HIGH); - // Skilled bots will grab more - c = 1 + bound(0, skill / 10, 1) * 0.5; - } - else - c = 0; + return 0; + return ammo_pickupevalfunc(player, 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) - { - 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) - { - 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; - } - } - - if (missing < 3 && best_ratio) - c = c - best_ratio * 0.3; - } + // reduce weapon value if bot already got a good arsenal + float c = 1; + int weapons_value = 0; + FOREACH(Weapons, it != WEP_Null && (player.weapons & it.m_wepset), { + weapons_value += it.bot_pickupbasevalue; + }); + c -= bound(0, weapons_value / 20000, 1) * 0.5; - return rating * c; + return item.bot_pickupbasevalue * c; } -float commodity_pickupevalfunc(entity player, entity item) +float ammo_pickupevalfunc(entity player, entity item) { bool need_shells = false, need_nails = false, need_rockets = false, need_cells = false, need_plasma = false, need_fuel = false; + entity wpn = NULL; float c = 0; + float rating = 0; // Detect needed ammo - FOREACH(Weapons, it != WEP_Null, { - if(!(player.weapons & (it.m_wepset))) - continue; + if(item.itemdef.instanceOfWeaponPickup) + { + entity ammo = NULL; + if(item.ammo_shells) { need_shells = true; ammo = ITEM_Shells; } + else if(item.ammo_nails) { need_nails = true; ammo = ITEM_Bullets; } + else if(item.ammo_rockets) { need_rockets = true; ammo = ITEM_Rockets; } + else if(item.ammo_cells) { need_cells = true; ammo = ITEM_Cells; } + else if(item.ammo_plasma) { need_plasma = true; ammo = ITEM_Plasma; } + else if(item.ammo_fuel) { need_fuel = true; ammo = ITEM_JetpackFuel; } - 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; - } - }); + if(!ammo) + return 0; + wpn = item; + rating = ammo.m_botvalue; + } + else + { + FOREACH(Weapons, it != WEP_Null, { + if(!(player.weapons & (it.m_wepset))) + continue; + + 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; + case ammo_cells: need_cells = true; break; + case ammo_plasma: need_plasma = true; break; + case ammo_fuel: need_fuel = true; break; + } + }); + rating = item.bot_pickupbasevalue; + } - // TODO: figure out if the player even has the weapon this ammo is for? - // may not affect strategy much though... - // find out how much more ammo/armor/health the player can hold if (need_shells) if (item.ammo_shells) if (player.ammo_shells < g_pickup_shells_max) - c = c + max(0, 1 - 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 = c + max(0, 1 - 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 = c + max(0, 1 - 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 = c + max(0, 1 - 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 = c + max(0, 1 - 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 = c + max(0, 1 - player.ammo_fuel / g_pickup_fuel_max); - if (item.armorvalue) + c = item.ammo_fuel / player.ammo_fuel; + + rating *= min(2, c); + if(wpn) + rating += wpn.bot_pickupbasevalue * 0.1; + return rating; +} + +.int item_group; +.int item_group_count; +float healtharmor_pickupevalfunc(entity player, entity item) +{ + float c = 0; + float rating = item.bot_pickupbasevalue; + + 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) - c = c + max(0, 1 - player.armorvalue / item.max_armorvalue); - if (item.health) + c = itemarmor / max(1, player.armorvalue * 2/3 + player.health * 1/3); + if (itemhealth) if (player.health < item.max_health) - c = c + max(0, 1 - player.health / item.max_health); + c = itemhealth / max(1, player.health); - return item.bot_pickupbasevalue * c; + rating *= min(2, c); + return rating; } void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force) @@ -1084,6 +1074,12 @@ void Item_Damage(entity this, entity inflictor, entity attacker, float damage, i RemoveItem(this); } +void item_use(entity this, entity actor, entity trigger) +{ + // use the touch function to handle collection + gettouch(this)(this, actor); +} + void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter) { string itemname = def.m_name; @@ -1104,6 +1100,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default this.respawntimejitter = defaultrespawntimejitter; } + if(!this.pickup_anyway && def.m_pickupanyway) + this.pickup_anyway = def.m_pickupanyway(); + int itemid = def.m_itemid; this.items = itemid; int weaponid = def.instanceOfWeaponPickup ? def.m_weapon.m_id : 0; @@ -1205,6 +1204,9 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default } */ + if(this.targetname != "" && (this.spawnflags & 16)) + this.use = item_use; + if(autocvar_spawn_debug >= 2) { // why not flags & fl_item? @@ -1284,6 +1286,8 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default delete(this); return; } + + setItemGroup(this); } void StartItem(entity this, GameItem def) @@ -1296,12 +1300,58 @@ void StartItem(entity this, GameItem def) ); } +#define IS_SMALL(def) ((def.instanceOfHealth && def == ITEM_HealthSmall) || (def.instanceOfArmor && def == ITEM_ArmorSmall)) +int group_count = 1; + +void setItemGroup(entity this) +{ + if(!IS_SMALL(this.itemdef)) + return; + + FOREACH_ENTITY_RADIUS(this.origin, 120, (it != this) && IS_SMALL(it.itemdef), + { + if(!this.item_group) + { + if(!it.item_group) + { + it.item_group = group_count; + group_count++; + } + this.item_group = it.item_group; + } + else // spawning item is already part of a item_group X + { + if(!it.item_group) + it.item_group = this.item_group; + else if(it.item_group != this.item_group) // found an item near the spawning item that is part of a different item_group Y + { + int grY = it.item_group; + // move all items of item_group Y to item_group X + FOREACH_ENTITY(IS_SMALL(it.itemdef), + { + if(it.item_group == grY) + it.item_group = this.item_group; + }); + } + } + }); +} + +void setItemGroupCount() +{ + for (int k = 1; k <= group_count; k++) + { + int count = 0; + FOREACH_ENTITY(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; }); + } +} + spawnfunc(item_rockets) { if(!this.ammo_rockets) this.ammo_rockets = g_pickup_rockets; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_ammo_anyway; StartItem(this, ITEM_Rockets); } @@ -1319,8 +1369,6 @@ spawnfunc(item_bullets) if(!this.ammo_nails) this.ammo_nails = g_pickup_nails; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_ammo_anyway; StartItem(this, ITEM_Bullets); } @@ -1328,8 +1376,6 @@ spawnfunc(item_cells) { if(!this.ammo_cells) this.ammo_cells = g_pickup_cells; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_ammo_anyway; StartItem(this, ITEM_Cells); } @@ -1337,8 +1383,6 @@ spawnfunc(item_plasma) { if(!this.ammo_plasma) this.ammo_plasma = g_pickup_plasma; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_ammo_anyway; StartItem(this, ITEM_Plasma); } @@ -1356,8 +1400,6 @@ spawnfunc(item_shells) if(!this.ammo_shells) this.ammo_shells = g_pickup_shells; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_ammo_anyway; StartItem(this, ITEM_Shells); } @@ -1367,8 +1409,6 @@ spawnfunc(item_armor_small) this.armorvalue = g_pickup_armorsmall; if(!this.max_armorvalue) this.max_armorvalue = g_pickup_armorsmall_max; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_armorsmall_anyway; StartItem(this, ITEM_ArmorSmall); } @@ -1378,8 +1418,6 @@ spawnfunc(item_armor_medium) this.armorvalue = g_pickup_armormedium; if(!this.max_armorvalue) this.max_armorvalue = g_pickup_armormedium_max; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_armormedium_anyway; StartItem(this, ITEM_ArmorMedium); } @@ -1389,8 +1427,6 @@ spawnfunc(item_armor_big) this.armorvalue = g_pickup_armorbig; if(!this.max_armorvalue) this.max_armorvalue = g_pickup_armorbig_max; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_armorbig_anyway; StartItem(this, ITEM_ArmorBig); } @@ -1400,8 +1436,6 @@ spawnfunc(item_armor_mega) this.armorvalue = g_pickup_armormega; if(!this.max_armorvalue) this.max_armorvalue = g_pickup_armormega_max; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_armormega_anyway; StartItem(this, ITEM_ArmorMega); } @@ -1411,8 +1445,6 @@ spawnfunc(item_health_small) this.max_health = g_pickup_healthsmall_max; if(!this.health) this.health = g_pickup_healthsmall; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_healthsmall_anyway; StartItem(this, ITEM_HealthSmall); } @@ -1422,8 +1454,6 @@ spawnfunc(item_health_medium) this.max_health = g_pickup_healthmedium_max; if(!this.health) this.health = g_pickup_healthmedium; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_healthmedium_anyway; StartItem(this, ITEM_HealthMedium); } @@ -1433,8 +1463,6 @@ spawnfunc(item_health_big) this.max_health = g_pickup_healthbig_max; if(!this.health) this.health = g_pickup_healthbig; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_healthbig_anyway; StartItem(this, ITEM_HealthBig); } @@ -1444,8 +1472,6 @@ spawnfunc(item_health_mega) this.max_health = g_pickup_healthmega_max; if(!this.health) this.health = g_pickup_healthmega; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_healthmega_anyway; StartItem(this, ITEM_HealthMega); } @@ -1609,8 +1635,6 @@ spawnfunc(item_fuel) { if(!this.ammo_fuel) this.ammo_fuel = g_pickup_fuel; - if(!this.pickup_anyway) - this.pickup_anyway = g_pickup_ammo_anyway; StartItem(this, ITEM_JetpackFuel); }