Author: sveinung
Date: Fri Aug 21 12:26:25 2015
New Revision: 29624

URL: http://svn.gna.org/viewcvs/freeciv?rev=29624&view=rev
Log:
Unhardcode can't found city on foreign tile

Move the rule that a city can't be founded on a tile claimed by another
player to the ruleset.

See patch #6264

Modified:
    trunk/common/city.c
    trunk/common/requirements.c
    trunk/data/alien/game.ruleset
    trunk/data/civ1/game.ruleset
    trunk/data/civ2/game.ruleset
    trunk/data/civ2civ3/game.ruleset
    trunk/data/classic/game.ruleset
    trunk/data/experimental/game.ruleset
    trunk/data/multiplayer/game.ruleset
    trunk/doc/README.actions
    trunk/server/rscompat.c

Modified: trunk/common/city.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/city.c?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/common/city.c (original)
+++ trunk/common/city.c Fri Aug 21 12:26:25 2015
@@ -1388,6 +1388,64 @@
   return (CB_OK == city_build_here_test(ptile, punit));
 }
 
+/**************************************************************************
+  Return TRUE iff the ruleset allows founding a city at a tile claimed by
+  someone else.
+
+  Since a local DiplRel requirement can be against something else than a
+  tile an unclaimed tile can't always contradict a local DiplRel
+  requirement. With knowledge about what entities each requirement in a
+  requirement vector is evaluated against a contradiction can be
+  introduced.
+
+  TODO: Get rid of this together with CB_BAD_BORDERS and UAB_BAD_BORDERS.
+  Maybe get rid of it before if the problem above is solved.
+**************************************************************************/
+static bool city_on_foreign_tile_is_legal(struct unit_type *punit_type)
+{
+  struct requirement tile_is_claimed;
+  struct requirement tile_is_foreign;
+
+  if (!is_actor_unit_type(punit_type)) {
+    /* Not an actor unit type. */
+    return FALSE;
+  }
+
+  /* Tile is claimed as a requirement. */
+  tile_is_claimed.range = REQ_RANGE_LOCAL;
+  tile_is_claimed.survives = FALSE;
+  tile_is_claimed.source.kind = VUT_CITYTILE;
+  tile_is_claimed.present = TRUE;
+  tile_is_claimed.source.value.citytile = CITYT_CLAIMED;
+
+  /* Tile is foreign as a requirement. */
+  tile_is_foreign.range = REQ_RANGE_LOCAL;
+  tile_is_foreign.survives = FALSE;
+  tile_is_foreign.source.kind = VUT_DIPLREL;
+  tile_is_foreign.present = TRUE;
+  tile_is_foreign.source.value.citytile = DRO_FOREIGN;
+
+  action_enabler_list_iterate(
+        action_enablers_for_action(ACTION_FOUND_CITY), enabler) {
+    if (!requirement_fulfilled_by_unit_type(punit_type,
+                                            &(enabler->actor_reqs))) {
+      /* This action enabler isn't for this unit type at all. */
+      continue;
+    }
+
+    if (!(does_req_contradicts_reqs(&tile_is_claimed,
+                                    &(enabler->target_reqs))
+          || does_req_contradicts_reqs(&tile_is_foreign,
+                                       &(enabler->actor_reqs)))) {
+      /* This ruleset permits city founding on foreign tiles. */
+      return TRUE;
+    }
+  } action_enabler_list_iterate_end;
+
+  /* This ruleset forbids city founding on foreign tiles. */
+  return FALSE;
+}
+
 /****************************************************************************
   Returns CB_OK if the given unit can build a city at the given map
   coordinates. Else, returns the reason of the failure.
@@ -1416,7 +1474,11 @@
     return CB_BAD_UNIT_TERRAIN;
   }
 
-  if (punit && tile_owner(ptile) && tile_owner(ptile) != unit_owner(punit)) {
+  if (punit && tile_owner(ptile) && tile_owner(ptile) != unit_owner(punit)
+      /* TODO: remove CB_BAD_BORDERS and UAB_BAD_BORDERS when it
+       * can be done without regressions. */
+      /* The ruleset may allow founding cities on foreign terrain. */
+      && !city_on_foreign_tile_is_legal(unit_type(punit))) {
     /* Cannot steal borders by settling. This has to be settled by
      * force of arms. */
     return CB_BAD_BORDERS;

Modified: trunk/common/requirements.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/requirements.c?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/common/requirements.c (original)
+++ trunk/common/requirements.c Fri Aug 21 12:26:25 2015
@@ -914,6 +914,10 @@
 
 /**************************************************************************
   Returns TRUE if req1 and req2 contradicts each other.
+
+  TODO: If information about what entity each requirement type will be
+  evaluated against is passed it will become possible to detect stuff like
+  that an unclaimed tile contradicts all DiplRel requirements against it.
 **************************************************************************/
 bool are_requirements_contradictions(const struct requirement *req1,
                                      const struct requirement *req2)

Modified: trunk/data/alien/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/alien/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/alien/game.ruleset       (original)
+++ trunk/data/alien/game.ruleset       Fri Aug 21 12:26:25 2015
@@ -359,13 +359,27 @@
       "TerrainClass", "Oceanic", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/data/civ1/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/civ1/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/civ1/game.ruleset        (original)
+++ trunk/data/civ1/game.ruleset        Fri Aug 21 12:26:25 2015
@@ -332,13 +332,27 @@
       "DiplRel", "Is foreign", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/data/civ2/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/civ2/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/civ2/game.ruleset        (original)
+++ trunk/data/civ2/game.ruleset        Fri Aug 21 12:26:25 2015
@@ -410,13 +410,27 @@
       "DiplRel", "Is foreign", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/data/civ2civ3/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/civ2civ3/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/civ2civ3/game.ruleset    (original)
+++ trunk/data/civ2civ3/game.ruleset    Fri Aug 21 12:26:25 2015
@@ -459,13 +459,27 @@
       "TerrainClass", "Oceanic", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/data/classic/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/classic/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/classic/game.ruleset     (original)
+++ trunk/data/classic/game.ruleset     Fri Aug 21 12:26:25 2015
@@ -415,13 +415,27 @@
       "DiplRel", "Is foreign", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/data/experimental/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/experimental/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/experimental/game.ruleset        (original)
+++ trunk/data/experimental/game.ruleset        Fri Aug 21 12:26:25 2015
@@ -433,13 +433,27 @@
       "DiplRel", "Is foreign", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/data/multiplayer/game.ruleset
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/data/multiplayer/game.ruleset?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/data/multiplayer/game.ruleset (original)
+++ trunk/data/multiplayer/game.ruleset Fri Aug 21 12:26:25 2015
@@ -399,13 +399,27 @@
       "DiplRel", "Is foreign", "Local", FALSE
     }
 
