Author: sveinung
Date: Fri May  5 12:30:07 2017
New Revision: 35404

URL: http://svn.gna.org/viewcvs/freeciv?rev=35404&view=rev
Log:
Add action property actor_consuming_always.

Introduce the new action property actor_consuming_always. It is true if
successfully performing the action always consumes the actor. Have it
replace the spends_unit parameter of diplomat_embassy() and
diplomat_investigate().

See hrm Feature #657303

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

Modified: trunk/common/actions.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.c?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/common/actions.c      (original)
+++ trunk/common/actions.c      Fri May  5 12:30:07 2017
@@ -86,7 +86,8 @@
                                  bool rare_pop_up,
                                  bool unitwaittime_controlled,
                                  const int min_distance,
-                                 const int max_distance);
+                                 const int max_distance,
+                                 bool actor_consuming_always);
 
 static bool is_enabler_active(const struct action_enabler *enabler,
                              const struct player *actor_player,
@@ -324,74 +325,75 @@
 {
   actions[ACTION_SPY_POISON] = action_new(ACTION_SPY_POISON, ATK_CITY,
                                           TRUE, FALSE, FALSE, TRUE,
-                                          0, 1);
+                                          0, 1, FALSE);
   actions[ACTION_SPY_SABOTAGE_UNIT] =
       action_new(ACTION_SPY_SABOTAGE_UNIT, ATK_UNIT,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_SPY_BRIBE_UNIT] =
       action_new(ACTION_SPY_BRIBE_UNIT, ATK_UNIT,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_SPY_SABOTAGE_CITY] =
       action_new(ACTION_SPY_SABOTAGE_CITY, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_SPY_TARGETED_SABOTAGE_CITY] =
       action_new(ACTION_SPY_TARGETED_SABOTAGE_CITY, ATK_CITY,
                  TRUE, TRUE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_SPY_INCITE_CITY] =
       action_new(ACTION_SPY_INCITE_CITY, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_ESTABLISH_EMBASSY] =
       action_new(ACTION_ESTABLISH_EMBASSY, ATK_CITY,
                  FALSE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_ESTABLISH_EMBASSY_STAY] =
       action_new(ACTION_ESTABLISH_EMBASSY_STAY, ATK_CITY,
                  FALSE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_SPY_STEAL_TECH] =
       action_new(ACTION_SPY_STEAL_TECH, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_SPY_TARGETED_STEAL_TECH] =
       action_new(ACTION_SPY_TARGETED_STEAL_TECH, ATK_CITY,
                  TRUE, TRUE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_SPY_INVESTIGATE_CITY] =
       action_new(ACTION_SPY_INVESTIGATE_CITY, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_INV_CITY_SPEND] =
       action_new(ACTION_INV_CITY_SPEND, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_SPY_STEAL_GOLD] =
       action_new(ACTION_SPY_STEAL_GOLD, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_TRADE_ROUTE] =
       action_new(ACTION_TRADE_ROUTE, ATK_CITY,
                  FALSE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_MARKETPLACE] =
       action_new(ACTION_MARKETPLACE, ATK_CITY,
                  FALSE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_HELP_WONDER] =
       action_new(ACTION_HELP_WONDER, ATK_CITY,
                  FALSE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_CAPTURE_UNITS] =
       action_new(ACTION_CAPTURE_UNITS, ATK_UNITS,
                  TRUE, FALSE, FALSE, TRUE,
                  /* A single domestic unit at the target tile will make the
                   * action illegal. It must therefore be performed from
                   * another tile. */
-                 1, 1);
+                 1, 1,
+                 FALSE);
   actions[ACTION_FOUND_CITY] =
       action_new(ACTION_FOUND_CITY, ATK_TILE,
                  FALSE, FALSE, TRUE, TRUE,
@@ -399,15 +401,16 @@
                   * Reason: The Freeciv code assumes that the city founding
                   * unit is located at the tile were the new city is
                   * founded. */
-                 0, 0);
+                 0, 0,
+                 TRUE);
   actions[ACTION_JOIN_CITY] =
       action_new(ACTION_JOIN_CITY, ATK_CITY,
                  FALSE, FALSE, TRUE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_STEAL_MAPS] =
       action_new(ACTION_STEAL_MAPS, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_BOMBARD] =
       action_new(ACTION_BOMBARD,
                  /* FIXME: Target is actually Units + City */
@@ -418,58 +421,63 @@
                   * another tile. */
                  1,
                  /* Overwritten by the ruleset's bombard_max_range */
-                 1);
+                 1,
+                 FALSE);
   actions[ACTION_SPY_NUKE] =
       action_new(ACTION_SPY_NUKE, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_NUKE] =
       action_new(ACTION_NUKE,
                  /* FIXME: Target is actually Tile + Units + City */
                  ATK_TILE,
                  TRUE, FALSE, TRUE, TRUE,
-                 0, 1);
+                 0, 1, TRUE);
   actions[ACTION_DESTROY_CITY] =
       action_new(ACTION_DESTROY_CITY, ATK_CITY,
                  TRUE, FALSE, TRUE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_EXPEL_UNIT] =
       action_new(ACTION_EXPEL_UNIT, ATK_UNIT,
                  TRUE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
   actions[ACTION_RECYCLE_UNIT] =
       action_new(ACTION_RECYCLE_UNIT, ATK_CITY,
                  FALSE, FALSE, TRUE, TRUE,
                  /* Illegal to perform to a target on another tile to
                   * keep the rules exactly as they were for now. */
-                 0, 1);
+                 0, 1,
+                 TRUE);
   actions[ACTION_DISBAND_UNIT] =
       action_new(ACTION_DISBAND_UNIT, ATK_SELF,
                  FALSE, FALSE, TRUE, TRUE,
-                 0, 0);
+                 0, 0, TRUE);
   actions[ACTION_HOME_CITY] =
       action_new(ACTION_HOME_CITY, ATK_CITY,
                  FALSE, FALSE, TRUE, FALSE,
                  /* Illegal to perform to a target on another tile to
                   * keep the rules exactly as they were for now. */
-                 0, 0);
+                 0, 0, FALSE);
   actions[ACTION_UPGRADE_UNIT] =
       action_new(ACTION_UPGRADE_UNIT, ATK_CITY,
                  FALSE, FALSE, TRUE, TRUE,
                  /* Illegal to perform to a target on another tile to
                   * keep the rules exactly as they were for now. */
-                 0, 0);
+                 0, 0,
+                 FALSE);
   actions[ACTION_PARADROP] =
       action_new(ACTION_PARADROP, ATK_TILE,
                  FALSE, FALSE, TRUE, TRUE,
                  1,
                  /* Still limited by each unit type's paratroopers_range
                   * field. */
-                 ACTION_DISTANCE_MAX);
+                 ACTION_DISTANCE_MAX,
+                 FALSE);
   actions[ACTION_AIRLIFT] =
       action_new(ACTION_AIRLIFT, ATK_CITY,
                  FALSE, FALSE, TRUE, TRUE,
-                 1, ACTION_DISTANCE_UNLIMITED);
+                 1, ACTION_DISTANCE_UNLIMITED,
+                 FALSE);
   actions[ACTION_ATTACK] =
       action_new(ACTION_ATTACK,
                  /* FIXME: Target is actually City and, depending on the
@@ -477,15 +485,15 @@
                   * tile (Units) or any unit at the target tile. */
                  ATK_TILE,
                  TRUE, FALSE, FALSE, TRUE,
-                 1, 1);
+                 1, 1, FALSE);
   actions[ACTION_CONQUER_CITY] =
       action_new(ACTION_CONQUER_CITY, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
-                 1, 1);
+                 1, 1, FALSE);
   actions[ACTION_HEAL_UNIT] =
       action_new(ACTION_HEAL_UNIT, ATK_UNIT,
                  FALSE, FALSE, FALSE, TRUE,
-                 0, 1);
+                 0, 1, FALSE);
 }
 
 /**************************************************************************
@@ -614,7 +622,8 @@
                                  bool rare_pop_up,
                                  bool unitwaittime_controlled,
                                  const int min_distance,
-                                 const int max_distance)
+                                 const int max_distance,
+                                 bool actor_consuming_always)
 {
   struct action *action;
 
@@ -636,6 +645,8 @@
   action->max_distance = max_distance;
 
   action->unitwaittime_controlled = unitwaittime_controlled;
+
+  action->actor_consuming_always = actor_consuming_always;
 
   /* Loaded from the ruleset. Until generalized actions are ready it has to
    * be defined seperatly from other action data. */

