Author: sveinung
Date: Thu Oct  6 14:03:55 2016
New Revision: 34018

URL: http://svn.gna.org/viewcvs/freeciv?rev=34018&view=rev
Log:
Add the new unit action "Heal Unit".

This allows medic units etc. A healing restores 25% of the target's hit
points are restored each healing. Healing spends all the actor's movement
points.

See patch #7774

Modified:
    trunk/ai/default/aicity.c
    trunk/client/gui-gtk-2.0/action_dialog.c
    trunk/client/gui-gtk-3.0/action_dialog.c
    trunk/client/gui-gtk-3.22/action_dialog.c
    trunk/client/gui-qt/dialogs.cpp
    trunk/client/gui-sdl2/action_dialog.c
    trunk/client/packhand.c
    trunk/common/actions.c
    trunk/common/actions.h
    trunk/doc/README.actions
    trunk/fc_version
    trunk/server/advisors/advdata.c
    trunk/server/ruleset.c
    trunk/server/unithand.c
    trunk/tools/ruleutil/rulesave.c

Modified: trunk/ai/default/aicity.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/ai/default/aicity.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/ai/default/aicity.c   (original)
+++ trunk/ai/default/aicity.c   Thu Oct  6 14:03:55 2016
@@ -1224,6 +1224,7 @@
   case ACTION_NUKE:
   case ACTION_PARADROP:
   case ACTION_ATTACK:
+  case ACTION_HEAL_UNIT:
   case ACTION_COUNT:
     fc_assert_msg(action_id_get_target_kind(action_id) == ATK_CITY,
                   "Action not aimed at cities");

