From ff43d9b57955e875e50cc6b3a05ba25bcd17fc4d Mon Sep 17 00:00:00 2001
From: Marko Lindqvist <cazfi74@gmail.com>
Date: Fri, 12 Jan 2024 07:53:10 +0200
Subject: [PATCH 35/35] Add hut frightening variants of teleport actions

See RM #174

Signed-off-by: Marko Lindqvist <cazfi74@gmail.com>
---
 common/actions.c   | 40 ++++++++++++++++++++++++++++++++++++++++
 common/actions.h   | 36 ++++++++++++++++++++----------------
 doc/README.actions | 42 ++++++++++++++++++++++++++++++++++++++++++
 server/citytools.c |  2 ++
 server/ruleset.c   |  4 ++++
 5 files changed, 108 insertions(+), 16 deletions(-)

diff --git a/common/actions.c b/common/actions.c
index 3074a9d1e7..26411d06a4 100644
--- a/common/actions.c
+++ b/common/actions.c
@@ -1513,6 +1513,18 @@ static void hard_code_actions(void)
                       TRUE, TRUE,
                       MAK_TELEPORT, 1,
                       ACTION_DISTANCE_MAX, FALSE);
+  actions[ACTION_TELEPORT_FRIGHTEN] =
+      unit_action_new(ACTION_TELEPORT_FRIGHTEN,
+                      ACTRES_TELEPORT,
+                      TRUE, TRUE,
+                      MAK_TELEPORT, 1,
+                      ACTION_DISTANCE_MAX, FALSE);
+  actions[ACTION_TELEPORT_FRIGHTEN_CONQUER] =
+      unit_action_new(ACTION_TELEPORT_FRIGHTEN_CONQUER,
+                      ACTRES_TELEPORT_CONQUER,
+                      TRUE, TRUE,
+                      MAK_TELEPORT, 1,
+                      ACTION_DISTANCE_MAX, FALSE);
   actions[ACTION_TELEPORT_ENTER] =
       unit_action_new(ACTION_TELEPORT_ENTER,
                       ACTRES_TELEPORT,
@@ -6687,6 +6699,10 @@ const char *action_ui_name_ruleset_var_name(int act)
     return "ui_name_teleport";
   case ACTION_TELEPORT_CONQUER:
     return "ui_name_teleport_conquer";
+  case ACTION_TELEPORT_FRIGHTEN:
+    return "ui_name_teleport_frighten";
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
+    return "ui_name_teleport_frighten_conquer";
   case ACTION_TELEPORT_ENTER:
     return "ui_name_teleport_enter";
   case ACTION_TELEPORT_ENTER_CONQUER:
@@ -7014,6 +7030,12 @@ const char *action_ui_name_default(int act)
   case ACTION_TELEPORT_CONQUER:
     /* TRANS: _Teleport (100% chance of success). */
     return N_("%sTeleport%s");
+  case ACTION_TELEPORT_FRIGHTEN:
+    /* TRANS: _Teleport (100% chance of success). */
+    return N_("%sTeleport%s");
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
+    /* TRANS: _Teleport (100% chance of success). */
+    return N_("%sTeleport%s");
   case ACTION_TELEPORT_ENTER:
     /* TRANS: _Teleport (100% chance of success). */
     return N_("%sTeleport%s");
@@ -7175,6 +7197,10 @@ const char *action_min_range_ruleset_var_name(int act)
     return "teleport_min_range";
   case ACTION_TELEPORT_CONQUER:
     return "teleport_conquer_min_range";
+  case ACTION_TELEPORT_FRIGHTEN:
+    return "teleport_frighten_min_range";
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
+    return "teleport_frighten_conquer_min_range";
   case ACTION_TELEPORT_ENTER:
     return "teleport_enter_min_range";
   case ACTION_TELEPORT_ENTER_CONQUER:
@@ -7338,6 +7364,10 @@ const char *action_max_range_ruleset_var_name(int act)
     return "teleport_max_range";
   case ACTION_TELEPORT_CONQUER:
     return "teleport_conquer_max_range";
+  case ACTION_TELEPORT_FRIGHTEN:
+    return "teleport_frighten_max_range";
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
+    return "teleport_frighten_conquer_max_range";
   case ACTION_TELEPORT_ENTER:
     return "teleport_enter_max_range";
   case ACTION_TELEPORT_ENTER_CONQUER:
@@ -7482,6 +7512,8 @@ const char *action_target_kind_ruleset_var_name(int act)
   case ACTION_UNIT_MOVE3:
   case ACTION_TELEPORT:
   case ACTION_TELEPORT_CONQUER:
+  case ACTION_TELEPORT_FRIGHTEN:
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
   case ACTION_TELEPORT_ENTER:
   case ACTION_TELEPORT_ENTER_CONQUER:
   case ACTION_SPY_ESCAPE:
@@ -7840,6 +7872,8 @@ const char *action_actor_consuming_always_ruleset_var_name(action_id act)
   case ACTION_UNIT_MOVE3:
   case ACTION_TELEPORT:
   case ACTION_TELEPORT_CONQUER:
+  case ACTION_TELEPORT_FRIGHTEN:
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
   case ACTION_TELEPORT_ENTER:
   case ACTION_TELEPORT_ENTER_CONQUER:
   case ACTION_SPY_ESCAPE:
@@ -7934,6 +7968,10 @@ const char *action_blocked_by_ruleset_var_name(const struct action *act)
     return "teleport_blocked_by";
   case ACTION_TELEPORT_CONQUER:
     return "teleport_conquer_blocked_by";
+  case ACTION_TELEPORT_FRIGHTEN:
+    return "teleport_frighten_blocked_by";
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
+    return "teleport_frighten_conquer_blocked_by";
   case ACTION_TELEPORT_ENTER:
     return "teleport_enter_blocked_by";
   case ACTION_TELEPORT_ENTER_CONQUER:
@@ -8183,6 +8221,8 @@ action_post_success_forced_ruleset_var_name(const struct action *act)
   case ACTION_UNIT_MOVE3:
   case ACTION_TELEPORT:
   case ACTION_TELEPORT_CONQUER:
+  case ACTION_TELEPORT_FRIGHTEN:
+  case ACTION_TELEPORT_FRIGHTEN_CONQUER:
   case ACTION_TELEPORT_ENTER:
   case ACTION_TELEPORT_ENTER_CONQUER:
   case ACTION_SPY_ESCAPE:
diff --git a/common/actions.h b/common/actions.h
index 95aef42cf7..d6d94a42e7 100644
--- a/common/actions.h
+++ b/common/actions.h
@@ -277,22 +277,26 @@ const char *gen_action_name_update_cb(const char *old_name);
 #define SPECENUM_VALUE112NAME "Teleport"
 #define SPECENUM_VALUE113 ACTION_TELEPORT_CONQUER
 #define SPECENUM_VALUE113NAME "Teleport Conquer"
-#define SPECENUM_VALUE114 ACTION_TELEPORT_ENTER
-#define SPECENUM_VALUE114NAME "Teleport Enter"
-#define SPECENUM_VALUE115 ACTION_TELEPORT_ENTER_CONQUER
-#define SPECENUM_VALUE115NAME "Teleport Enter Conquer"
-#define SPECENUM_VALUE116 ACTION_CLEAN
-#define SPECENUM_VALUE116NAME "Clean"
-#define SPECENUM_VALUE117 ACTION_COLLECT_RANSOM
-#define SPECENUM_VALUE117NAME "Collect Ransom"
-#define SPECENUM_VALUE118 ACTION_USER_ACTION1
-#define SPECENUM_VALUE118NAME "User Action 1"
-#define SPECENUM_VALUE119 ACTION_USER_ACTION2
-#define SPECENUM_VALUE119NAME "User Action 2"
-#define SPECENUM_VALUE120 ACTION_USER_ACTION3
-#define SPECENUM_VALUE120NAME "User Action 3"
-#define SPECENUM_VALUE121 ACTION_USER_ACTION4
-#define SPECENUM_VALUE121NAME "User Action 4"
+#define SPECENUM_VALUE114 ACTION_TELEPORT_FRIGHTEN
+#define SPECENUM_VALUE114NAME "Teleport Frighten"
+#define SPECENUM_VALUE115 ACTION_TELEPORT_FRIGHTEN_CONQUER
+#define SPECENUM_VALUE115NAME "Teleport Frighten Conquer"
+#define SPECENUM_VALUE116 ACTION_TELEPORT_ENTER
+#define SPECENUM_VALUE116NAME "Teleport Enter"
+#define SPECENUM_VALUE117 ACTION_TELEPORT_ENTER_CONQUER
+#define SPECENUM_VALUE117NAME "Teleport Enter Conquer"
+#define SPECENUM_VALUE118 ACTION_CLEAN
+#define SPECENUM_VALUE118NAME "Clean"
+#define SPECENUM_VALUE119 ACTION_COLLECT_RANSOM
+#define SPECENUM_VALUE119NAME "Collect Ransom"
+#define SPECENUM_VALUE120 ACTION_USER_ACTION1
+#define SPECENUM_VALUE120NAME "User Action 1"
+#define SPECENUM_VALUE121 ACTION_USER_ACTION2
+#define SPECENUM_VALUE121NAME "User Action 2"
+#define SPECENUM_VALUE122 ACTION_USER_ACTION3
+#define SPECENUM_VALUE122NAME "User Action 3"
+#define SPECENUM_VALUE123 ACTION_USER_ACTION4
+#define SPECENUM_VALUE123NAME "User Action 4"
 #define SPECENUM_BITVECTOR bv_actions
 #define SPECENUM_COUNT ACTION_COUNT
 #define SPECENUM_NAME_UPDATER
diff --git a/doc/README.actions b/doc/README.actions
index 80e3b4af7d..79d4460dcd 100644
--- a/doc/README.actions
+++ b/doc/README.actions
@@ -1468,6 +1468,48 @@ Actions done by a unit against a tile
 * the target tile can't contain any units not allied to the actor
   unit and all its cargo.
 
+"Teleport Frighten" - teleport unit to the target tile.
+* UI name can be set using ui_name_teleport_frighten
+* any action listed in teleport_blocked_by must be impossible
+* the range of legal distance between actor unit and target tile
+  must be between teleport_min_range and teleport_max_range
+* the actor unit may not be transported (!)
+* the actor unit's type must be the target tile's terrain animal if the
+  player's nation is an animal barbarian.
+* the actor unit must be able to exist outside of a transport at the target
+  tile.
+* the actor unit doesn't have the "CoastStrict" unit type flag or the
+  target tile is on or adjacent to a tile that doesn't have the
+  "UnsafeCoast" terrain flag.
+* the actor unit can't be diplomatically forbidden from entering the target
+  tile.
+* the target tile can't contain any city or units not allied to the actor
+  unit and all its cargo.
+* can result in hut frightening if
+   - the target tile has an extra with "Enter" in its rmcauses (a Hut)
+   - the target tile's Hut's rmreqs are fulfilled
+
+"Teleport Frighten Conquer" - teleport unit to the target tile and conquer it
+* UI name can be set using ui_name_teleport_frighten_conquer
+* any action listed in teleport_conquer_blocked_by must be impossible
+* the range of legal distance between actor unit and target tile
+  must be between teleport_conquer_min_range and teleport_conquer_max_range
+* the actor unit may not be transported (!)
+* the actor unit's type must be the target tile's terrain animal if the
+  player's nation is an animal barbarian.
+* the actor unit must be able to exist outside of a transport at the target
+  tile.
+* the actor unit doesn't have the "CoastStrict" unit type flag or the
+  target tile is on or adjacent to a tile that doesn't have the
+  "UnsafeCoast" terrain flag.
+* the actor unit can't be diplomatically forbidden from entering the target
+  tile.
+* the target tile can't contain any units not allied to the actor
+  unit and all its cargo.
+* can result in hut frightening if
+   - the target tile has an extra with "Enter" in its rmcauses (a Hut)
+   - the target tile's Hut's rmreqs are fulfilled
+
 "Teleport Enter" - teleport unit to the target tile.
 * UI name can be set using ui_name_teleport
 * any action listed in teleport_blocked_by must be impossible
diff --git a/server/citytools.c b/server/citytools.c
index 1faa0cf093..19602572e9 100644
--- a/server/citytools.c
+++ b/server/citytools.c
@@ -1990,6 +1990,8 @@ bool unit_conquer_city(struct unit *punit, struct city *pcity)
                                                ACTION_PARADROP_FRIGHTEN_CONQUER)
                         || utype_can_do_action(unit_type_get(punit),
                                                ACTION_PARADROP_ENTER_CONQUER)