Modified: trunk/common/actions.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.h?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/common/actions.h      (original)
+++ trunk/common/actions.h      Fri May  5 12:30:07 2017
@@ -201,6 +201,12 @@
   /* Actions that blocks this action. The action will be illegal if any
    * bloking action is legal. */
   bv_actions blocked_by;
+
+  /* Successfully performing this action will always consume the actor.
+   * Don't set this for actions that consumes the unit in some cases
+   * (depending on luck, the presence of a flag, etc) but not in other
+   * cases. */
+  bool actor_consuming_always;
 };
 
 struct action_enabler

Modified: trunk/common/unittype.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.c?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/common/unittype.c     (original)
+++ trunk/common/unittype.c     Fri May  5 12:30:07 2017
@@ -841,6 +841,17 @@
   } action_enabler_list_iterate_end;
 
   return FALSE;
+}
+
+/**************************************************************************
+  Returns TRUE iff performing the specified action will consume an actor
+  unit of the specified type.
+**************************************************************************/
+bool utype_is_consumed_by_action(const struct action *paction,
+                                 const struct unit_type *utype)
+{
+  /* Only care about the action it self for now. */
+  return paction->actor_consuming_always;
 }
 
 /****************************************************************************

Modified: trunk/common/unittype.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/unittype.h?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/common/unittype.h     (original)
+++ trunk/common/unittype.h     Fri May  5 12:30:07 2017
@@ -634,6 +634,9 @@
                                  const enum citytile_type prop,
                                  const bool is_there);
 
+bool utype_is_consumed_by_action(const struct action *paction,
+                                 const struct unit_type *utype);
+
 /* Functions to operate on various flag and roles. */
 typedef bool (*role_unit_callback)(struct unit_type *ptype, void *data);
 

