]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Bot AI: improve item rating
authorterencehill <piuntn@gmail.com>
Tue, 10 Jan 2017 15:08:16 +0000 (16:08 +0100)
committerterencehill <piuntn@gmail.com>
Tue, 10 Jan 2017 15:08:16 +0000 (16:08 +0100)
* fine-tune weapon base values and always use them instead of needlessly calculating every time new ones from the priority lists
* dynamically increase ammo and health/armor values based on the current need of them
* rate already owned weapons like ammo plus a small percentage of base weapon value

30 files changed:
qcsrc/common/items/item/ammo.qh
qcsrc/common/items/item/armor.qh
qcsrc/common/items/item/health.qh
qcsrc/common/items/item/jetpack.qh
qcsrc/common/items/item/pickup.qh
qcsrc/common/items/item/powerup.qh
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/mutators/mutator/instagib/items.qh
qcsrc/common/mutators/mutator/overkill/hmg.qh
qcsrc/common/mutators/mutator/overkill/rpc.qh
qcsrc/common/t_items.qc
qcsrc/common/t_items.qh
qcsrc/common/weapons/weapon/arc.qc
qcsrc/common/weapons/weapon/crylink.qc
qcsrc/common/weapons/weapon/devastator.qc
qcsrc/common/weapons/weapon/electro.qc
qcsrc/common/weapons/weapon/fireball.qc
qcsrc/common/weapons/weapon/hagar.qc
qcsrc/common/weapons/weapon/hlac.qc
qcsrc/common/weapons/weapon/machinegun.qc
qcsrc/common/weapons/weapon/minelayer.qc
qcsrc/common/weapons/weapon/mortar.qc
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/common/weapons/weapon/seeker.qc
qcsrc/common/weapons/weapon/shockwave.qc
qcsrc/common/weapons/weapon/shotgun.qc
qcsrc/common/weapons/weapon/tuba.qc
qcsrc/common/weapons/weapon/vaporizer.qc
qcsrc/common/weapons/weapon/vortex.qc
qcsrc/server/mutators/mutator/gamemode_keyhunt.qc

index e1d493fe975a7c50dfcd11af3d9fba717a67c1da..f240578b3295f7f7f50978245c123e01f61d3dfa 100644 (file)
@@ -3,7 +3,7 @@
 #include "pickup.qh"
 CLASS(Ammo, Pickup)
 #ifdef SVQC
-    ATTRIB(Ammo, m_pickupevalfunc, float(entity player, entity item), commodity_pickupevalfunc);
+    ATTRIB(Ammo, m_pickupevalfunc, float(entity player, entity item), ammo_pickupevalfunc);
     ATTRIB(Ammo, m_respawntime, float(), GET(g_pickup_respawntime_ammo));
     ATTRIB(Ammo, m_respawntimejitter, float(), GET(g_pickup_respawntimejitter_ammo));
 #endif
@@ -24,7 +24,7 @@ REGISTER_ITEM(Bullets, Ammo) {
     this.m_name     =   "bullets";
     this.m_icon     =   "ammo_bullets";
 #ifdef SVQC
-    this.m_botvalue =   2000;
+    this.m_botvalue =   1500;
     this.m_itemid   =   IT_NAILS;
 #endif
 }
@@ -40,7 +40,7 @@ REGISTER_ITEM(Cells, Ammo) {
     this.m_name     =   "cells";
     this.m_icon     =   "ammo_cells";
 #ifdef SVQC
-    this.m_botvalue =   2000;
+    this.m_botvalue =   1500;
     this.m_itemid   =   IT_CELLS;
 #endif
 }
@@ -56,7 +56,7 @@ REGISTER_ITEM(Plasma, Ammo) {
     this.m_name     =   "plasma";
     this.m_icon     =   "ammo_plasma";
 #ifdef SVQC
-    this.m_botvalue =   2000;
+    this.m_botvalue =   1500;
     this.m_itemid   =   IT_PLASMA;
 #endif
 }
