Author: sveinung
Date: Wed Aug 19 14:24:31 2015
New Revision: 29584

URL: http://svn.gna.org/viewcvs/freeciv?rev=29584&view=rev
Log:
Explain if tgt tile city center blocks action

See patch #6251

Modified:
    trunk/common/unittype.c
    trunk/common/unittype.h
    trunk/server/unithand.c

Modified: trunk/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.c?rev=29584&r1=29583&r2=29584&view=diff
==============================================================================
--- trunk/common/unittype.c     (original)
+++ trunk/common/unittype.c     Wed Aug 19 14:24:31 2015
@@ -654,6 +654,74 @@
     }
 
     free(ml_range);
+  } action_enabler_list_iterate_end;
+
+  return FALSE;
+}
+
+/**************************************************************************
+  Return TRUE iff the given (action enabler controlled) action may be
+  performed by a unit of the given type if the target tile has the given
+  property.
+
+  Note: Values aren't cached. If a performance critical user appears it
+  would be a good idea to cache the result.
+**************************************************************************/
+bool utype_may_act_tgt_city_tile(struct unit_type *punit_type,
+                                 const int action_id,
+                                 const enum citytile_type prop,
+                                 const bool is_there)
+{
+  struct requirement req;
+
+  if (!is_actor_unit_type(punit_type)) {
+    /* Not an actor unit. */
+    return FALSE;
+  }
+
+  if (action_id == ACTION_ANY) {
+    /* Any action is OK. */
+    action_iterate(alt_act) {
+      if (utype_may_act_tgt_city_tile(punit_type, alt_act,
+                                      prop, is_there)) {
+        /* It only has to be true for one action. */
+        return TRUE;
+      }
+    } action_iterate_end;
+
+    /* No action enabled. */
+    return FALSE;
+  }
+
+  if (action_get_actor_kind(action_id) != AAK_UNIT) {
+    /* This action isn't performed by any unit at all so this unit type
+     * can't do it. */
+    return FALSE;
+  }
+
+  /* Common for every situation */
+  req.range = REQ_RANGE_LOCAL;
+  req.survives = FALSE;
+  req.source.kind = VUT_CITYTILE;
+
+  /* Will only check for the specified is_there */
+  req.present = is_there;
+
+  /* Will only check the specified property */
+  req.source.value.citytile = prop;
+
+  action_enabler_list_iterate(action_enablers_for_action(action_id),
+                              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(&req, &(enabler->target_reqs))) {
+      /* This action isn't blocked by the given target tile property. */
+      return TRUE;
+    }
   } action_enabler_list_iterate_end;
 
   return FALSE;

Modified: trunk/common/unittype.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.h?rev=29584&r1=29583&r2=29584&view=diff
==============================================================================
--- trunk/common/unittype.h     (original)
+++ trunk/common/unittype.h     Wed Aug 19 14:24:31 2015
@@ -543,6 +543,11 @@
                               const int action_id,
                               const int move_fragments);
 
+bool utype_may_act_tgt_city_tile(struct unit_type *punit_type,
+                                 const int action_id,
+                                 const enum citytile_type prop,
+                                 const bool is_there);
+
 /* Functions to operate on various flag and roles. */
 typedef bool (*role_unit_callback)(struct unit_type *ptype, void *data);
 

Modified: trunk/server/unithand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/unithand.c?rev=29584&r1=29583&r2=29584&view=diff
==============================================================================
--- trunk/server/unithand.c     (original)
+++ trunk/server/unithand.c     Wed Aug 19 14:24:31 2015
@@ -90,6 +90,8 @@
   ANEK_FOREIGN,
   /* Explanation: not enough MP left. */
   ANEK_LOW_MP,
+  /* Explanation: can't be done to city centers. */
+  ANEK_IS_CITY_CENTER,
   /* Explanation: the action is disabled in this scenario. */
   ANEK_SCENARIO_DISABLED,
   /* Explanation not detected. */
@@ -798,6 +800,13 @@
                                                  DRO_FOREIGN,
                                                  FALSE)) {
     expl->kind = ANEK_DOMESTIC;
+  } else if (tgt_player
+             && (target_tile && tile_city(target_tile))
+             && !utype_may_act_tgt_city_tile(unit_type(punit),
+                                             action_id,
+                                             CITYT_CENTER,
+                                             TRUE)) {
+    expl->kind = ANEK_IS_CITY_CENTER;
   } else if ((game.scenario.prevent_new_cities
               && utype_can_do_action(unit_type(punit), ACTION_FOUND_CITY))
              && (action_id == ACTION_FOUND_CITY
@@ -868,6 +877,10 @@
   case ANEK_LOW_MP:
     notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
                   _("This unit has too few moves left to act."));
+    break;
+  case ANEK_IS_CITY_CENTER:
+    notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
+                  _("This unit cannot act against city centers."));
     break;
   case ANEK_SCENARIO_DISABLED:
     notify_player(pplayer, unit_tile(punit), E_BAD_COMMAND, ftc_server,
@@ -1135,6 +1148,13 @@
     notify_player(pplayer, unit_tile(actor),
                   event, ftc_server,
                   _("Your %s has too few moves left to %s."),
+                  unit_name_translation(actor),
+                  gen_action_translated_name(stopped_action));
+    break;
+  case ANEK_IS_CITY_CENTER:
+    notify_player(pplayer, unit_tile(actor),
+                  event, ftc_server,
+                  _("Your %s can't do %s to city centers."),
                   unit_name_translation(actor),
                   gen_action_translated_name(stopped_action));
     break;


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

Reply via email to