Re: [Freeciv-Dev] Patch: Generalizing bonus such F_HORSE vs. F_PIKEMEN

2009-01-02 Thread Marko Lindqvist
 The reason I have not written similar patch is that it would require
too many unit classes to be practical. You didn't include ruleset
changes to your patch, but if you do those properly you will notice
how much duplicate entries you have to write (if you have classes
Horses, Pikemen and Land, you need to include similar effects
for all three classes in effects.ruleset).
 It would be a bit better if you target unit types instead of unit
classes, but then we have hardcoded limit of four types to have
bonuses against. Hmm... Actually that limit might be quite bad for
class based approach too - if number of classes explodes like Land +
Horses + Pikemen, you need three slots just for land moving units.

 Anyway, these things need to be generalized (there's old ticket about
this somewhere, possibly with additional info) so I would very much
like to see somehow improved version of this patch.

2009/1/2 Yoav Luft:
 B. The code on helpdata.c does not work, it always see NULL pointers,
 altough everywhere else it doesn't happen.

 Help is in client side while all the other code you touch is in
server side. You need to change network protocol and to send this new
information to client side as well.


 - ML

___
Freeciv-dev mailing list
Freeciv-dev@gna.org
https://mail.gna.org/listinfo/freeciv-dev


[Freeciv-Dev] Patch: Generalizing bonus such F_HORSE vs. F_PIKEMEN

2009-01-01 Thread Yoav Luft
This patch is supposed to allow modders to use more bonuses against
specific units.
It adds for the units.ruleset the following optional fields:
bonus_against_classX = Class Name - against which class we get
bonus. the X is a number from 1 to 4, so we can have different bonuses
against up to 4 different classes.
defense_bonusX = (percent value) - percent by which unit's defense is
increased against the class given in bonus_against_classX. Notice that
the X must be the same number. Also, negetive value will decrease our
defense. E.g - 100 will double our defense (adds it's full value to
itself), while -50 will halve it.
attack_bonusX = (percent value)
attack_firepowerX = (number) - The firepower when attacking that
class, the default is keeping the same firepower.
defense_firepowerX = (number) - As above, but when defending against that class.

I am sending this to the mailing list first because:
A. I am not sure my approach is good. It works, but it's not
nesseceraily the best solution.
B. The code on helpdata.c does not work, it always see NULL pointers,
altough everywhere else it doesn't happen.
diff -r -u trunk/ai/advmilitary.c trunk-class-bonus/ai/advmilitary.c
--- trunk/ai/advmilitary.c	2008-10-26 18:33:50.0 +0200
+++ trunk-class-bonus/ai/advmilitary.c	2008-12-22 13:19:16.0 +0200
@@ -488,6 +488,8 @@
 static unsigned int assess_danger(struct city *pcity)
 {
   int i;
+	int j;
+	int h = 0;
   unsigned int danger[DANGER_LAST];
   int defender;
   struct player *pplayer = city_owner(pcity);
@@ -496,6 +498,8 @@
   int igwall_threat = 0;
   struct tile *ptile = pcity-tile;
   int defense;
+#define MAX_DEFENSE_BONUS 8
+	struct unit_class *(defense_bonuses)[MAX_DEFENSE_BONUS];
 
   TIMING_LOG(AIT_DANGER, TIMER_START);
 
@@ -514,7 +518,19 @@
 
   unit_list_iterate(ptile-units, punit) {
 if (unit_has_type_flag(punit, F_DIPLOMAT)) pcity-ai.has_diplomat = TRUE;
+		/* Check if the defender has some bonus against any type at all */
+		int j;
+		for (j = 0; j = CLASS_BONUS_MAX; j++) {
+			if (punit-utype-bonuses[j].class_bonus == NULL) {
+continue;
+			} else {
+if (punit-utype-bonuses[j].defense_bonus != 0) {
+	defense_bonuses[h] = punit-utype-bonuses[j].class_bonus;
+	h++;
+}
+			}
+		}
   } unit_list_iterate_end;
 
   players_iterate(aplayer) {
@@ -567,14 +583,23 @@
   }
 
   if (unit_has_type_flag(punit, F_HORSE)) {
-	if (pikemen) {
-	  vulnerability /= 2;
-	} else {
-	  (void) ai_wants_role_unit(pplayer, pcity, F_PIKEMEN,
-vulnerability * move_rate /
-MAX(dist * 2, 1));
-	}
-  }
+if (pikemen) {
+	vulnerability /= 2;
+} else {
+	(void) ai_wants_role_unit(pplayer, pcity, F_PIKEMEN,
+	vulnerability * move_rate /
+	MAX(dist * 2, 1));
+}
+  }
+
+			/* we check whether we have a unit with a bonus against that class
+			 * if so, we reduce vulnerability to half (regradless of the bonus)
+			 */
+			for (j = 0; j  h; j++) {
+if (punit-utype-uclass == defense_bonuses[j]) {
+		vulnerability /= 2;
+		}
+	}
 
   if (unit_has_type_flag(punit, F_DIPLOMAT)  (dist = 2 * move_rate)) {
 	pcity-ai.diplomat_threat = TRUE;
@@ -681,6 +706,7 @@
   int desire = punittype-hp;
   int attack = punittype-attack_strength;
   int defense = punittype-defense_strength;
+	int defense_bonus = 0;
 
   /* Sea and helicopters often have their firepower set to 1 when
* defending. We can't have such units as defenders. */
@@ -699,6 +725,17 @@
   if (utype_has_flag(punittype, F_GAMELOSS)) {
 desire /= 10; /* but might actually be worth it */
   }
+	/* if unit has any defense bonus at all */
+	int i;
+	for (i = 0; i = CLASS_BONUS_MAX; i++) {
+		if (punittype-bonuses[i].class_bonus == NULL) {
+			continue;
+		} else {
+			defense_bonus += punittype-bonuses[i].defense_bonus;
+		}
+	}
+	desire += (defense_bonus * defense) / 100;
+
   return desire;
 }
 
diff -r -u trunk/client/helpdata.c trunk-class-bonus/client/helpdata.c
--- trunk/client/helpdata.c	2008-11-21 07:54:27.0 +0200
+++ trunk-class-bonus/client/helpdata.c	2008-12-24 19:20:24.0 +0200
@@ -1012,6 +1012,51 @@
 		for the attacker.\n),
 		 utype-bombard_rate);
   }
+	/* Get some information about unit bonuses */
+	int i;
+	for (i = 0; i  CLASS_BONUS_MAX; i++) {
+		if (utype-bonuses[i].class_bonus == NULL) {
+			continue;
+		} 
+		if (utype-bonuses[i].attack_bonus  0) {
+			cat_snprintf(buf, bufsz,
+	_(* Gets %d percent attack bonus against units of %s class.\n),
+	utype-bonuses[i].attack_bonus,
+	uclass_name_translation(utype-bonuses[i].class_bonus));
+		}
+		if (utype-bonuses[i].attack_bonus  0) {
+			cat_snprintf(buf, bufsz,
+	_(* Gets %d percent attack penalty against units of %s class.\n),
+	utype-bonuses[i].attack_bonus,
+	uclass_name_translation(utype-bonuses[i].class_bonus));
+		}
+		if (utype-bonuses[i].defense_bonus  0) {
+			cat_snprintf(buf, bufsz,
+	_(* Gets %d percent defense bonus against units of %s