From 203ee9c9f611c69b308b9bfbd4a330a8827bf206 Mon Sep 17 00:00:00 2001 From: Marko Lindqvist Date: Thu, 28 Sep 2023 09:40:32 +0300 Subject: [PATCH 44/44] Add "Teleport Conquer" action type See osdn #48665 Signed-off-by: Marko Lindqvist --- ai/default/daicity.c | 1 + ai/default/daidiplomacy.c | 1 + common/actions.c | 35 +++++++++++++++++++++++++++++++---- common/actions.h | 27 ++++++++++++++------------- common/actres.c | 11 +++++++---- common/fc_types.h | 3 ++- doc/README.actions | 18 ++++++++++++++++++ server/advisors/advdata.c | 1 + server/unithand.c | 8 ++++++-- 9 files changed, 81 insertions(+), 24 deletions(-) diff --git a/ai/default/daicity.c b/ai/default/daicity.c index fc77944563..7bacb04e79 100644 --- a/ai/default/daicity.c +++ b/ai/default/daicity.c @@ -1309,6 +1309,7 @@ static int action_target_neg_util(action_id act_id, case ACTRES_HUT_FRIGHTEN: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_HOMELESS: case ACTRES_ENABLER_CHECK: diff --git a/ai/default/daidiplomacy.c b/ai/default/daidiplomacy.c index 8b62adbec6..8c174eaaaf 100644 --- a/ai/default/daidiplomacy.c +++ b/ai/default/daidiplomacy.c @@ -2030,6 +2030,7 @@ void dai_incident(struct ai_type *ait, enum incident_type type, break; case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_SPY_ESCAPE: case ACTRES_TRADE_ROUTE: case ACTRES_MARKETPLACE: diff --git a/common/actions.c b/common/actions.c index 7dcc78f62e..66c178af9d 100644 --- a/common/actions.c +++ b/common/actions.c @@ -843,7 +843,7 @@ static void hard_code_oblig_hard_reqs(void) N_("All action enablers for %s must require" " that the actor isn't transported."), ACTRES_UNIT_MOVE, - ACTRES_TELEPORT, + ACTRES_TELEPORT, ACTRES_TELEPORT_CONQUER, ACTRES_NONE); /* Why this is a hard requirement: assumed by the Freeciv code. */ @@ -1498,6 +1498,11 @@ static void hard_code_actions(void) unit_action_new(ACTION_TELEPORT, ACTRES_TELEPORT, TRUE, TRUE, MAK_TELEPORT, 1, 1, FALSE); + actions[ACTION_TELEPORT_CONQUER] = + unit_action_new(ACTION_TELEPORT_CONQUER, ACTRES_TELEPORT_CONQUER, + TRUE, TRUE, + MAK_TELEPORT, 1, + ACTION_DISTANCE_MAX, FALSE); actions[ACTION_USER_ACTION1] = unit_action_new(ACTION_USER_ACTION1, ACTRES_NONE, FALSE, TRUE, @@ -3316,6 +3321,7 @@ action_actor_utype_hard_reqs_ok_full(const struct action *paction, case ACTRES_SPY_ATTACK: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_ENABLER_CHECK: case ACTRES_NONE: /* No hard unit type requirements. */ @@ -3458,6 +3464,7 @@ action_hard_reqs_actor(const struct action *paction, case ACTRES_HOMELESS: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_ESTABLISH_EMBASSY: case ACTRES_SPY_INVESTIGATE_CITY: case ACTRES_SPY_POISON: @@ -3530,9 +3537,9 @@ action_hard_reqs_actor(const struct action *paction, Can return maybe when not omniscient. Should always return yes or no when omniscient. - This is done by checking the action's hard requirements. Hard - requirements must be fulfilled before an action can be done. The reason - why is usually that code dealing with the action assumes that the + This is done by checking the action's hard requirements. + Hard requirements must be fulfilled before an action can be done. + The reason why is usually that code dealing with the action assumes that requirements are true. A requirement may also end up here if it can't be expressed in a requirement vector or if its absence makes the action pointless. @@ -4819,6 +4826,7 @@ action_prob(const action_id wanted_action, break; case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: chance = ACTPROB_CERTAIN; break; /* Not UI action, so chance is meaningless */ @@ -6683,6 +6691,8 @@ const char *action_ui_name_ruleset_var_name(int act) return "ui_name_unit_move_3"; case ACTION_TELEPORT: return "ui_name_teleport"; + case ACTION_TELEPORT_CONQUER: + return "ui_name_teleport_conquer"; case ACTION_SPY_ESCAPE: return "ui_name_escape"; case ACTION_USER_ACTION1: @@ -6999,6 +7009,9 @@ const char *action_ui_name_default(int act) case ACTION_TELEPORT: /* TRANS: _Teleport (100% chance of success). */ return N_("%sTeleport%s"); + case ACTION_TELEPORT_CONQUER: + /* TRANS: _Teleport to Conquer (100% chance of success). */ + return N_("%sTeleport to Conquer%s"); case ACTION_SPY_ESCAPE: /* TRANS: _Escape To Nearest City (100% chance of success). */ return N_("%sEscape To Nearest City%s"); @@ -7147,6 +7160,8 @@ const char *action_min_range_ruleset_var_name(int act) return "nuke_units_min_range"; case ACTION_TELEPORT: return "teleport_min_range"; + case ACTION_TELEPORT_CONQUER: + return "teleport_conquer_min_range"; case ACTION_USER_ACTION1: return "user_action_1_min_range"; case ACTION_USER_ACTION2: @@ -7241,6 +7256,7 @@ int action_min_range_default(enum action_result result) case ACTRES_NUKE_UNITS: return RS_DEFAULT_ACTION_MIN_RANGE; case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: return RS_DEFAULT_MOVE_MIN_RANGE; case ACTRES_NONE: return RS_DEFAULT_ACTION_MIN_RANGE; @@ -7388,6 +7404,8 @@ const char *action_max_range_ruleset_var_name(int act) return "airlift_max_range"; case ACTION_TELEPORT: return "teleport_max_range"; + case ACTION_TELEPORT_CONQUER: + return "teleport_conquer_max_range"; case ACTION_USER_ACTION1: return "user_action_1_max_range"; case ACTION_USER_ACTION2: @@ -7485,6 +7503,7 @@ int action_max_range_default(enum action_result result) return RS_DEFAULT_ACTION_MAX_RANGE; case ACTRES_AIRLIFT: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: return ACTION_DISTANCE_UNLIMITED; case ACTRES_NONE: return RS_DEFAULT_ACTION_MAX_RANGE; @@ -7615,6 +7634,7 @@ const char *action_target_kind_ruleset_var_name(int act) case ACTION_UNIT_MOVE2: case ACTION_UNIT_MOVE3: case ACTION_TELEPORT: + case ACTION_TELEPORT_CONQUER: case ACTION_SPY_ESCAPE: /* Target kind is not ruleset changeable */ return NULL; @@ -7715,6 +7735,7 @@ action_target_kind_default(enum action_result result) case ACTRES_HUT_FRIGHTEN: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: return ATK_TILE; case ACTRES_CONQUER_EXTRAS: return ATK_EXTRAS; @@ -7807,6 +7828,7 @@ bool action_result_legal_target_kind(enum action_result result, case ACTRES_HUT_FRIGHTEN: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: return tgt_kind == ATK_TILE; case ACTRES_CONQUER_EXTRAS: return tgt_kind == ATK_EXTRAS; @@ -7911,6 +7933,7 @@ action_sub_target_kind_default(enum action_result result) case ACTRES_HUT_FRIGHTEN: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_ENABLER_CHECK: case ACTRES_SPY_ESCAPE: return ASTK_NONE; @@ -8055,6 +8078,7 @@ const char *action_actor_consuming_always_ruleset_var_name(action_id act) case ACTION_UNIT_MOVE2: case ACTION_UNIT_MOVE3: case ACTION_TELEPORT: + case ACTION_TELEPORT_CONQUER: case ACTION_SPY_ESCAPE: /* Actor consuming always is not ruleset changeable */ return NULL; @@ -8141,6 +8165,8 @@ const char *action_blocked_by_ruleset_var_name(const struct action *act) return "move_3_blocked_by"; case ACTION_TELEPORT: return "teleport_blocked_by"; + case ACTION_TELEPORT_CONQUER: + return "teleport_conquer_blocked_by"; case ACTION_SPY_ESCAPE: case ACTION_SPY_POISON: case ACTION_SPY_POISON_ESC: @@ -8382,6 +8408,7 @@ action_post_success_forced_ruleset_var_name(const struct action *act) case ACTION_UNIT_MOVE2: case ACTION_UNIT_MOVE3: case ACTION_TELEPORT: + case ACTION_TELEPORT_CONQUER: case ACTION_SPY_ESCAPE: case ACTION_USER_ACTION1: case ACTION_USER_ACTION2: diff --git a/common/actions.h b/common/actions.h index 315e0da585..9c146ece5d 100644 --- a/common/actions.h +++ b/common/actions.h @@ -270,19 +270,20 @@ const char *gen_action_name_update_cb(const char *old_name); #define SPECENUM_VALUE109NAME "Unit Move 2" #define SPECENUM_VALUE110 ACTION_UNIT_MOVE3 #define SPECENUM_VALUE110NAME "Unit Move 3" -#define SPECENUM_VALUE111 ACTION_CLEAN -#define SPECENUM_VALUE111NAME "Clean" -/* TODO: Move next to "Move" */ -#define SPECENUM_VALUE112 ACTION_TELEPORT -#define SPECENUM_VALUE112NAME "Teleport" -#define SPECENUM_VALUE113 ACTION_USER_ACTION1 -#define SPECENUM_VALUE113NAME "User Action 1" -#define SPECENUM_VALUE114 ACTION_USER_ACTION2 -#define SPECENUM_VALUE114NAME "User Action 2" -#define SPECENUM_VALUE115 ACTION_USER_ACTION3 -#define SPECENUM_VALUE115NAME "User Action 3" -#define SPECENUM_VALUE116 ACTION_USER_ACTION4 -#define SPECENUM_VALUE116NAME "User Action 4" +#define SPECENUM_VALUE111 ACTION_TELEPORT +#define SPECENUM_VALUE111NAME "Teleport" +#define SPECENUM_VALUE112 ACTION_TELEPORT_CONQUER +#define SPECENUM_VALUE112NAME "Teleport Conquer" +#define SPECENUM_VALUE113 ACTION_CLEAN +#define SPECENUM_VALUE113NAME "Clean" +#define SPECENUM_VALUE114 ACTION_USER_ACTION1 +#define SPECENUM_VALUE114NAME "User Action 1" +#define SPECENUM_VALUE115 ACTION_USER_ACTION2 +#define SPECENUM_VALUE115NAME "User Action 2" +#define SPECENUM_VALUE116 ACTION_USER_ACTION3 +#define SPECENUM_VALUE116NAME "User Action 3" +#define SPECENUM_VALUE117 ACTION_USER_ACTION4 +#define SPECENUM_VALUE117NAME "User Action 4" #define SPECENUM_BITVECTOR bv_actions #define SPECENUM_COUNT ACTION_COUNT #define SPECENUM_NAME_UPDATER diff --git a/common/actres.c b/common/actres.c index 9b0654fa97..609a794dd1 100644 --- a/common/actres.c +++ b/common/actres.c @@ -229,6 +229,9 @@ static struct actres act_results[ACTRES_LAST] = { { ACT_TGT_COMPL_SIMPLE, ABK_NONE, /* ACTRES_TELEPORT */ FALSE, ACTIVITY_LAST, DRT_NONE, EC_NONE, ERM_NONE }, + { ACT_TGT_COMPL_SIMPLE, ABK_NONE, /* ACTRES_TELEPORT_CONQUER */ + FALSE, ACTIVITY_LAST, DRT_NONE, + EC_NONE, ERM_NONE }, { ACT_TGT_COMPL_SIMPLE, ABK_NONE, /* ACTRES_ENABLER_CHECK */ FALSE, ACTIVITY_LAST, DRT_NONE, EC_NONE, ERM_NONE } @@ -1043,7 +1046,7 @@ enum fc_tristate actres_possible(enum action_result result, case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: - + case ACTRES_TELEPORT_CONQUER: if (result == ACTRES_UNIT_MOVE) { /* Reason: is moving to the tile. */ if (!unit_can_move_to_tile(nmap, actor->unit, target->tile, @@ -1051,11 +1054,11 @@ enum fc_tristate actres_possible(enum action_result result, return TRI_NO; } } else { - fc_assert(result == ACTRES_TELEPORT); + fc_assert(result == ACTRES_TELEPORT || result == ACTRES_TELEPORT_CONQUER); /* Reason: is teleporting to the tile. */ if (!unit_can_teleport_to_tile(nmap, actor->unit, target->tile, - FALSE, FALSE)) { + FALSE, result == ACTRES_TELEPORT_CONQUER)) { return TRI_NO; } } @@ -1066,7 +1069,7 @@ enum fc_tristate actres_possible(enum action_result result, } /* We cannot move a transport into a tile that holds - * units or cities not allied with all of our cargo. */ + * units or cities not allied with ani of our cargo. */ if (get_transporter_capacity(actor->unit) > 0) { unit_list_iterate(unit_tile(actor->unit)->units, pcargo) { if (unit_contained_in(pcargo, actor->unit) diff --git a/common/fc_types.h b/common/fc_types.h index ea632f7f8d..a14e94f3c7 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -317,8 +317,9 @@ enum counter_target { CTGT_CITY }; /* TODO: Move close to "Move" */ #define SPECENUM_VALUE65 ACTRES_TELEPORT #define SPECENUM_VALUE65NAME "Teleport" +#define SPECENUM_VALUE66 ACTRES_TELEPORT_CONQUER /* Hardcoded action that's just controlled by enablers */ -#define SPECENUM_VALUE66 ACTRES_ENABLER_CHECK +#define SPECENUM_VALUE67 ACTRES_ENABLER_CHECK /* All consequences are handled as (ruleset) action data. */ #define SPECENUM_COUNT ACTRES_LAST #include "specenum_gen.h" diff --git a/doc/README.actions b/doc/README.actions index 5963bc0cd1..ad47c99979 100644 --- a/doc/README.actions +++ b/doc/README.actions @@ -1420,6 +1420,24 @@ Actions done by a unit against a tile * the target tile can't contain any city or units not allied to the actor unit and all its cargo. +"Teleport Conquer" - telepor unit to the target tile and conquer it +* UI name can be set using ui_name_teleport_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. + Actions done by a unit against all extras at a tile =================================================== "Conquer Extras" - Claim ownership of an extra. diff --git a/server/advisors/advdata.c b/server/advisors/advdata.c index a33a5a24f6..98b8b008ab 100644 --- a/server/advisors/advdata.c +++ b/server/advisors/advdata.c @@ -888,6 +888,7 @@ adv_want adv_gov_action_immunity_want(struct government *gov) case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_ENABLER_CHECK: case ACTRES_MARKETPLACE: case ACTRES_FOUND_CITY: diff --git a/server/unithand.c b/server/unithand.c index 31c802ccc8..59cd78268a 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -1118,7 +1118,7 @@ static struct player *need_war_player_hlp(const struct unit *actor, case ACTRES_PARADROP_CONQUER: /* Target is a tile but a city can block it. */ fc_assert_action(action_get_target_kind(paction) == ATK_TILE, break); - if (target_tile + if (target_tile != NULL && map_is_known_and_seen(target_tile, actor_player, V_MAIN)) { /* Seen tile unit savers */ @@ -1188,6 +1188,7 @@ static struct player *need_war_player_hlp(const struct unit *actor, case ACTRES_HUT_FRIGHTEN: case ACTRES_UNIT_MOVE: case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: case ACTRES_ENABLER_CHECK: case ACTRES_SPY_ESCAPE: case ACTRES_NONE: @@ -3923,9 +3924,12 @@ bool unit_perform_action(struct player *pplayer, target_tile, paction)); break; case ACTRES_TELEPORT: + case ACTRES_TELEPORT_CONQUER: ACTION_PERFORM_UNIT_TILE(action_type, actor_unit, target_tile, unit_move(actor_unit, target_tile, 0, - NULL, FALSE, FALSE, FALSE, + NULL, FALSE, + paction->result == ACTRES_TELEPORT_CONQUER, + paction->result == ACTRES_TELEPORT_CONQUER, FALSE, FALSE)); break; case ACTRES_TRANSFORM_TERRAIN: -- 2.40.1