Modified: trunk/client/gui-gtk-2.0/action_dialog.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-gtk-2.0/action_dialog.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/client/gui-gtk-2.0/action_dialog.c    (original)
+++ trunk/client/gui-gtk-2.0/action_dialog.c    Thu Oct  6 14:03:55 2016
@@ -488,6 +488,20 @@
   struct action_data *args = (struct action_data *)data;
 
   request_do_action(ACTION_SPY_SABOTAGE_UNIT, args->actor_unit_id,
+                    args->target_unit_id, 0, "");
+
+  gtk_widget_destroy(act_sel_dialog);
+  free(args);
+}
+
+/*****************************************************************
+  User selected "Heal Unit" from choice dialog
+*****************************************************************/
+static void heal_unit_callback(GtkWidget *w, gpointer data)
+{
+  struct action_data *args = (struct action_data *)data;
+
+  request_do_action(ACTION_HEAL_UNIT, args->actor_unit_id,
                     args->target_unit_id, 0, "");
 
   gtk_widget_destroy(act_sel_dialog);
@@ -1278,6 +1292,7 @@
   /* Unit acting against a unit target. */
   [ACTION_SPY_BRIBE_UNIT] = (GCallback)diplomat_bribe_callback,
   [ACTION_SPY_SABOTAGE_UNIT] = (GCallback)spy_sabotage_unit_callback,
+  [ACTION_HEAL_UNIT] = (GCallback)heal_unit_callback,
 
   /* Unit acting against all units at a tile. */
   [ACTION_CAPTURE_UNITS] = (GCallback)capture_units_callback,

Modified: trunk/client/gui-gtk-3.0/action_dialog.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-gtk-3.0/action_dialog.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/client/gui-gtk-3.0/action_dialog.c    (original)
+++ trunk/client/gui-gtk-3.0/action_dialog.c    Thu Oct  6 14:03:55 2016
@@ -498,6 +498,20 @@
   struct action_data *args = (struct action_data *)data;
 
   request_do_action(ACTION_SPY_SABOTAGE_UNIT, args->actor_unit_id,
+                    args->target_unit_id, 0, "");
+
+  gtk_widget_destroy(act_sel_dialog);
+  free(args);
+}
+
+/*****************************************************************
+  User selected "Heal Unit" from choice dialog
+*****************************************************************/
+static void heal_unit_callback(GtkWidget *w, gpointer data)
+{
+  struct action_data *args = (struct action_data *)data;
+
+  request_do_action(ACTION_HEAL_UNIT, args->actor_unit_id,
                     args->target_unit_id, 0, "");
 
   gtk_widget_destroy(act_sel_dialog);
@@ -1372,6 +1386,7 @@
   /* Unit acting against a unit target. */
   [ACTION_SPY_BRIBE_UNIT] = (GCallback)diplomat_bribe_callback,
   [ACTION_SPY_SABOTAGE_UNIT] = (GCallback)spy_sabotage_unit_callback,
+  [ACTION_HEAL_UNIT] = (GCallback)heal_unit_callback,
 
   /* Unit acting against all units at a tile. */
   [ACTION_CAPTURE_UNITS] = (GCallback)capture_units_callback,

Modified: trunk/client/gui-gtk-3.22/action_dialog.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-gtk-3.22/action_dialog.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/client/gui-gtk-3.22/action_dialog.c   (original)
+++ trunk/client/gui-gtk-3.22/action_dialog.c   Thu Oct  6 14:03:55 2016
@@ -498,6 +498,20 @@
   struct action_data *args = (struct action_data *)data;
 
   request_do_action(ACTION_SPY_SABOTAGE_UNIT, args->actor_unit_id,
+                    args->target_unit_id, 0, "");
+
+  gtk_widget_destroy(act_sel_dialog);
+  free(args);
+}
+
+/*****************************************************************
+  User selected "Heal Unit" from choice dialog
+*****************************************************************/
+static void heal_unit_callback(GtkWidget *w, gpointer data)
+{
+  struct action_data *args = (struct action_data *)data;
+
+  request_do_action(ACTION_HEAL_UNIT, args->actor_unit_id,
                     args->target_unit_id, 0, "");
 
   gtk_widget_destroy(act_sel_dialog);
@@ -1366,6 +1380,7 @@
   /* Unit acting against a unit target. */
   [ACTION_SPY_BRIBE_UNIT] = (GCallback)diplomat_bribe_callback,
   [ACTION_SPY_SABOTAGE_UNIT] = (GCallback)spy_sabotage_unit_callback,
+  [ACTION_HEAL_UNIT] = (GCallback)heal_unit_callback,
 
   /* Unit acting against all units at a tile. */
   [ACTION_CAPTURE_UNITS] = (GCallback)capture_units_callback,

Modified: trunk/client/gui-qt/dialogs.cpp
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-qt/dialogs.cpp?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/client/gui-qt/dialogs.cpp     (original)
+++ trunk/client/gui-qt/dialogs.cpp     Thu Oct  6 14:03:55 2016
@@ -95,6 +95,7 @@
 static void unit_home_city(QVariant data1, QVariant data2);
 static void airlift(QVariant data1, QVariant data2);
 static void conquer_city(QVariant data1, QVariant data2);
+static void heal_unit(QVariant data1, QVariant data2);
 static void keep_moving(QVariant data1, QVariant data2);
 static void pillage_something(QVariant data1, QVariant data2);
 static void action_entry(choice_dialog *cd,
@@ -151,6 +152,7 @@
   /* Unit acting against a unit target. */
   action_function[ACTION_SPY_BRIBE_UNIT] = diplomat_bribe;
   action_function[ACTION_SPY_SABOTAGE_UNIT] = spy_sabotage_unit;
+  action_function[ACTION_HEAL_UNIT] = heal_unit;
 
   /* Unit acting against all units at a tile. */
   action_function[ACTION_CAPTURE_UNITS] = capture_units;
@@ -1742,6 +1744,17 @@
                     diplomat_target_id, 0, "");
 }
 
+/***************************************************************************
+  Action "Heal Unit" for choice dialog
+***************************************************************************/
+static void heal_unit(QVariant data1, QVariant data2)
+{
+  int actor_id = data1.toInt();
+  int target_id = data2.toInt();
+
+  request_do_action(ACTION_HEAL_UNIT, actor_id, target_id, 0, "");
+}
+
 /**************************************************************************
   Action capture units for choice dialog
 **************************************************************************/

