From 07f92afac006497cfe761652ff4ee8aa18925c5a Mon Sep 17 00:00:00 2001
From: terencehill <piuntn@gmail.com>
Date: Thu, 19 Jan 2017 00:45:21 +0100
Subject: [PATCH] Rate more small healths/armors in groups

---
 qcsrc/common/t_items.qc         | 67 +++++++++++++++++++++++++++++++--
 qcsrc/common/t_items.qh         |  2 +
 qcsrc/server/bot/default/bot.qc |  1 +
 3 files changed, 66 insertions(+), 4 deletions(-)

diff --git a/qcsrc/common/t_items.qc b/qcsrc/common/t_items.qc
index 7ea83888c9..dc16cc4ab3 100644
--- a/qcsrc/common/t_items.qc
+++ b/qcsrc/common/t_items.qc
@@ -1043,17 +1043,26 @@ float ammo_pickupevalfunc(entity player, entity item)
 	return rating;
 }
 
+.int item_group;
+.int item_group_count;
 float healtharmor_pickupevalfunc(entity player, entity item)
 {
 	float c = 0;
 	float rating = item.bot_pickupbasevalue;
 
-	if (item.armorvalue)
+	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 = item.armorvalue / max(1, player.armorvalue * 2/3 + player.health * 1/3);
-	if (item.health)
+		c = itemarmor / max(1, player.armorvalue * 2/3 + player.health * 1/3);
+	if (itemhealth)
 	if (player.health < item.max_health)
-		c = item.health / max(1, player.health);
+		c = itemhealth / max(1, player.health);
 
 	rating *= min(2, c);
 	return rating;
@@ -1274,6 +1283,8 @@ void _StartItem(entity this, entity def, float defaultrespawntime, float default
 		delete(this);
 		return;
 	}
+
+	setItemGroup(this);
 }
 
 void StartItem(entity this, GameItem def)
@@ -1286,6 +1297,54 @@ 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)
diff --git a/qcsrc/common/t_items.qh b/qcsrc/common/t_items.qh
index f5a310562b..1b2293bcff 100644
--- a/qcsrc/common/t_items.qh
+++ b/qcsrc/common/t_items.qh
@@ -114,6 +114,8 @@ float healtharmor_pickupevalfunc(entity player, entity item);
 .entity itemdef;
 void _StartItem(entity this, entity def, float defaultrespawntime, float defaultrespawntimejitter);
 
+void setItemGroup(entity this);
+void setItemGroupCount();
 
 float GiveWeapon(entity e, float wpn, float op, float val);
 
diff --git a/qcsrc/server/bot/default/bot.qc b/qcsrc/server/bot/default/bot.qc
index 160f8ec90b..2fb0a43c2b 100644
--- a/qcsrc/server/bot/default/bot.qc
+++ b/qcsrc/server/bot/default/bot.qc
@@ -46,6 +46,7 @@ entity bot_spawn()
 	entity bot = spawnclient();
 	if (bot)
 	{
+		setItemGroupCount();
 		currentbots = currentbots + 1;
 		bot_setnameandstuff(bot);
 		ClientConnect(bot);
-- 
2.39.5