-[actionenabler_build_city]
+[actionenabler_build_city_pinoneer]
 action = "Found City"
 actor_reqs    =
     { "type",   "name", "range"
       "UnitFlag", "Cities", "Local"
       "UnitState", "OnLivableTile", "Local"
       "MinMoveFrags", "1", "Local"
+    }
+target_reqs    =
+    { "type",   "name", "range", "present"
+      "CityTile", "Claimed", "Local", FALSE
+    }
+
+[actionenabler_build_city_domestic]
+action = "Found City"
+actor_reqs    =
+    { "type",   "name", "range", "present"
+      "UnitFlag", "Cities", "Local", TRUE
+      "UnitState", "OnLivableTile", "Local", TRUE
+      "MinMoveFrags", "1", "Local", TRUE
+      "DiplRel", "Is foreign", "Local", FALSE
     }
 
 [actionenabler_join_city]

Modified: trunk/doc/README.actions
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/doc/README.actions?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/doc/README.actions    (original)
+++ trunk/doc/README.actions    Fri Aug 21 12:26:25 2015
@@ -279,7 +279,6 @@
  * the scenario setting prevent_new_cities must be false.
  * actor must be on the same tile as the target.
  * target must not have the NoCities terrain flag.
- * target must not be owned by a foreign player.
  * target must not be closer than citymindist to nearest city.
 
 "Explode Nuclear" - Detonate at the target tile. Cause a nuclear explosion.

Modified: trunk/server/rscompat.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/rscompat.c?rev=29624&r1=29623&r2=29624&view=diff
==============================================================================
--- trunk/server/rscompat.c     (original)
+++ trunk/server/rscompat.c     Fri Aug 21 12:26:25 2015
@@ -283,9 +283,11 @@
 
     action_enabler_add(enabler);
 
-    /* City founding is now action enabler controlled. Add the old rule
-     * that units with the Cities unit type flag can found a city.
-     * Other requirements are still hard coded. */
+    /* City founding is now action enabler controlled. Add the old rules.
+     * The rule that a city can't be founded on a tile claimed by another
+     * player has to be translated to "a city can be founded on an
+     * unclaimed tile OR on a tile owned by the actor player. That results
+     * in two action enablers. */
 
     enabler = action_enabler_new();
 
@@ -305,6 +307,37 @@
     requirement_vector_append(&enabler->actor_reqs,
                               req_from_str("MinMoveFrags", "Local", FALSE,
                                            TRUE, TRUE, "1"));
+
+    /* The target tile can't be claimed. */
+    requirement_vector_append(&enabler->target_reqs,
+                              req_from_str("CityTile", "Local", FALSE,
+                                           FALSE, TRUE, "Claimed"));
+
+    action_enabler_add(enabler);
+
+    enabler = action_enabler_new();
+
+    enabler->action = ACTION_FOUND_CITY;
+
+    /* The actor unit must have the unit type flag Cities. */
+    requirement_vector_append(&enabler->actor_reqs,
+                              req_from_str("UnitFlag", "Local", FALSE,
+                                           TRUE, TRUE, "Cities"));
+
+    /* The actor must be on native terrain. */
+    requirement_vector_append(&enabler->actor_reqs,
+                              req_from_str("UnitState", "Local", FALSE,
+                                           TRUE, TRUE, "OnLivableTile"));
+
+    /* The actor unit must have moves left. */
+    requirement_vector_append(&enabler->actor_reqs,
+                              req_from_str("MinMoveFrags", "Local", FALSE,
+                                           TRUE, TRUE, "1"));
+
+    /* The target tile must be domestic. */
+    requirement_vector_append(&enabler->actor_reqs,
+                              req_from_str("DiplRel", "Local", FALSE,
+                                           FALSE, TRUE, "Is foreign"));
 
     action_enabler_add(enabler);
 


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

Reply via email to