Modified: trunk/client/gui-sdl2/action_dialog.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/gui-sdl2/action_dialog.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/client/gui-sdl2/action_dialog.c       (original)
+++ trunk/client/gui-sdl2/action_dialog.c       Thu Oct  6 14:03:55 2016
@@ -830,6 +830,23 @@
     popdown_diplomat_dialog();
     request_do_action(ACTION_SPY_SABOTAGE_UNIT,
                       diplomat_id, target_id, 0, "");
+  }
+
+  return -1;
+}
+
+/****************************************************************
+  User clicked "Heal Unit"
+*****************************************************************/
+static int heal_unit_callback(struct widget *pWidget)
+{
+  if (Main.event.button.button == SDL_BUTTON_LEFT) {
+    int actor_id = MAX_ID - pWidget->ID;
+    int target_id = pWidget->data.unit->id;
+
+    popdown_diplomat_dialog();
+    request_do_action(ACTION_HEAL_UNIT,
+                      actor_id, target_id, 0, "");
   }
 
   return -1;
@@ -1113,6 +1130,7 @@
   /* Unit acting against a unit target. */
   [ACTION_SPY_BRIBE_UNIT] = diplomat_bribe_callback,
   [ACTION_SPY_SABOTAGE_UNIT] = spy_sabotage_unit_callback,
+  [ACTION_HEAL_UNIT] = heal_unit_callback,
   [ACTION_EXPEL_UNIT] = expel_unit_callback,
 
   /* Unit acting against all units at a tile. */

Modified: trunk/client/packhand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/client/packhand.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/client/packhand.c     (original)
+++ trunk/client/packhand.c     Thu Oct  6 14:03:55 2016
@@ -4520,6 +4520,7 @@
       case ACTION_UPGRADE_UNIT:
       case ACTION_PARADROP:
       case ACTION_AIRLIFT:
+      case ACTION_HEAL_UNIT:
         /* An intersting non attack action has been found. */
         return ACTION_COUNT;
         break;

Modified: trunk/common/actions.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/common/actions.c      (original)
+++ trunk/common/actions.c      Thu Oct  6 14:03:55 2016
@@ -252,6 +252,10 @@
       action_new(ACTION_CONQUER_CITY, ATK_CITY,
                  TRUE, FALSE, FALSE, TRUE,
                  1, 1);
+  actions[ACTION_HEAL_UNIT] =
+      action_new(ACTION_HEAL_UNIT, ATK_UNIT,
+                 FALSE, FALSE, FALSE, TRUE,
+                 0, 1);
 
   /* Initialize the action enabler list */
   action_iterate(act) {
@@ -1107,6 +1111,7 @@
   case ACTION_PARADROP:
   case ACTION_AIRLIFT:
   case ACTION_CONQUER_CITY:
+  case ACTION_HEAL_UNIT:
     /* No hard unit type requirements. */
     break;
 
@@ -1244,6 +1249,7 @@
   case ACTION_HOME_CITY:
   case ACTION_UPGRADE_UNIT:
   case ACTION_ATTACK:
+  case ACTION_HEAL_UNIT:
     /* No hard unit type requirements. */
     break;
 
@@ -1707,6 +1713,14 @@
 
     break;
 
+  case ACTION_HEAL_UNIT:
+    /* Reason: It is not the healthy who need a doctor, but the sick. */
+    /* Info leak: the actor can see the target's HP. */
+    if (!(target_unit->hp < target_unittype->hp)) {
+      return TRI_NO;
+    }
+    break;
+
   case ACTION_SPY_INVESTIGATE_CITY:
   case ACTION_SPY_POISON:
   case ACTION_SPY_SABOTAGE_CITY:
@@ -2553,6 +2567,10 @@
     /* No battle is fought first. */
     chance = ACTPROB_CERTAIN;
     break;
+  case ACTION_HEAL_UNIT:
+    /* No battle is fought first. */
+    chance = ACTPROB_CERTAIN;
+    break;
   case ACTION_COUNT:
     fc_assert(FALSE);
     break;

Modified: trunk/common/actions.h
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/common/actions.h?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/common/actions.h      (original)
+++ trunk/common/actions.h      Thu Oct  6 14:03:55 2016
@@ -109,6 +109,8 @@
 #define SPECENUM_VALUE29NAME "Attack"
 #define SPECENUM_VALUE30 ACTION_CONQUER_CITY
 #define SPECENUM_VALUE30NAME "Conquer City"
+#define SPECENUM_VALUE31 ACTION_HEAL_UNIT
+#define SPECENUM_VALUE31NAME "Heal Unit"
 #define SPECENUM_BITVECTOR bv_actions
 /* Limited by what values num2char() can store in unit orders in
  * savegames. */

Modified: trunk/doc/README.actions
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/doc/README.actions?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/doc/README.actions    (original)
+++ trunk/doc/README.actions    Thu Oct  6 14:03:55 2016
@@ -327,6 +327,12 @@
  * target must be visible for the actor.
  * target's owner must have a capital
 
+"Heal Unit" - Restore the target unit's health.
+ * UI name can be set using ui_name_heal_unit
+ * spends all actor movement
+ * actor must be on the same tile as the target or on the tile next to it.
+ * target must be visible for the actor.
+
 Actions done by a unit against all units at a tile
 ==================================================
 "Capture Units" - steal the target units.

Modified: trunk/fc_version
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/fc_version?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/fc_version    (original)
+++ trunk/fc_version    Thu Oct  6 14:03:55 2016
@@ -56,7 +56,7 @@
 #   - Avoid adding a new mandatory capability to the development branch for
 #     as long as possible.  We want to maintain network compatibility with
 #     the stable branch for as long as possible.
-NETWORK_CAPSTRING_MANDATORY="+Freeciv.Devel-3.0-2016.Oct.05c"
+NETWORK_CAPSTRING_MANDATORY="+Freeciv.Devel-3.0-2016.Oct.06"
 NETWORK_CAPSTRING_OPTIONAL=""
 
 FREECIV_DISTRIBUTOR=""

Modified: trunk/server/advisors/advdata.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/advisors/advdata.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/server/advisors/advdata.c     (original)
+++ trunk/server/advisors/advdata.c     Thu Oct  6 14:03:55 2016
@@ -884,6 +884,7 @@
           case ACTION_HOME_CITY:
           case ACTION_UPGRADE_UNIT:
           case ACTION_AIRLIFT:
+          case ACTION_HEAL_UNIT:
             /* Could be good. An embassy gives permanent contact. A trade
              * route gives gold per turn. Join city gives population. Help
              * wonder gives shields. */

Modified: trunk/server/ruleset.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/ruleset.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/server/ruleset.c      (original)
+++ trunk/server/ruleset.c      Thu Oct  6 14:03:55 2016
@@ -6123,6 +6123,13 @@
           N_("%sConquer City%s"),
           "actions.ui_name_conquer_city");
       sz_strlcpy(action_by_number(ACTION_CONQUER_CITY)->ui_name,
+                 text);
+
+      text = secfile_lookup_str_default(file,
+          /* TRANS: Heal _Unit (3% chance of success). */
+          N_("Heal %sUnit%s"),
+          "actions.ui_name_heal_unit");
+      sz_strlcpy(action_by_number(ACTION_HEAL_UNIT)->ui_name,
                  text);
 
       /* The quiet (don't auto generate help for) property of all actions

Modified: trunk/server/unithand.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/server/unithand.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/server/unithand.c     (original)
+++ trunk/server/unithand.c     Thu Oct  6 14:03:55 2016
@@ -440,6 +440,59 @@
                              target_tile, target_link);
 
   /* Mission accomplished. */
+  return TRUE;
+}
+
+/**************************************************************************
+  Restore some of the target unit's hit points.
+
+  Returns TRUE iff action could be done, FALSE if it couldn't. Even if
+  this returns TRUE, unit may have died during the action.
+**************************************************************************/
+static bool do_heal_unit(struct player *act_player,
+                         struct unit *act_unit,
+                         struct unit *tgt_unit)
+{
+  int healing_limit;
+  int tgt_hp_max;
+  struct player *tgt_player;
+  struct tile *tgt_tile;
+
+  /* Sanity checks: got all the needed input. */
+  fc_assert_ret_val(act_player, FALSE);
+  fc_assert_ret_val(act_unit, FALSE);
+  fc_assert_ret_val(tgt_unit, FALSE);
+
+  /* The target unit can't have more HP than this. */
+  tgt_hp_max = unit_type_get(tgt_unit)->hp;
+
+  /* Sanity check: target isn't at full health and can therefore can be
+   * healed. */
+  fc_assert_ret_val(tgt_unit->hp < tgt_hp_max, FALSE);
+
+  /* Fetch the target unit's owner. */
+  tgt_player = unit_owner(tgt_unit);
+  fc_assert_ret_val(tgt_player, FALSE);
+
+  /* Fetch the target unit's tile. */
+  tgt_tile = unit_tile(tgt_unit);
+  fc_assert_ret_val(tgt_tile, FALSE);
+
+  /* The max amount of HP that can be added. */
+  healing_limit = tgt_hp_max / 4;
+
+  /* Heal the target unit. */
+  tgt_unit->hp = MIN(tgt_unit->hp + healing_limit, tgt_hp_max);
+  send_unit_info(NULL, tgt_unit);
+
+  /* Healing a unit spends the actor's movement. */
+  act_unit->moves_left = 0;
+  send_unit_info(NULL, act_unit);
+
+  /* This may have diplomatic consequences. */
+  action_consequence_success(ACTION_HEAL_UNIT, act_player, tgt_player,
+                             tgt_tile, unit_link(tgt_unit));
+
   return TRUE;
 }
 