Modified: trunk/server/diplomats.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/diplomats.c?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/server/diplomats.c    (original)
+++ trunk/server/diplomats.c    Fri May  5 12:30:07 2017
@@ -165,16 +165,15 @@
 
   - It costs some minimal movement to investigate a city.
 
-  - If spends_unit is TRUE the actor unit dies after investigation.
-  - If it isn't the actor unit always survive.  There is no risk.
+  - The actor unit always survives the investigation unless the action
+    being performed is configured to always consume the actor unit.
 
   Returns TRUE iff action could be done, FALSE if it couldn't. Even if
   this returns TRUE, unit may have died during the action.
 ****************************************************************************/
 bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
                           struct city *pcity,
-                          const enum gen_action action_id,
-                          bool spends_unit)
+                          const struct action *paction)
 {
   struct player *cplayer;
   struct packet_unit_short_info unit_packet;
@@ -241,12 +240,12 @@
   }
 
   /* this may cause a diplomatic incident */
-  action_id_consequence_success(action_id, pplayer, cplayer,
-                                city_tile(pcity), city_link(pcity));
-
-  /* The actor unit always survive when spends_unit is FALSE, it never does
-   * when it is TRUE. */
-  if (spends_unit) {
+  action_consequence_success(paction, pplayer, cplayer,
+                             city_tile(pcity), city_link(pcity));
+
+  /* The actor unit always survive unless the action it self has determined
+   * to always consume it. */
+  if (utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
     wipe_unit(pdiplomat, ULR_USED, NULL);
   } else {
     send_unit_info(NULL, pdiplomat);
@@ -289,15 +288,14 @@
   - Otherwise, the embassy is created.
   - It costs some minimal movement to establish an embassy.
 
-  - If spends_unit is TRUE the actor unit is consumed in creation of
-    embassy. If it isn't the actor unit always survive.
+  - The actor unit always survives the investigation unless the action
+    being performed is configured to always consume the actor unit.
 
   Returns TRUE iff action could be done, FALSE if it couldn't. Even if
   this returns TRUE, unit may have died during the action.
 ****************************************************************************/
 bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
-                      struct city *pcity, const enum gen_action action_id,
-                      bool spends_unit)
+                      struct city *pcity, const struct action *paction)
 {
   struct player *cplayer;
 
@@ -340,12 +338,12 @@
   }
 
   /* this may cause a diplomatic incident */