@@ -72,7 +72,7 @@ REGISTER_ITEM(Rockets, Ammo) {
     this.m_name     =   "rockets";
     this.m_icon     =   "ammo_rockets";
 #ifdef SVQC
-    this.m_botvalue =   3000;
+    this.m_botvalue =   1500;
     this.m_itemid   =   IT_ROCKETS;
 #endif
 }
@@ -88,7 +88,7 @@ REGISTER_ITEM(Shells, Ammo) {
     this.m_name     =   "shells";
     this.m_icon     =   "ammo_shells";
 #ifdef SVQC
-    this.m_botvalue =   500;
+    this.m_botvalue =   1000;
     this.m_itemid   =   IT_SHELLS;
 #endif
 }
index 4b6b9fdf6c4c8554599bdcc9e3e14830ea699fd3..9fcd076345213216f0c4d49fa6f2f8fbb6df1a08 100644 (file)
@@ -5,7 +5,8 @@ CLASS(Armor, Pickup)
 #ifdef SVQC
     ATTRIB(Armor, m_mins, vector, '-16 -16 0');
     ATTRIB(Armor, m_maxs, vector, '16 16 48');
-    ATTRIB(Armor, m_pickupevalfunc, float(entity player, entity item), commodity_pickupevalfunc);
+    ATTRIB(Armor, m_pickupevalfunc, float(entity player, entity item), healtharmor_pickupevalfunc);
+    ATTRIB(Armor, m_botvalue, int, 3000);
 #endif
 ENDCLASS(Armor)
 
@@ -26,7 +27,6 @@ REGISTER_ITEM(ArmorSmall, Armor) {
     this.m_name                 =   "5 Armor";
     this.m_icon                 =   "armor";
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_LOW;
     this.m_itemid               =   IT_ARMOR_SHARD;
     this.m_respawntime          =   GET(g_pickup_respawntime_short);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_short);
@@ -46,7 +46,6 @@ REGISTER_ITEM(ArmorMedium, Armor) {
     this.m_name                 =   "25 Armor";
     this.m_icon                 =   "armor";
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_MID;
     this.m_itemid               =   IT_ARMOR;
     this.m_respawntime          =   GET(g_pickup_respawntime_medium);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_medium);
@@ -68,7 +67,6 @@ REGISTER_ITEM(ArmorBig, Armor) {
     this.m_color                =   '0 1 0';
     this.m_waypoint             =   _("Big armor");
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_HIGH;
     this.m_itemid               =   IT_ARMOR;
     this.m_respawntime          =   GET(g_pickup_respawntime_long);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_long);
@@ -92,7 +90,6 @@ REGISTER_ITEM(ArmorMega, Armor) {
     this.m_waypointblink        =   2;
 #ifdef SVQC
     this.m_maxs                 =   '16 16 70';
-    this.m_botvalue             =   BOT_PICKUP_RATING_HIGH;
     this.m_itemid               =   IT_ARMOR;
     this.m_respawntime          =   GET(g_pickup_respawntime_long);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_long);
index f7915987e3b01a55fcc864ce3517e7590372acfa..e32d0ebbdc0cc2f89cf2fd5309476ce1ef11cfa5 100644 (file)
@@ -5,7 +5,8 @@ CLASS(Health, Pickup)
 #ifdef SVQC
     ATTRIB(Health, m_mins, vector, '-16 -16 0');
     ATTRIB(Health, m_maxs, vector, '16 16 48');
-    ATTRIB(Health, m_pickupevalfunc, float(entity player, entity item), commodity_pickupevalfunc);
+    ATTRIB(Health, m_pickupevalfunc, float(entity player, entity item), healtharmor_pickupevalfunc);
+    ATTRIB(Health, m_botvalue, int, 2500);
 #endif
 ENDCLASS(Health)
 
@@ -26,7 +27,6 @@ REGISTER_ITEM(HealthSmall, Health) {
     this.m_name                 =   "5 Health";
     this.m_icon                 =   "health";
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_LOW;
     this.m_itemid               =   IT_5HP;
     this.m_respawntime          =   GET(g_pickup_respawntime_short);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_short);
@@ -46,7 +46,6 @@ REGISTER_ITEM(HealthMedium, Health) {
     this.m_name                 =   "25 Health";
     this.m_icon                 =   "health";
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_MID;
     this.m_itemid               =   IT_25HP;
     this.m_respawntime          =   GET(g_pickup_respawntime_short);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_short);