+                        || utype_can_do_action(unit_type_get(punit),
+                                               ACTION_TELEPORT_FRIGHTEN_CONQUER)
                         || utype_can_do_action(unit_type_get(punit),
                                                ACTION_TELEPORT_ENTER_CONQUER),
                         FALSE, "Bad unit for city occupation.");
diff --git a/server/ruleset.c b/server/ruleset.c
index b6868fddc0..d177140ffc 100644
--- a/server/ruleset.c
+++ b/server/ruleset.c
@@ -7903,6 +7903,10 @@ static bool load_ruleset_actions(struct section_file *file,
              ACT_SUB_RES_HUT_FRIGHTEN);
       BV_SET(action_by_number(ACTION_PARADROP_FRIGHTEN_CONQUER)->sub_results,
              ACT_SUB_RES_HUT_FRIGHTEN);
+      BV_SET(action_by_number(ACTION_TELEPORT_FRIGHTEN)->sub_results,
+             ACT_SUB_RES_HUT_FRIGHTEN);
+      BV_SET(action_by_number(ACTION_TELEPORT_FRIGHTEN_CONQUER)->sub_results,
+             ACT_SUB_RES_HUT_FRIGHTEN);
 
       /* Unit May Embark */
       action_iterate(act_id) {
-- 
2.43.0

