Author: sveinung
Date: Sun Sep 13 19:28:12 2015
New Revision: 29875

URL: http://svn.gna.org/viewcvs/freeciv?rev=29875&view=rev
Log:
Set local building and utype for city targets

Set the target building and target utype for the target vector of any action
enabler that enables a unit to act against a city.

The initial semantic is that the target city's current production provides
the building type or unit type for local requirements. This makes the target
utype NULL when a building is being built and vice versa. This keeps the
action enabler semantic consistent for all unit vs city actions.

A possible future semantic change is to set the local building to the
specified building target for actions that specifies one while keeping the
current semantic for all other actions.

See patch #6344

Modified:
    trunk/common/actions.c

Modified: trunk/common/actions.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.c?rev=29875&r1=29874&r2=29875&view=diff
==============================================================================
--- trunk/common/actions.c      (original)
+++ trunk/common/actions.c      Sun Sep 13 19:28:12 2015
@@ -529,6 +529,51 @@
 }
 
 /**************************************************************************
+  Returns the local building type of a city target.
+
+  target_city can't be NULL
+**************************************************************************/
+static struct impr_type *
+tgt_city_local_building(const struct city *target_city)
+{
+  /* Only used with city targets */
+  fc_assert_ret_val(target_city, NULL);
+
+  if (target_city->production.kind == VUT_IMPROVEMENT) {
+    /* The local building is what the target city currently is building. */
+    return target_city->production.value.building;
+  } else {
+    /* In the current semantic the local building is always the building
+     * being built. */
+    /* TODO: Consider making the local building the target building for
+     * actions that allows specifying a building target. */
+    return NULL;
+  }
+}
+
+/**************************************************************************
+  Returns the local unit type of a city target.
+
+  target_city can't be NULL
+**************************************************************************/
+static struct unit_type *
+tgt_city_local_utype(const struct city *target_city)
+{
+  /* Only used with city targets */
+  fc_assert_ret_val(target_city, NULL);
+
+  if (target_city->production.kind == VUT_UTYPE) {
+    /* The local unit type is what the target city currently is
+     * building. */
+    return target_city->production.value.utype;
+  } else {
+    /* In the current semantic the local utype is always the type of the
+     * unit being built. */
+    return NULL;
+  }
+}
+
+/**************************************************************************
   Returns TRUE iff trade route establishing is forced and possible.
 **************************************************************************/
 static bool trade_route_blocks(const struct unit *actor_unit,
@@ -1034,6 +1079,9 @@
                                     const struct unit *actor_unit,
                                     const struct city *target_city)
 {
+  struct impr_type *target_building;
+  struct unit_type *target_utype;
+
   if (actor_unit == NULL || target_city == NULL) {
     /* Can't do an action when actor or target are missing. */
     return FALSE;
@@ -1053,13 +1101,17 @@
                           action_get_target_kind(wanted_action)),
                         action_target_kind_name(ATK_CITY));
 
+  target_building = tgt_city_local_building(target_city);
+  target_utype = tgt_city_local_utype(target_city);
+
   return is_action_enabled(wanted_action,
                            unit_owner(actor_unit), NULL, NULL,
                            unit_tile(actor_unit),
                            actor_unit, unit_type(actor_unit),
                            NULL, NULL,
-                           city_owner(target_city), target_city, NULL,
-                           city_tile(target_city), NULL, NULL, NULL, NULL);
+                           city_owner(target_city), target_city,
+                           target_building, city_tile(target_city),
+                           NULL, target_utype, NULL, NULL);
 }
 
 /**************************************************************************
@@ -1440,6 +1492,7 @@
             const struct impr_type *actor_building,
             const struct tile *actor_tile,
             const struct unit *actor_unit,
+            const struct unit_type *actor_unittype_p,
             const struct output_type *actor_output,
             const struct specialist *actor_specialist,
             const struct player *target_player,
@@ -1447,6 +1500,7 @@
             const struct impr_type *target_building,
             const struct tile *target_tile,
             const struct unit *target_unit,
+            const struct unit_type *target_unittype_p,
             const struct output_type *target_output,
             const struct specialist *target_specialist)
 {
@@ -1456,16 +1510,16 @@
   const struct unit_type *actor_unittype;
   const struct unit_type *target_unittype;
 
-  if (actor_unit == NULL) {
-    actor_unittype = NULL;
+  if (actor_unittype_p == NULL && actor_unit != NULL) {
+    actor_unittype = unit_type(actor_unit);
   } else {
-    actor_unittype = unit_type(actor_unit);
-  }
-
-  if (target_unit == NULL) {
-    target_unittype = NULL;
+    actor_unittype = actor_unittype_p;
+  }
+
+  if (target_unittype_p == NULL && target_unit != NULL) {
+    target_unittype = unit_type(target_unit);
   } else {
-    target_unittype = unit_type(target_unit);
+    target_unittype = target_unittype_p;
   }
 
   if (!is_action_possible(wanted_action,
@@ -1613,6 +1667,9 @@
                                        const int action_id,
                                        const struct city* target_city)
 {
+  struct impr_type *target_building;
+  struct unit_type *target_utype;
+
   if (actor_unit == NULL || target_city == NULL) {
     /* Can't do an action when actor or target are missing. */
     return ACTPROB_IMPOSSIBLE;
@@ -1632,12 +1689,16 @@
                           action_get_target_kind(action_id)),
                         action_target_kind_name(ATK_CITY));
 
+  target_building = tgt_city_local_building(target_city);
+  target_utype = tgt_city_local_utype(target_city);
+
   return action_prob(action_id,
                      unit_owner(actor_unit), NULL, NULL,
-                     unit_tile(actor_unit), actor_unit,
+                     unit_tile(actor_unit), actor_unit, NULL,
                      NULL, NULL,
-                     city_owner(target_city), target_city, NULL,
-                     city_tile(target_city), NULL, NULL, NULL);
+                     city_owner(target_city), target_city,
+                     target_building, city_tile(target_city),
+                     NULL, target_utype, NULL, NULL);
 }
 
 /**************************************************************************
@@ -1669,12 +1730,12 @@
 
   return action_prob(action_id,
                      unit_owner(actor_unit), NULL, NULL,
-                     unit_tile(actor_unit), actor_unit,
+                     unit_tile(actor_unit), actor_unit, NULL,
                      NULL, NULL,
                      unit_owner(target_unit),
                      tile_city(unit_tile(target_unit)), NULL,
                      unit_tile(target_unit),
-                     target_unit, NULL, NULL);
+                     target_unit, NULL, NULL, NULL);
 }
 
 /**************************************************************************
@@ -1712,12 +1773,12 @@
     int prob_unit = action_prob(action_id,
                                 unit_owner(actor_unit), NULL, NULL,
                                 unit_tile(actor_unit),
-                                actor_unit,
+                                actor_unit, NULL,
                                 NULL, NULL,
                                 unit_owner(target_unit),
                                 tile_city(unit_tile(target_unit)), NULL,
                                 unit_tile(target_unit),
-                                target_unit,
+                                target_unit, NULL,
                                 NULL, NULL);
 
     switch (prob_unit) {
@@ -1784,10 +1845,10 @@
   return action_prob(action_id,
                      unit_owner(actor_unit), NULL, NULL,
                      unit_tile(actor_unit),
-                     actor_unit,
+                     actor_unit, NULL,
                      NULL, NULL,
                      tile_owner(target_tile), NULL, NULL,
-                     target_tile, NULL, NULL, NULL);
+                     target_tile, NULL, NULL, NULL, NULL);
 }
 
 /**************************************************************************


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

Reply via email to