@@ -533,6 +586,7 @@
   case ACTION_UPGRADE_UNIT:
   case ACTION_PARADROP:
   case ACTION_AIRLIFT:
+  case ACTION_HEAL_UNIT:
     /* No special help. */
     break;
   case ACTION_COUNT:
@@ -2140,6 +2194,20 @@
       }
     }
     break;
+  case ACTION_HEAL_UNIT:
+    if (punit) {
+      if (is_action_enabled_unit_on_unit(action_type,
+                                         actor_unit, punit)) {
+        ACTION_STARTED_UNIT_UNIT(action_type, actor_unit, punit);
+
+        return do_heal_unit(pplayer, actor_unit, punit);
+      } else {
+        illegal_action(pplayer, actor_unit, action_type,
+                       unit_owner(punit), NULL, NULL, punit,
+                       requester);
+      }
+    }
+    break;
   case ACTION_DISBAND_UNIT:
     if (actor_unit) {
       if (is_action_enabled_unit_on_self(action_type,
@@ -4741,6 +4809,7 @@
       case ACTION_CONQUER_CITY:
       case ACTION_PARADROP:
       case ACTION_AIRLIFT:
+      case ACTION_HEAL_UNIT:
         /* No validation required. */
         break;
       /* Invalid action. Should have been caught above. */

Modified: trunk/tools/ruleutil/rulesave.c
URL: 
http://svn.gna.org/viewcvs/freeciv/trunk/tools/ruleutil/rulesave.c?rev=34018&r1=34017&r2=34018&view=diff
==============================================================================
--- trunk/tools/ruleutil/rulesave.c     (original)
+++ trunk/tools/ruleutil/rulesave.c     Thu Oct  6 14:03:55 2016
@@ -1054,6 +1054,9 @@
   secfile_insert_str(sfile,
                      action_by_number(ACTION_CONQUER_CITY)->ui_name,
                      "actions.ui_name_conquer_city");
+  secfile_insert_str(sfile,
+                     action_by_number(ACTION_HEAL_UNIT)->ui_name,
+                     "actions.ui_name_heal_unit");
 
   i = 0;
   action_iterate(act) {


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

Reply via email to