@@ -68,7 +67,6 @@ REGISTER_ITEM(HealthBig, Health) {
     this.m_color                =   '1 0 0';
     this.m_waypoint             =   _("Big health");
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_MID;
     this.m_itemid               =   IT_25HP;
     this.m_respawntime          =   GET(g_pickup_respawntime_medium);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_medium);
@@ -92,7 +90,6 @@ REGISTER_ITEM(HealthMega, Health) {
     this.m_waypointblink        =   2;
 #ifdef SVQC
     this.m_maxs                 =   '16 16 70';
-    this.m_botvalue             =   BOT_PICKUP_RATING_HIGH;
     this.m_itemid               =   IT_HEALTH;
     this.m_respawntime          =   GET(g_pickup_respawntime_long);
     this.m_respawntimejitter    =   GET(g_pickup_respawntimejitter_long);
index 8334c791ab11d99843595e2e54eaf57e6f922b15..5093234fbe9ec3de67402133c5b90fdffd965342 100644 (file)
@@ -26,8 +26,8 @@ REGISTER_ITEM(Jetpack, Powerup) {
     this.m_waypoint             =   _("Jet Pack");
     this.m_waypointblink        =   2;
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_LOW;
-    this.m_pickupevalfunc       =   commodity_pickupevalfunc;
+    this.m_botvalue             =   3000;
+    this.m_pickupevalfunc       =   ammo_pickupevalfunc;
 #endif
 }
 
@@ -42,7 +42,7 @@ REGISTER_ITEM(JetpackFuel, Ammo) {
     this.m_name     =   "Fuel";
     this.m_icon     =   "ammo_fuel";
 #ifdef SVQC
-    this.m_botvalue =   BOT_PICKUP_RATING_LOW;
+    this.m_botvalue =   2000;
     this.m_itemid   =   IT_FUEL;
 #endif
 }
@@ -61,8 +61,8 @@ REGISTER_ITEM(JetpackRegen, Powerup) {
     this.m_waypoint             =   _("Fuel regen");
     this.m_waypointblink        =   2;
 #ifdef SVQC
-    this.m_botvalue             =   BOT_PICKUP_RATING_LOW;
+    this.m_botvalue             =   3000;
     this.m_itemid               =   IT_FUEL_REGEN;
-    this.m_pickupevalfunc       =   commodity_pickupevalfunc;
+    this.m_pickupevalfunc       =   ammo_pickupevalfunc;
 #endif
 }
index 204a49921d5f2b84fbc3f30aaff98d692dcbf9e7..af83fb9c8127062292b3fb03546cb46deb8e8fe8 100644 (file)
@@ -17,11 +17,6 @@ PROPERTY(float, g_pickup_respawntimejitter_long)
 PROPERTY(float, g_pickup_respawntimejitter_powerup)
 #endif
 
-// pickup ratings for bot logic
-const int BOT_PICKUP_RATING_LOW  =  2500;
-const int BOT_PICKUP_RATING_MID  =  5000;
-const int BOT_PICKUP_RATING_HIGH = 10000;
-
 #include <common/items/inventory.qh>
 #include <common/items/item.qh>
 #include <common/t_items.qh>
index 80b1e6affc0a12747c9d2fd0b14c4ef25659da32..aaec88eeee770536e8bcabd19201d618be410f4f 100644 (file)
@@ -10,7 +10,7 @@ CLASS(Powerup, Pickup)
 #ifdef SVQC
     ATTRIB(Powerup, m_mins, vector, '-16 -16 0');
     ATTRIB(Powerup, m_maxs, vector, '16 16 80');
-    ATTRIB(Powerup, m_botvalue, int, 100000);
+    ATTRIB(Powerup, m_botvalue, int, 20000);
     ATTRIB(Powerup, m_itemflags, int, FL_POWERUP);
     ATTRIB(Powerup, m_respawntime, float(), GET(g_pickup_respawntime_powerup));
     ATTRIB(Powerup, m_respawntimejitter, float(), GET(g_pickup_respawntimejitter_powerup));
index 57a5bf5793c7ccaf6285b8a9ae96b35c9e1236d9..4df42406d064fd9f737f0947efa522aa79aecd26 100644 (file)
@@ -350,7 +350,7 @@ void buff_Init(entity this)
        this.solid = SOLID_TRIGGER;
        this.flags = FL_ITEM;
        this.bot_pickup = true;
-       this.bot_pickupevalfunc = commodity_pickupevalfunc;
+       this.bot_pickupevalfunc = generic_pickupevalfunc;
        this.bot_pickupbasevalue = 1000;
        IL_PUSH(g_items, this);
        setthink(this, buff_Think);
index 1efa4cbdc1d221d0a19adc9c33cb6f048706bb7e..d9f641d8200316387529a5093f90664a4c95f189 100644 (file)
@@ -22,7 +22,7 @@ REGISTER_ITEM(VaporizerCells, Ammo) {
     this.m_name                 =   "Vaporizer Ammo";
     this.m_icon                 =   "ammo_supercells";
 #ifdef SVQC
-    this.m_botvalue             =   100;
+    this.m_botvalue             =   2000;
     this.m_itemid               =   IT_CELLS;
     this.m_respawntime          =   GET(instagib_respawntime_ammo);
     this.m_respawntimejitter    =   GET(instagib_respawntimejitter_ammo);
index 7219fd1f80756bb0abb8fd88a984c7e18a1ae861..99eb4c8091f4d12ab72e674fdb5405be04ca0a95 100644 (file)
@@ -4,7 +4,7 @@ CLASS(HeavyMachineGun, Weapon)
 /* ammotype  */ ATTRIB(HeavyMachineGun, ammo_field, .int, ammo_nails);
 /* impulse   */ ATTRIB(HeavyMachineGun, impulse, int, 3);
 /* flags     */ ATTRIB(HeavyMachineGun, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_FLAG_SUPERWEAPON);
-/* rating    */ ATTRIB(HeavyMachineGun, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(HeavyMachineGun, bot_pickupbasevalue, float, 10000);
 /* color     */ ATTRIB(HeavyMachineGun, wpcolor, vector, '0.5 0.5 0');
 /* modelname */ ATTRIB(HeavyMachineGun, mdl, string, "ok_hmg");
 #ifdef GAMEQC
index 535fa5533a08f6ba0528db24938fce2db70c868e..8de910102da2b043841942a2e531913294b3ab7c 100644 (file)
@@ -4,7 +4,7 @@ CLASS(RocketPropelledChainsaw, Weapon)
 /* ammotype  */ ATTRIB(RocketPropelledChainsaw, ammo_field, .int, ammo_rockets);
 /* impulse   */ ATTRIB(RocketPropelledChainsaw, impulse, int, 7);
 /* flags     */ ATTRIB(RocketPropelledChainsaw, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_HIDDEN | WEP_FLAG_NORMAL | WEP_FLAG_CANCLIMB | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_SUPERWEAPON);
-/* rating    */ ATTRIB(RocketPropelledChainsaw, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(RocketPropelledChainsaw, bot_pickupbasevalue, float, 10000);
 /* color     */ ATTRIB(RocketPropelledChainsaw, wpcolor, vector, '0.5 0.5 0');
 /* modelname */ ATTRIB(RocketPropelledChainsaw, mdl, string, "ok_rl");
 #ifdef GAMEQC
index a48bb7c8c8f31c1141d085aeb43a823684dd322a..852a9281411f89f753bf039bc4895dc52d0e7939 100644 (file)
@@ -949,133 +949,106 @@ 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;
-       }
-       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;
+                       return 0;
+               return ammo_pickupevalfunc(player, item);
        }
-
-       return rating * c;
+       return item.bot_pickupbasevalue;
 }
 
-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 = (player.ammo_shells + 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 = (player.ammo_nails + 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 = (player.ammo_rockets + 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 = (player.ammo_cells + 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 = (player.ammo_plasma + 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);
+               c = (player.ammo_fuel + item.ammo_fuel) / player.ammo_fuel;
+
+       rating *= min(3, c);
+       if(wpn)
+               // Skilled bots will grab more
+               rating += wpn.bot_pickupbasevalue * (0.1 + 0.1 * bound(0, skill / 10, 1));
+       return rating;
+}
+
+float healtharmor_pickupevalfunc(entity player, entity item)
+{
+       float c = 0;
+       float rating = item.bot_pickupbasevalue;
+
        if (item.armorvalue)
        if (player.armorvalue < item.max_armorvalue)
-               c = c + max(0, 1 - player.armorvalue / item.max_armorvalue);
+               c = (player.armorvalue + player.health + item.armorvalue) / (max(1, player.armorvalue + player.health));
        if (item.health)
        if (player.health < item.max_health)
-               c = c + max(0, 1 - player.health / item.max_health);
+               c = (player.health + item.health) / (max(1, player.health));
 
-       return item.bot_pickupbasevalue * c;
+       rating *= min(3, c);
+       return rating;
 }
 
 void Item_Damage(entity this, entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
index 418ce391767f4ff170a27f315ffbe953bab91d1a..f5a310562b8cfc189e9a0260758141eae8eef980 100644 (file)
@@ -107,8 +107,8 @@ void UpdateItemAfterTeleport(entity this);
 float generic_pickupevalfunc(entity player, entity item);// {return item.bot_pickupbasevalue;} // WEAPONTODO
 
 float weapon_pickupevalfunc(entity player, entity item);
-
-float commodity_pickupevalfunc(entity player, entity item);
+float ammo_pickupevalfunc(entity player, entity item);
+float healtharmor_pickupevalfunc(entity player, entity item);
 
 .float is_item;
 .entity itemdef;
index 88ba1c768c63cacf23e4ac0524f8dbb181ea13e6..b902cbe9a54861f809d156400302f2426955507c 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Arc, Weapon)
 /* ammotype  */ ATTRIB(Arc, ammo_field, .int, ammo_cells);
 /* impulse   */ ATTRIB(Arc, impulse, int, 3);
 /* flags     */ ATTRIB(Arc, spawnflags, int, WEP_FLAG_NORMAL);
-/* rating    */ ATTRIB(Arc, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(Arc, bot_pickupbasevalue, float, 8000);
 /* color     */ ATTRIB(Arc, wpcolor, vector, '1 1 1');
 /* modelname */ ATTRIB(Arc, mdl, string, "arc");
 #ifdef GAMEQC
index dbcddf1ad0d8327aadebdc3003326897fba16abb..e76117dc459cc66950ec1db9258eb89bf5c19511 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Crylink, Weapon)
 /* ammotype  */ ATTRIB(Crylink, ammo_field, .int, ammo_cells);
 /* impulse   */ ATTRIB(Crylink, impulse, int, 6);
 /* flags     */ ATTRIB(Crylink, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH | WEP_FLAG_CANCLIMB);
-/* rating    */ ATTRIB(Crylink, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Crylink, bot_pickupbasevalue, float, 6000);
 /* color     */ ATTRIB(Crylink, wpcolor, vector, '1 0.5 1');
 /* modelname */ ATTRIB(Crylink, mdl, string, "crylink");
 #ifdef GAMEQC
index a6473b39274c552dc2520dc218b08cfb42fcbc91..ab86be4f8fee38dbac4285e31af5c33f0b841e4e 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Devastator, Weapon)
 /* ammotype  */ ATTRIB(Devastator, ammo_field, .int, ammo_rockets);
 /* impulse   */ ATTRIB(Devastator, impulse, int, 9);
 /* flags     */ ATTRIB(Devastator, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Devastator, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(Devastator, bot_pickupbasevalue, float, 8000);
 /* color     */ ATTRIB(Devastator, wpcolor, vector, '1 1 0');
 /* modelname */ ATTRIB(Devastator, mdl, string, "rl");
 #ifdef GAMEQC
index 46e46c24059660e8fd3b30b7ffe37da13d704d9d..0e8d272e070e9a03b3a5225202d3cc135da8038a 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Electro, Weapon)
 /* ammotype  */ ATTRIB(Electro, ammo_field, .int, ammo_cells);
 /* impulse   */ ATTRIB(Electro, impulse, int, 5);
 /* flags     */ ATTRIB(Electro, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Electro, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Electro, bot_pickupbasevalue, float, 5000);
 /* color     */ ATTRIB(Electro, wpcolor, vector, '0 0.5 1');
 /* modelname */ ATTRIB(Electro, mdl, string, "electro");
 #ifdef GAMEQC
index dff721aa1a540e194b70a016d6785fcc5d07f5f2..2add2e4685eb26ef9b091429e7ce7efe1521ddf7 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Fireball, Weapon)
 /* ammotype  */ //ATTRIB(Fireball, ammo_field, .int, ammo_none);
 /* impulse   */ ATTRIB(Fireball, impulse, int, 9);
 /* flags     */ ATTRIB(Fireball, spawnflags, int, WEP_FLAG_SUPERWEAPON | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Fireball, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Fireball, bot_pickupbasevalue, float, 5000);
 /* color     */ ATTRIB(Fireball, wpcolor, vector, '1 0.5 0');
 /* modelname */ ATTRIB(Fireball, mdl, string, "fireball");
 #ifdef GAMEQC
index 897ad437f6408dc2b556a1d3416f298882002c1e..f7b289278608a7a0591abb74481d2d0878965302 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Hagar, Weapon)
 /* ammotype  */ ATTRIB(Hagar, ammo_field, .int, ammo_rockets);
 /* impulse   */ ATTRIB(Hagar, impulse, int, 8);
 /* flags     */ ATTRIB(Hagar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Hagar, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Hagar, bot_pickupbasevalue, float, 6000);
 /* color     */ ATTRIB(Hagar, wpcolor, vector, '1 1 0.5');
 /* modelname */ ATTRIB(Hagar, mdl, string, "hagar");
 #ifdef GAMEQC
index 010ca4fe8e18183e7c7f970f311844df3eb790e0..6e03b1041406233b5c0130f08be7c8782c79c25f 100644 (file)
@@ -4,7 +4,7 @@ CLASS(HLAC, Weapon)
 /* ammotype  */ ATTRIB(HLAC, ammo_field, .int, ammo_cells);
 /* impulse   */ ATTRIB(HLAC, impulse, int, 6);
 /* flags     */ ATTRIB(HLAC, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(HLAC, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(HLAC, bot_pickupbasevalue, float, 4000);
 /* color     */ ATTRIB(HLAC, wpcolor, vector, '0 1 0');
 /* modelname */ ATTRIB(HLAC, mdl, string, "hlac");
 #ifdef GAMEQC
index 7344ba9d0da4e220f66b01d2a602029fce4adff9..0d986e77352876254623d22ec3545025184d5446 100644 (file)
@@ -4,7 +4,7 @@ CLASS(MachineGun, Weapon)
 /* ammotype  */ ATTRIB(MachineGun, ammo_field, .int, ammo_nails);
 /* impulse   */ ATTRIB(MachineGun, impulse, int, 3);
 /* flags     */ ATTRIB(MachineGun, spawnflags, int, WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
-/* rating    */ ATTRIB(MachineGun, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(MachineGun, bot_pickupbasevalue, float, 7000);
 /* color     */ ATTRIB(MachineGun, wpcolor, vector, '1 1 0');
 /* modelname */ ATTRIB(MachineGun, mdl, string, "uzi");
 #ifdef GAMEQC
index 00f729b113e14f7bf87dc02eb1e006c1dc7a2f65..a6e8cac47d3766d218cd8392500d8f633feb1c82 100644 (file)
@@ -4,7 +4,7 @@ CLASS(MineLayer, Weapon)
 /* ammotype  */ ATTRIB(MineLayer, ammo_field, .int, ammo_rockets);
 /* impulse   */ ATTRIB(MineLayer, impulse, int, 4);
 /* flags     */ ATTRIB(MineLayer, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(MineLayer, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(MineLayer, bot_pickupbasevalue, float, 7000);
 /* color     */ ATTRIB(MineLayer, wpcolor, vector, '0.75 1 0');
 /* modelname */ ATTRIB(MineLayer, mdl, string, "minelayer");
 #ifdef GAMEQC
index 56338da17182d72edbc50b1887e3fbb968786e8b..0ea0f1b1b03018aa46b91413a120e80cd5d1097d 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Mortar, Weapon)
 /* ammotype  */ ATTRIB(Mortar, ammo_field, .int, ammo_rockets);
 /* impulse   */ ATTRIB(Mortar, impulse, int, 4);
 /* flags     */ ATTRIB(Mortar, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Mortar, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Mortar, bot_pickupbasevalue, float, 7000);
 /* color     */ ATTRIB(Mortar, wpcolor, vector, '1 0 0');
 /* modelname */ ATTRIB(Mortar, mdl, string, "gl");
 #ifdef GAMEQC
index 37d8e0e23a22eee23405f8664fb4f2a73f4f2b00..d75b1fe8df3c2102e1e34caa1aeb73580ff862eb 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Rifle, Weapon)
 /* ammotype  */ ATTRIB(Rifle, ammo_field, .int, ammo_nails);
 /* impulse   */ ATTRIB(Rifle, impulse, int, 7);
 /* flags     */ ATTRIB(Rifle, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
-/* rating    */ ATTRIB(Rifle, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Rifle, bot_pickupbasevalue, float, 7000);
 /* color     */ ATTRIB(Rifle, wpcolor, vector, '0.5 1 0');
 /* modelname */ ATTRIB(Rifle, mdl, string, "campingrifle");
 #ifdef GAMEQC
index 20f5995e547c06c66a407f8267b03b149cfe17cd..0f4891837fb492b34f06a91f01142cd483c4bc51 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Seeker, Weapon)
 /* ammotype  */ ATTRIB(Seeker, ammo_field, .int, ammo_rockets);
 /* impulse   */ ATTRIB(Seeker, impulse, int, 8);
 /* flags     */ ATTRIB(Seeker, spawnflags, int, WEP_FLAG_MUTATORBLOCKED | WEP_FLAG_RELOADABLE | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Seeker, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(Seeker, bot_pickupbasevalue, float, 5000);
 /* color     */ ATTRIB(Seeker, wpcolor, vector, '0.5 1 0');
 /* modelname */ ATTRIB(Seeker, mdl, string, "seeker");
 #ifdef GAMEQC
index 823aac11c1d223a35ab068280503eb628194aa7b..17d055fe4829b5ee0de9a7eb42e41e5233bf95cd 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Shockwave, Weapon)
 /* ammotype  */ //ATTRIB(Shockwave, ammo_field, .int, ammo_none);
 /* impulse   */ ATTRIB(Shockwave, impulse, int, 2);
 /* flags     */ ATTRIB(Shockwave, spawnflags, int, WEP_TYPE_HITSCAN | WEP_FLAG_CANCLIMB | WEP_TYPE_MELEE_SEC);
-/* rating    */ ATTRIB(Shockwave, bot_pickupbasevalue, float, BOT_PICKUP_RATING_LOW);
+/* rating    */ ATTRIB(Shockwave, bot_pickupbasevalue, float, 3000);
 /* color     */ ATTRIB(Shockwave, wpcolor, vector, '0.5 0.25 0');
 /* modelname */ ATTRIB(Shockwave, mdl, string, "shotgun");
 #ifdef GAMEQC
index f6d730fcb1f9dffc28331e6d17e718558f190779..e597665c5ebee23918afad49a5a47cf2abb48145 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Shotgun, Weapon)
 /* ammotype  */ ATTRIB(Shotgun, ammo_field, .int, ammo_shells);
 /* impulse   */ ATTRIB(Shotgun, impulse, int, 2);
 /* flags     */ ATTRIB(Shotgun, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN | WEP_TYPE_MELEE_SEC);
-/* rating    */ ATTRIB(Shotgun, bot_pickupbasevalue, float, BOT_PICKUP_RATING_LOW);
+/* rating    */ ATTRIB(Shotgun, bot_pickupbasevalue, float, 6000);
 /* color     */ ATTRIB(Shotgun, wpcolor, vector, '0.5 0.25 0');
 /* modelname */ ATTRIB(Shotgun, mdl, string, "shotgun");
 #ifdef GAMEQC
index 09d050833b46de6323e9cf880cce3c80b2b2cd44..988ee7355664f15cc045583c6a074b4df1d55be1 100644 (file)
@@ -3,7 +3,7 @@
 CLASS(Tuba, Weapon)
 /* impulse   */ ATTRIB(Tuba, impulse, int, 1);
 /* flags     */ ATTRIB(Tuba, spawnflags, int, WEP_FLAG_HIDDEN | WEP_TYPE_SPLASH);
-/* rating    */ ATTRIB(Tuba, bot_pickupbasevalue, float, BOT_PICKUP_RATING_MID);
+/* rating    */ ATTRIB(Tuba, bot_pickupbasevalue, float, 2000);
 /* color     */ ATTRIB(Tuba, wpcolor, vector, '0 1 0');
 /* modelname */ ATTRIB(Tuba, mdl, string, "tuba");
 #ifdef GAMEQC
index 3e2575838b8b19ef64c081f01d18df4947ee1a58..de2edbeefe8dfdfce43a75b548ad66cdd8929fa2 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Vaporizer, Weapon)
 /* ammotype  */ ATTRIB(Vaporizer, ammo_field, .int, ammo_cells);
 /* impulse   */ ATTRIB(Vaporizer, impulse, int, 7);
 /* flags     */ ATTRIB(Vaporizer, spawnflags, int, WEP_FLAG_RELOADABLE | WEP_FLAG_CANCLIMB | WEP_FLAG_SUPERWEAPON | WEP_TYPE_HITSCAN);
-/* rating    */ ATTRIB(Vaporizer, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(Vaporizer, bot_pickupbasevalue, float, 10000);
 /* color     */ ATTRIB(Vaporizer, wpcolor, vector, '0.5 1 1');
 /* modelname */ ATTRIB(Vaporizer, mdl, string, "minstanex");
 #ifdef GAMEQC
index 34d9fb8dd8e924842cd357a4e3990dc5386219ca..abb84008e06de9cf34d34ea91a94189c0df95db8 100644 (file)
@@ -4,7 +4,7 @@ CLASS(Vortex, Weapon)
 /* ammotype  */ ATTRIB(Vortex, ammo_field, .int, ammo_cells);
 /* impulse   */ ATTRIB(Vortex, impulse, int, 7);
 /* flags     */ ATTRIB(Vortex, spawnflags, int, WEP_FLAG_NORMAL | WEP_FLAG_RELOADABLE | WEP_TYPE_HITSCAN);
-/* rating    */ ATTRIB(Vortex, bot_pickupbasevalue, float, BOT_PICKUP_RATING_HIGH);
+/* rating    */ ATTRIB(Vortex, bot_pickupbasevalue, float, 8000);
 /* color     */ ATTRIB(Vortex, wpcolor, vector, '0.5 1 1');
 /* modelname */ ATTRIB(Vortex, mdl, string, "nex");
 #ifdef GAMEQC
index 32559afbc803e1d4f43ca742d2058c2a809ce230..5f3bd4b39597fff8371f165f8cfa2edecc77d92d 100644 (file)
@@ -1051,11 +1051,11 @@ void havocbot_goalrating_kh(entity this, float ratingscale_team, float ratingsca
                        }
                }
                if(!head.owner)
-                       navigation_routerating(this, head, ratingscale_dropped * BOT_PICKUP_RATING_HIGH, 100000);
+                       navigation_routerating(this, head, ratingscale_dropped * 10000, 100000);
                else if(head.team == this.team)
-                       navigation_routerating(this, head.owner, ratingscale_team * BOT_PICKUP_RATING_HIGH, 100000);
+                       navigation_routerating(this, head.owner, ratingscale_team * 10000, 100000);
                else
-                       navigation_routerating(this, head.owner, ratingscale_enemy * BOT_PICKUP_RATING_HIGH, 100000);
+                       navigation_routerating(this, head.owner, ratingscale_enemy * 10000, 100000);
        }
 
        havocbot_goalrating_items(this, 1, this.origin, 10000);