-  action_id_consequence_success(action_id, pplayer, cplayer,
-                                city_tile(pcity), city_link(pcity));
-
-  /* The actor unit always survive when spends_unit is FALSE, it never does
-   * when it is TRUE. */
-  if (spends_unit) {
+  action_consequence_success(paction, pplayer, cplayer,
+                             city_tile(pcity), city_link(pcity));
+
+  /* The actor unit always survive unless the action it self has determined
+   * to always consume it. */
+  if (utype_is_consumed_by_action(paction, unit_type_get(pdiplomat))) {
     wipe_unit(pdiplomat, ULR_USED, NULL);
   } else {
     send_unit_info(NULL, pdiplomat);

Modified: trunk/server/diplomats.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/diplomats.h?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/server/diplomats.h    (original)
+++ trunk/server/diplomats.h    Fri May  5 12:30:07 2017
@@ -16,12 +16,10 @@
 #include "fc_types.h"
 
 bool diplomat_embassy(struct player *pplayer, struct unit *pdiplomat,
-                      struct city *pcity, const enum gen_action action_id,
-                      bool spends_unit);
+                      struct city *pcity, const struct action *paction);
 bool diplomat_investigate(struct player *pplayer, struct unit *pdiplomat,
                           struct city *pcity,
-                          const enum gen_action action_id,
-                          bool spends_unit);
+                          const struct action *paction);
 void spy_send_sabotage_list(struct connection *pc, struct unit *pdiplomat,
                             struct city *pcity,
                             const enum gen_action action_id);

Modified: trunk/server/unithand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/unithand.c?rev=35404&r1=35403&r2=35404&view=diff
==============================================================================
--- trunk/server/unithand.c     (original)
+++ trunk/server/unithand.c     Fri May  5 12:30:07 2017
@@ -2363,28 +2363,19 @@
                                         action_type));
     break;
   case ACTION_SPY_INVESTIGATE_CITY:
+  case ACTION_INV_CITY_SPEND:
+    /* Difference is caused by data in the action structure. */
     ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity,
                              diplomat_investigate(pplayer,
                                                   actor_unit, pcity,
-                                                  action_type,
-                                                  FALSE));
-    break;
-  case ACTION_INV_CITY_SPEND:
-    ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity,
-                             diplomat_investigate(pplayer,
-                                                  actor_unit, pcity,
-                                                  action_type,
-                                                  TRUE));
+                                                  paction));
     break;
   case ACTION_ESTABLISH_EMBASSY:
+  case ACTION_ESTABLISH_EMBASSY_STAY:
+    /* Difference is caused by data in the action structure. */
     ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity,
                              diplomat_embassy(pplayer, actor_unit, pcity,
-                                              action_type, FALSE));
-    break;
-  case ACTION_ESTABLISH_EMBASSY_STAY:
-    ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity,
-                             diplomat_embassy(pplayer, actor_unit, pcity,
-                                              action_type, TRUE));
+                                              paction));
     break;
   case ACTION_SPY_INCITE_CITY:
     ACTION_STARTED_UNIT_CITY(action_type, actor_unit, pcity,


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

Reply via email to