Author: sveinung
Date: Fri Jun 26 21:26:27 2015
New Revision: 29189

URL: http://svn.gna.org/viewcvs/freeciv?rev=29189&view=rev
Log:
Update action probability vs individual unit calculation

so it reflects rule changes.

Rule changes:
 * It's not certain that the victim unit is alone at its tile.
 * It's not certain that the actor is foreign.
 * The victim unit of sabotage won't defend it self in a diplomatic battle.

See bug #23649

Modified:
    branches/S2_6/common/actions.c

Modified: branches/S2_6/common/actions.c
URL: 
http://svn.gna.org/viewcvs/freeciv/branches/S2_6/common/actions.c?rev=29189&r1=29188&r2=29189&view=diff
==============================================================================
--- branches/S2_6/common/actions.c      (original)
+++ branches/S2_6/common/actions.c      Fri Jun 26 21:26:27 2015
@@ -825,11 +825,12 @@
 /**************************************************************************
   The action probability that pattacker will win a diplomatic battle.
 
-  It is assumed that pattacker and pdefender have different owners.
-
-  See diplomat_infiltrate_tile() in server/diplomats.c
-**************************************************************************/
-static action_probability ap_diplomat_battle(const struct unit *pattacker,
+  It is assumed that pattacker and pdefender have different owners and that
+  the defender can defend in a diplomatic battle.
+
+  See diplomat_success_vs_defender() in server/diplomats.c
+**************************************************************************/
+static action_probability ap_dipl_battle_win(const struct unit *pattacker,
                                              const struct unit *pdefender)
 {
   struct city *pcity;
@@ -839,15 +840,12 @@
 
   /* Superspy always win */
   if (unit_has_type_flag(pdefender, UTYF_SUPERSPY)) {
-    /* In UTYF_SUPERSPY vs UTYF_SUPERSPY the attacker always dies. */
+    /* A defending UTYF_SUPERSPY will defeat every possible attacker. */
     return ACTPROB_IMPOSSIBLE;
   }
   if (unit_has_type_flag(pattacker, UTYF_SUPERSPY)) {
-    return 200;
-  }
-
-  /* This target is defenseless */
-  if (!unit_has_type_flag(pdefender, UTYF_DIPLOMAT)) {
+    /* An attacking UTYF_SUPERSPY will defeat every possible defender
+     * except another UTYF_SUPERSPY. */
     return 200;
   }
 
@@ -894,6 +892,39 @@
 
   /* Convert to action probability */
   return chance * 2;
+}
+
+/**************************************************************************
+  The action probability that pattacker will win a diplomatic battle.
+
+  See diplomat_infiltrate_tile() in server/diplomats.c
+**************************************************************************/
+static action_probability ap_diplomat_battle(const struct unit *pattacker,
+                                             const struct unit *pvictim)
+{
+  unit_list_iterate(unit_tile(pvictim)->units, punit) {
+    if (unit_owner(punit) == unit_owner(pattacker)) {
+      /* Won't defend against its owner. */
+      continue;
+    }
+
+    if (punit == pvictim) {
+      /* A victim unit is defenseless. */
+      continue;
+    }
+
+    if (!(unit_has_type_flag(punit, UTYF_DIPLOMAT)
+        || unit_has_type_flag(punit, UTYF_SUPERSPY))) {
+      /* The unit can't defend. */
+      continue;
+    }
+
+    /* There will be a diplomatic battle in stead of an action. */
+    return ap_dipl_battle_win(pattacker, punit);
+  } unit_list_iterate_end;
+
+  /* No diplomatic battle will occur. */
+  return 200;
 }
 
 /**************************************************************************
@@ -971,13 +1002,12 @@
     /* TODO */
     break;
   case ACTION_SPY_SABOTAGE_UNIT:
-    /* Hard coded limit: The victim unit is alone at the tile */
+    /* All uncertainty comes from potential diplomatic battles. */
     chance = ap_diplomat_battle(actor_unit, target_unit);
     break;
   case ACTION_SPY_BRIBE_UNIT:
-    /* Hard coded limit: The target unit is alone at its tile.
-     * It won't fight a diplomatic battle. */
-    chance = 200;
+    /* All uncertainty comes from potential diplomatic battles. */
+    chance = ap_diplomat_battle(actor_unit, target_unit);;
     break;
   case ACTION_SPY_SABOTAGE_CITY:
     /* TODO */


_______________________________________________
Freeciv-commits mailing list
Freeciv-commits@gna.org
https://mail.gna.org/listinfo/freeciv-commits

Reply via email to