From d8ab2d5248769ecf977803fff354a15ceec756a6 Mon Sep 17 00:00:00 2001 From: Sveinung Kvilhaugsvik Date: Fri, 19 Feb 2021 04:54:04 +0100 Subject: [PATCH] Split "Paradrop Unit" Reduce the number of paradrop side effects by splitting the new actions "Paradrop Unit Conquer", "Paradrop Unit Frighten", "Paradrop Unit Frighten Conquer", "Paradrop Unit Enter" and "Paradrop Unit Enter Conquer" from "Paradrop Unit". City conquest and extra conquest ended up in the same actions to keep the number of new actions down. They can be split later on ruleset author request. Allows more fine grained control over Paradrop side effects. Enables simplifications and clean ups already half done. See osdn #41565 --- ai/default/aiparatrooper.c | 6 +- ai/default/aiunit.c | 3 +- ai/default/daicity.c | 2 + ai/default/daidiplomacy.c | 1 + ai/default/daimilitary.c | 3 +- client/control.c | 3 +- client/gui-gtk-3.22/menu.c | 4 +- client/gui-gtk-4.0/menu.c | 4 +- client/gui-qt/dialogs.cpp | 86 +++++++++++++ client/gui-qt/menu.cpp | 6 +- client/helpdata.c | 4 +- client/packhand.c | 5 + common/actions.c | 186 +++++++++++++++++++++++++++- common/actions.h | 10 ++ common/fc_types.h | 2 + common/networking/packets.def | 2 +- common/unit.c | 13 +- common/unittype.c | 1 + common/unittype.h | 2 +- data/alien/effects.ruleset | 12 +- data/alien/game.ruleset | 49 +++++++- data/civ2/game.ruleset | 49 +++++++- data/civ2civ3/game.ruleset | 49 +++++++- data/classic/game.ruleset | 83 ++++++++++++- data/goldkeep/game.ruleset | 83 ++++++++++++- data/multiplayer/game.ruleset | 83 ++++++++++++- data/sandbox/game.ruleset | 169 +++++++++++++++++++++++-- data/webperimental/game.ruleset | 83 ++++++++++++- doc/README.actions | 149 ++++++++++++++++++++-- server/advisors/advdata.c | 8 +- server/citytools.c | 6 +- server/rscompat.c | 210 +++++++++++++++++++++++++++++--- server/ruleset.c | 12 ++ server/unithand.c | 11 +- server/unittools.c | 21 +--- 35 files changed, 1314 insertions(+), 106 deletions(-) diff --git a/ai/default/aiparatrooper.c b/ai/default/aiparatrooper.c index 459c361335..3011896396 100644 --- a/ai/default/aiparatrooper.c +++ b/ai/default/aiparatrooper.c @@ -231,7 +231,8 @@ void dai_manage_paratrooper(struct ai_type *ait, struct player *pplayer, struct action *paction = action_by_number(act_id); bool possible; - if (!action_has_result(paction, ACTRES_PARADROP)) { + if (!(action_has_result(paction, ACTRES_PARADROP) + || action_has_result(paction, ACTRES_PARADROP_CONQUER))) { /* Not relevant. */ continue; } @@ -393,7 +394,8 @@ void dai_choose_paratrooper(struct ai_type *ait, unit_type_iterate(u_type) { struct unit *virtual_unit; - if (!utype_can_do_action(u_type, ACTION_PARADROP)) { + if (!utype_can_do_action(u_type, ACTION_PARADROP) + && !utype_can_do_action(u_type, ACTION_PARADROP_CONQUER)) { continue; } if (A_NEVER == u_type->require_advance) { diff --git a/ai/default/aiunit.c b/ai/default/aiunit.c index 188d16a35e..a15f6a5d2b 100644 --- a/ai/default/aiunit.c +++ b/ai/default/aiunit.c @@ -2585,7 +2585,8 @@ void dai_manage_unit(struct ai_type *ait, struct player *pplayer, } else if (unit_has_type_role(punit, L_BARBARIAN_LEADER)) { dai_manage_barbarian_leader(ait, pplayer, punit); return; - } else if (unit_can_do_action(punit, ACTION_PARADROP)) { + } else if (unit_can_do_action_result(punit, ACTRES_PARADROP) + || unit_can_do_action_result(punit, ACTRES_PARADROP_CONQUER)) { dai_manage_paratrooper(ait, pplayer, punit); return; } else if (is_ferry && unit_data->task != AIUNIT_HUNTER) { diff --git a/ai/default/daicity.c b/ai/default/daicity.c index 4be4433ee0..264bb75ddd 100644 --- a/ai/default/daicity.c +++ b/ai/default/daicity.c @@ -1269,6 +1269,8 @@ static int action_target_neg_util(action_id act_id, return 0; /* Shouldn't happen. */ + case ACTRES_PARADROP_CONQUER: + /* Against the tile so potential city effects are overlooked for now. */ case ACTRES_SPY_BRIBE_UNIT: case ACTRES_SPY_SABOTAGE_UNIT: case ACTRES_SPY_ATTACK: diff --git a/ai/default/daidiplomacy.c b/ai/default/daidiplomacy.c index 92d1ca7bac..ca4b93698a 100644 --- a/ai/default/daidiplomacy.c +++ b/ai/default/daidiplomacy.c @@ -1987,6 +1987,7 @@ void dai_incident(struct ai_type *ait, enum incident_type type, case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: /* TODO: bigger incident */ case ACTRES_AIRLIFT: case ACTRES_HEAL_UNIT: case ACTRES_TRANSFORM_TERRAIN: diff --git a/ai/default/daimilitary.c b/ai/default/daimilitary.c index b9f63a8805..8801ebfe78 100644 --- a/ai/default/daimilitary.c +++ b/ai/default/daimilitary.c @@ -366,7 +366,8 @@ static unsigned int assess_danger_unit(const struct city *pcity, *move_time = PF_IMPOSSIBLE_MC; - if (utype_can_do_action(punittype, ACTION_PARADROP) + if ((utype_can_do_action_result(punittype, ACTRES_PARADROP) + || utype_can_do_action_result(punittype, ACTRES_PARADROP_CONQUER)) && 0 < punittype->paratroopers_range) { *move_time = (real_map_distance(ptile, unit_tile(punit)) / punittype->paratroopers_range); diff --git a/client/control.c b/client/control.c index 4adaaaeb2e..62eef57d4b 100644 --- a/client/control.c +++ b/client/control.c @@ -2985,7 +2985,8 @@ void do_unit_paradrop_to(struct unit *punit, struct tile *ptile) action_iterate(act_id) { struct action *paction = action_by_number(act_id); - if (!action_has_result(paction, ACTRES_PARADROP)) { + if (!(action_has_result(paction, ACTRES_PARADROP_CONQUER) + || action_has_result(paction, ACTRES_PARADROP))) { /* Not relevant. */ continue; } diff --git a/client/gui-gtk-3.22/menu.c b/client/gui-gtk-3.22/menu.c index d08c10d30f..f703748bc4 100644 --- a/client/gui-gtk-3.22/menu.c +++ b/client/gui-gtk-3.22/menu.c @@ -2584,7 +2584,9 @@ void real_menus_update(void) menus_rename("PLANT", plantext); menus_rename("TRANSFORM_TERRAIN", transtext); - if (units_can_do_action(punits, ACTION_PARADROP, TRUE)) { + if (units_can_do_action_with_result(punits, ACTRES_PARADROP, TRUE) + || units_can_do_action_with_result(punits, ACTRES_PARADROP_CONQUER, + TRUE)) { menus_rename("CLEAN_POLLUTION", action_get_ui_name_mnemonic(ACTION_PARADROP, "_")); } else { diff --git a/client/gui-gtk-4.0/menu.c b/client/gui-gtk-4.0/menu.c index 52549e83c4..1fc3404cae 100644 --- a/client/gui-gtk-4.0/menu.c +++ b/client/gui-gtk-4.0/menu.c @@ -2571,7 +2571,9 @@ void real_menus_update(void) menus_rename("PLANT", plantext); menus_rename("TRANSFORM_TERRAIN", transtext); - if (units_can_do_action(punits, ACTION_PARADROP, TRUE)) { + if (units_can_do_action_with_result(punits, ACTRES_PARADROP, TRUE) + || units_can_do_action_with_result(punits, ACTRES_PARADROP_CONQUER, + TRUE)) { menus_rename("CLEAN_POLLUTION", action_get_ui_name_mnemonic(ACTION_PARADROP, "_")); } else { diff --git a/client/gui-qt/dialogs.cpp b/client/gui-qt/dialogs.cpp index c2991957f5..5a7e38f764 100644 --- a/client/gui-qt/dialogs.cpp +++ b/client/gui-qt/dialogs.cpp @@ -130,6 +130,11 @@ static void nuke(QVariant data1, QVariant data2); static void attack(QVariant data1, QVariant data2); static void suicide_attack(QVariant data1, QVariant data2); static void paradrop(QVariant data1, QVariant data2); +static void paradrop_conquer(QVariant data1, QVariant data2); +static void paradrop_frighten(QVariant data1, QVariant data2); +static void paradrop_frighten_conquer(QVariant data1, QVariant data2); +static void paradrop_enter(QVariant data1, QVariant data2); +static void paradrop_enter_conquer(QVariant data1, QVariant data2); static void disembark1(QVariant data1, QVariant data2); static void disembark2(QVariant data1, QVariant data2); static void enter_hut(QVariant data1, QVariant data2); @@ -249,6 +254,12 @@ static const QHash af_map_init(void) action_function[ACTION_FOUND_CITY] = found_city; action_function[ACTION_NUKE] = nuke; action_function[ACTION_PARADROP] = paradrop; + action_function[ACTION_PARADROP_CONQUER] = paradrop_conquer; + action_function[ACTION_PARADROP_ENTER] = paradrop_enter; + action_function[ACTION_PARADROP_ENTER_CONQUER] = paradrop_enter_conquer; + action_function[ACTION_PARADROP_FRIGHTEN] = paradrop_frighten; + action_function[ACTION_PARADROP_FRIGHTEN_CONQUER] + = paradrop_frighten_conquer; action_function[ACTION_ATTACK] = attack; action_function[ACTION_SUICIDE_ATTACK] = suicide_attack; action_function[ACTION_TRANSFORM_TERRAIN] = transform_terrain; @@ -2885,6 +2896,81 @@ static void paradrop(QVariant data1, QVariant data2) } } +/***********************************************************************//** + Action "Paradrop Unit Conquer" for choice dialog +***************************************************************************/ +static void paradrop_conquer(QVariant data1, QVariant data2) +{ + int actor_id = data1.toInt(); + int target_id = data2.toInt(); + + if (NULL != game_unit_by_number(actor_id) + && NULL != index_to_tile(&(wld.map), target_id)) { + request_do_action(ACTION_PARADROP_CONQUER, + actor_id, target_id, 0, ""); + } +} + +/***********************************************************************//** + Action "Paradrop Unit Frighten" for choice dialog +***************************************************************************/ +static void paradrop_frighten(QVariant data1, QVariant data2) +{ + int actor_id = data1.toInt(); + int target_id = data2.toInt(); + + if (NULL != game_unit_by_number(actor_id) + && NULL != index_to_tile(&(wld.map), target_id)) { + request_do_action(ACTION_PARADROP_FRIGHTEN, + actor_id, target_id, 0, ""); + } +} + +/***********************************************************************//** + Action "Paradrop Unit Frighten Conquer" for choice dialog +***************************************************************************/ +static void paradrop_frighten_conquer(QVariant data1, QVariant data2) +{ + int actor_id = data1.toInt(); + int target_id = data2.toInt(); + + if (NULL != game_unit_by_number(actor_id) + && NULL != index_to_tile(&(wld.map), target_id)) { + request_do_action(ACTION_PARADROP_FRIGHTEN_CONQUER, + actor_id, target_id, 0, ""); + } +} + +/***********************************************************************//** + Action "Paradrop Unit Enter" for choice dialog +***************************************************************************/ +static void paradrop_enter(QVariant data1, QVariant data2) +{ + int actor_id = data1.toInt(); + int target_id = data2.toInt(); + + if (NULL != game_unit_by_number(actor_id) + && NULL != index_to_tile(&(wld.map), target_id)) { + request_do_action(ACTION_PARADROP_ENTER, + actor_id, target_id, 0, ""); + } +} + +/***********************************************************************//** + Action "Paradrop Unit Enter Conquer" for choice dialog +***************************************************************************/ +static void paradrop_enter_conquer(QVariant data1, QVariant data2) +{ + int actor_id = data1.toInt(); + int target_id = data2.toInt(); + + if (NULL != game_unit_by_number(actor_id) + && NULL != index_to_tile(&(wld.map), target_id)) { + request_do_action(ACTION_PARADROP_ENTER_CONQUER, + actor_id, target_id, 0, ""); + } +} + /***********************************************************************//** Action join city for choice dialog ***************************************************************************/ diff --git a/client/gui-qt/menu.cpp b/client/gui-qt/menu.cpp index 2902b1be27..bd8c021553 100644 --- a/client/gui-qt/menu.cpp +++ b/client/gui-qt/menu.cpp @@ -2335,7 +2335,11 @@ void mr_menu::menus_sensitive() || can_units_do(punits, can_unit_paradrop)) { i.value()->setEnabled(true); } - if (units_can_do_action(punits, ACTION_PARADROP, true)) { + if (units_can_do_action_with_result(punits, ACTRES_PARADROP, + true) + || units_can_do_action_with_result(punits, + ACTRES_PARADROP_CONQUER, + true)) { i.value()->setText( QString(action_id_name_translation(ACTION_PARADROP)) .replace("&", "&&")); diff --git a/client/helpdata.c b/client/helpdata.c index 94cfb38a3d..eebda07164 100644 --- a/client/helpdata.c +++ b/client/helpdata.c @@ -2458,7 +2458,9 @@ char *helptext_unit(char *buf, size_t bufsz, struct player *pplayer, /* FIXME: move paratroopers_range to the action and remove this * variable once actions are generalized. */ - int relative_max = action_has_result(paction, ACTRES_PARADROP) ? + int relative_max = (action_has_result(paction, ACTRES_PARADROP) + || action_has_result(paction, + ACTRES_PARADROP_CONQUER)) ? MIN(paction->max_distance, utype->paratroopers_range) : paction->max_distance; diff --git a/client/packhand.c b/client/packhand.c index fd3dca36be..d0c7c31a76 100644 --- a/client/packhand.c +++ b/client/packhand.c @@ -4842,6 +4842,11 @@ static action_id auto_attack_act(const struct act_prob *act_probs) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_AIRLIFT: case ACTION_HEAL_UNIT: case ACTION_HEAL_UNIT2: diff --git a/common/actions.c b/common/actions.c index 3d597475ea..3a0513a2d7 100644 --- a/common/actions.c +++ b/common/actions.c @@ -329,6 +329,7 @@ static void hard_code_oblig_hard_reqs(void) /* TRANS: error message for ruledit */ N_("All action enablers for %s must require a " "non domestic target."), + ACTRES_PARADROP_CONQUER, ACTRES_NONE); /* The same for tile extras targeted actions that also can be done to * unowned extras. */ @@ -508,6 +509,7 @@ static void hard_code_oblig_hard_reqs(void) " or that the diplomatic relation to" " the target tile owner isn't peace."), ACTRES_PARADROP, + ACTRES_PARADROP_CONQUER, ACTRES_NONE); /* Why this is a hard requirement: Preserve semantics of NonMil @@ -522,6 +524,22 @@ static void hard_code_oblig_hard_reqs(void) ACTRES_ATTACK, ACTRES_CONQUER_CITY, ACTRES_NONE); + oblig_hard_req_reg(req_contradiction_or( + 2, + req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, UTYF_CIVILIAN), + FALSE, + req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, + CITYT_CENTER), + TRUE), + /* TRANS: error message for ruledit */ + N_("All action enablers for %s must require" + " no city at the target tile or" + " that the actor doesn't have" + " the NonMil utype flag."), + ACTRES_PARADROP_CONQUER, + ACTRES_NONE); /* Why this is a hard requirement: Preserve semantics of * CanOccupyCity unit class flag. */ @@ -534,6 +552,23 @@ static void hard_code_oblig_hard_reqs(void) " the CanOccupyCity uclass flag."), ACTRES_CONQUER_CITY, ACTRES_NONE); + oblig_hard_req_reg(req_contradiction_or( + 2, + req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, + UCF_CAN_OCCUPY_CITY), + FALSE, + req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, + CITYT_CENTER), + TRUE), + /* TRANS: error message for ruledit */ + N_("All action enablers for %s must require" + " no city at the target tile or" + " that the actor has" + " the CanOccupyCity uclass flag."), + ACTRES_PARADROP_CONQUER, + ACTRES_NONE); /* Why this is a hard requirement: Consistency with ACTRES_ATTACK. * Assumed by other locations in the Freeciv code. Examples: @@ -545,6 +580,21 @@ static void hard_code_oblig_hard_reqs(void) " that the actor is at war with the target."), ACTRES_CONQUER_CITY, ACTRES_NONE); + oblig_hard_req_reg(req_contradiction_or( + 2, + req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, DS_WAR), + FALSE, + req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, + CITYT_CENTER), + TRUE), + /* TRANS: error message for ruledit */ + N_("All action enablers for %s must require" + " no city at the target tile or" + " that the actor is at war with the target."), + ACTRES_PARADROP_CONQUER, + ACTRES_NONE); /* Why this is a hard requirement: a unit must move into a city to * conquer it, move into a transport to embark, move out of a transport @@ -599,7 +649,10 @@ static void hard_code_oblig_hard_reqs(void) N_("All action enablers for %s must require" " that the actor isn't transporting" " another unit."), - ACTRES_PARADROP, ACTRES_AIRLIFT, ACTRES_NONE); + ACTRES_PARADROP, + ACTRES_PARADROP_CONQUER, + ACTRES_AIRLIFT, + ACTRES_NONE); /* Why this is a hard requirement: Assumed in the code. */ oblig_hard_req_register(req_from_values(VUT_UNITSTATE, REQ_RANGE_LOCAL, @@ -699,6 +752,22 @@ static void hard_code_oblig_hard_reqs_ruleset(void) " a non animal player actor."), ACTRES_CONQUER_CITY, ACTRES_NONE); + oblig_hard_req_reg(req_contradiction_or( + 2, + req_from_values(VUT_NATION, REQ_RANGE_PLAYER, + FALSE, TRUE, TRUE, + nation_number(pnation)), + FALSE, + req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, + CITYT_CENTER), + TRUE), + /* TRANS: error message for ruledit */ + N_("All action enablers for %s must require" + " no city at the target tile or" + " a non animal player actor."), + ACTRES_PARADROP_CONQUER, + ACTRES_NONE); } } nations_iterate_end; } @@ -964,6 +1033,53 @@ static void hard_code_actions(void) * paratroopers_range field. */ ACTION_DISTANCE_MAX, FALSE); + actions[ACTION_PARADROP_CONQUER] = + unit_action_new(ACTION_PARADROP_CONQUER, ACTRES_PARADROP_CONQUER, + TRUE, TRUE, + MAK_TELEPORT, + 1, + /* Still limited by each unit type's + * paratroopers_range field. */ + ACTION_DISTANCE_MAX, + FALSE); + actions[ACTION_PARADROP_FRIGHTEN] = + unit_action_new(ACTION_PARADROP_FRIGHTEN, ACTRES_PARADROP, + TRUE, TRUE, + MAK_TELEPORT, + 1, + /* Still limited by each unit type's + * paratroopers_range field. */ + ACTION_DISTANCE_MAX, + FALSE); + actions[ACTION_PARADROP_FRIGHTEN_CONQUER] = + unit_action_new(ACTION_PARADROP_FRIGHTEN_CONQUER, + ACTRES_PARADROP_CONQUER, + TRUE, TRUE, + MAK_TELEPORT, + 1, + /* Still limited by each unit type's + * paratroopers_range field. */ + ACTION_DISTANCE_MAX, + FALSE); + actions[ACTION_PARADROP_ENTER] = + unit_action_new(ACTION_PARADROP_ENTER, ACTRES_PARADROP, + TRUE, TRUE, + MAK_TELEPORT, + 1, + /* Still limited by each unit type's + * paratroopers_range field. */ + ACTION_DISTANCE_MAX, + FALSE); + actions[ACTION_PARADROP_ENTER_CONQUER] = + unit_action_new(ACTION_PARADROP_ENTER_CONQUER, + ACTRES_PARADROP_CONQUER, + TRUE, TRUE, + MAK_TELEPORT, + 1, + /* Still limited by each unit type's + * paratroopers_range field. */ + ACTION_DISTANCE_MAX, + FALSE); actions[ACTION_AIRLIFT] = unit_action_new(ACTION_AIRLIFT, ACTRES_AIRLIFT, TRUE, TRUE, @@ -2002,6 +2118,7 @@ bool action_creates_extra(const struct action *paction, case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_AIRLIFT: case ACTRES_STRIKE_BUILDING: case ACTRES_STRIKE_PRODUCTION: @@ -2085,6 +2202,7 @@ bool action_removes_extra(const struct action *paction, case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_AIRLIFT: case ACTRES_STRIKE_BUILDING: case ACTRES_STRIKE_PRODUCTION: @@ -3093,6 +3211,7 @@ action_actor_utype_hard_reqs_ok_full(const struct action *paction, break; case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: if (actor_unittype->paratroopers_range <= 0) { /* Reason: Can't pardrop 0 tiles. */ return FALSE; @@ -3210,6 +3329,7 @@ action_hard_reqs_actor(const struct action *paction, switch (result) { case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: /* Reason: Keep the old rules. */ /* Info leak: The player knows if his unit already has paradropped this * turn. */ @@ -3712,6 +3832,7 @@ is_action_possible(const action_id wanted_action, break; case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: /* Reason: Keep the old rules. */ /* Info leak: The player knows if he knows the target tile. */ if (!plr_knows_tile(actor_player, target_tile)) { @@ -5268,6 +5389,7 @@ action_prob(const action_id wanted_action, chance = ACTPROB_CERTAIN; break; case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: /* TODO */ break; case ACTRES_AIRLIFT: @@ -6491,6 +6613,7 @@ int action_dice_roll_initial_odds(const struct action *paction) case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_AIRLIFT: case ACTRES_ATTACK: case ACTRES_CONQUER_CITY: @@ -7000,6 +7123,16 @@ const char *action_ui_name_ruleset_var_name(int act) return "ui_name_upgrade_unit"; case ACTION_PARADROP: return "ui_name_paradrop_unit"; + case ACTION_PARADROP_CONQUER: + return "ui_name_paradrop_unit_conquer"; + case ACTION_PARADROP_FRIGHTEN: + return "ui_name_paradrop_unit_frighten"; + case ACTION_PARADROP_FRIGHTEN_CONQUER: + return "ui_name_paradrop_unit_frighten_conquer"; + case ACTION_PARADROP_ENTER: + return "ui_name_paradrop_unit_enter"; + case ACTION_PARADROP_ENTER_CONQUER: + return "ui_name_paradrop_unit_enter_conquer"; case ACTION_AIRLIFT: return "ui_name_airlift_unit"; case ACTION_ATTACK: @@ -7260,6 +7393,21 @@ const char *action_ui_name_default(int act) case ACTION_PARADROP: /* TRANS: Drop _Paratrooper (100% chance of success). */ return N_("Drop %sParatrooper%s"); + case ACTION_PARADROP_CONQUER: + /* TRANS: Drop _Paratrooper (100% chance of success). */ + return N_("Drop %sParatrooper%s"); + case ACTION_PARADROP_FRIGHTEN: + /* TRANS: Drop _Paratrooper (100% chance of success). */ + return N_("Drop %sParatrooper%s"); + case ACTION_PARADROP_FRIGHTEN_CONQUER: + /* TRANS: Drop _Paratrooper (100% chance of success). */ + return N_("Drop %sParatrooper%s"); + case ACTION_PARADROP_ENTER: + /* TRANS: Drop _Paratrooper (100% chance of success). */ + return N_("Drop %sParatrooper%s"); + case ACTION_PARADROP_ENTER_CONQUER: + /* TRANS: Drop _Paratrooper (100% chance of success). */ + return N_("Drop %sParatrooper%s"); case ACTION_AIRLIFT: /* TRANS: _Airlift to City (100% chance of success). */ return N_("%sAirlift to City%s"); @@ -7437,6 +7585,11 @@ const char *action_min_range_ruleset_var_name(int act) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_AIRLIFT: case ACTION_ATTACK: case ACTION_SUICIDE_ATTACK: @@ -7545,6 +7698,7 @@ int action_min_range_default(enum action_result result) case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_AIRLIFT: case ACTRES_STRIKE_BUILDING: case ACTRES_STRIKE_PRODUCTION: @@ -7636,6 +7790,11 @@ const char *action_max_range_ruleset_var_name(int act) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_ATTACK: case ACTION_SUICIDE_ATTACK: case ACTION_STRIKE_BUILDING: @@ -7749,6 +7908,7 @@ int action_max_range_default(enum action_result result) case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_STRIKE_BUILDING: case ACTRES_STRIKE_PRODUCTION: case ACTRES_ATTACK: @@ -7850,6 +8010,11 @@ const char *action_target_kind_ruleset_var_name(int act) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_AIRLIFT: case ACTION_ATTACK: case ACTION_SUICIDE_ATTACK: @@ -7982,6 +8147,7 @@ action_target_kind_default(enum action_result result) case ACTRES_FOUND_CITY: case ACTRES_NUKE: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_TRANSFORM_TERRAIN: case ACTRES_CULTIVATE: case ACTRES_PLANT: @@ -8067,6 +8233,7 @@ bool action_result_legal_target_kind(enum action_result result, return tgt_kind == ATK_UNITS; case ACTRES_FOUND_CITY: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_TRANSFORM_TERRAIN: case ACTRES_CULTIVATE: case ACTRES_PLANT: @@ -8168,6 +8335,7 @@ action_sub_target_kind_default(enum action_result result) case ACTRES_FOUND_CITY: case ACTRES_NUKE: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_TRANSFORM_TERRAIN: case ACTRES_CULTIVATE: case ACTRES_PLANT: @@ -8257,6 +8425,7 @@ action_target_compl_calc(enum action_result result, case ACTRES_FOUND_CITY: case ACTRES_NUKE: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_TRANSFORM_TERRAIN: case ACTRES_CULTIVATE: case ACTRES_PLANT: @@ -8338,6 +8507,11 @@ const char *action_actor_consuming_always_ruleset_var_name(action_id act) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_AIRLIFT: case ACTION_ATTACK: case ACTION_SUICIDE_ATTACK: @@ -8497,6 +8671,11 @@ const char *action_blocked_by_ruleset_var_name(const struct action *act) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_AIRLIFT: case ACTION_STRIKE_BUILDING: case ACTION_STRIKE_PRODUCTION: @@ -8621,6 +8800,11 @@ action_post_success_forced_ruleset_var_name(const struct action *act) case ACTION_HOME_CITY: case ACTION_UPGRADE_UNIT: case ACTION_PARADROP: + case ACTION_PARADROP_CONQUER: + case ACTION_PARADROP_FRIGHTEN: + case ACTION_PARADROP_FRIGHTEN_CONQUER: + case ACTION_PARADROP_ENTER: + case ACTION_PARADROP_ENTER_CONQUER: case ACTION_AIRLIFT: case ACTION_STRIKE_BUILDING: case ACTION_STRIKE_PRODUCTION: diff --git a/common/actions.h b/common/actions.h index 48f436f1c1..d9c3d3557a 100644 --- a/common/actions.h +++ b/common/actions.h @@ -262,6 +262,16 @@ extern "C" { #define SPECENUM_VALUE97NAME "Unit Move 2" #define SPECENUM_VALUE98 ACTION_UNIT_MOVE3 #define SPECENUM_VALUE98NAME "Unit Move 3" +#define SPECENUM_VALUE99 ACTION_PARADROP_CONQUER +#define SPECENUM_VALUE99NAME "Paradrop Unit Conquer" +#define SPECENUM_VALUE100 ACTION_PARADROP_FRIGHTEN +#define SPECENUM_VALUE100NAME "Paradrop Unit Frighten" +#define SPECENUM_VALUE101 ACTION_PARADROP_FRIGHTEN_CONQUER +#define SPECENUM_VALUE101NAME "Paradrop Unit Frighten Conquer" +#define SPECENUM_VALUE102 ACTION_PARADROP_ENTER +#define SPECENUM_VALUE102NAME "Paradrop Unit Enter" +#define SPECENUM_VALUE103 ACTION_PARADROP_ENTER_CONQUER +#define SPECENUM_VALUE103NAME "Paradrop Unit Enter Conquer" #define SPECENUM_BITVECTOR bv_actions #define SPECENUM_COUNT ACTION_COUNT #include "specenum_gen.h" diff --git a/common/fc_types.h b/common/fc_types.h index bca3ffc3cb..d0ba8a88c9 100644 --- a/common/fc_types.h +++ b/common/fc_types.h @@ -291,6 +291,8 @@ enum output_type_id { #define SPECENUM_VALUE57NAME "Unit Frighten Hut" #define SPECENUM_VALUE58 ACTRES_UNIT_MOVE #define SPECENUM_VALUE58NAME "Unit Move" +#define SPECENUM_VALUE59 ACTRES_PARADROP_CONQUER +#define SPECENUM_VALUE59NAME "Unit Paradrop Conquer" /* All consequences are handled as (ruleset) action data. */ #define SPECENUM_COUNT ACTRES_NONE #include "specenum_gen.h" diff --git a/common/networking/packets.def b/common/networking/packets.def index 618517f267..8e84fe4bf4 100644 --- a/common/networking/packets.def +++ b/common/networking/packets.def @@ -1389,7 +1389,7 @@ PACKET_RULESET_UNIT = 140; sc, lsend UINT8 happy_cost; # unhappy people in home city UINT8 upkeep[O_LAST]; # normal upkeep cost (food, gold, shields) - UINT16 paratroopers_range; # max range of paratroopers, ACTION_PARADROP + UINT16 paratroopers_range; # max range of paratroopers, ACTION_PARADROP* UINT8 veteran_levels; STRING veteran_name[MAX_VET_LEVELS:veteran_levels][MAX_LEN_NAME]; diff --git a/common/unit.c b/common/unit.c index 37067b096f..f8a05b0f61 100644 --- a/common/unit.c +++ b/common/unit.c @@ -793,7 +793,18 @@ bool can_unit_alight_or_be_unloaded(const struct unit *pcargo, **************************************************************************/ bool can_unit_paradrop(const struct unit *punit) { - return action_maybe_possible_actor_unit(ACTION_PARADROP, punit); + action_by_result_iterate(paction, act_id, ACTRES_PARADROP) { + if (action_maybe_possible_actor_unit(act_id, punit)) { + return TRUE; + } + } action_by_result_iterate_end; + action_by_result_iterate(paction, act_id, ACTRES_PARADROP_CONQUER) { + if (action_maybe_possible_actor_unit(act_id, punit)) { + return TRUE; + } + } action_by_result_iterate_end; + + return FALSE; } /**********************************************************************//** diff --git a/common/unittype.c b/common/unittype.c index 479eab8248..b06e08f8c4 100644 --- a/common/unittype.c +++ b/common/unittype.c @@ -345,6 +345,7 @@ static bool action_is_hostile(action_id act_id) case ACTRES_HOME_CITY: case ACTRES_UPGRADE_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: /* TODO: should this be hostile? */ case ACTRES_AIRLIFT: case ACTRES_HEAL_UNIT: case ACTRES_TRANSFORM_TERRAIN: diff --git a/common/unittype.h b/common/unittype.h index ce993e9ea2..fca5e18e1e 100644 --- a/common/unittype.h +++ b/common/unittype.h @@ -511,7 +511,7 @@ struct unit_type { int happy_cost; /* unhappy people in home city */ int upkeep[O_LAST]; - /* Only valid for ACTION_PARADROP */ + /* Only valid for ACTION_PARADROP* */ int paratroopers_range; /* Additional values for the expanded veteran system */ diff --git a/data/alien/effects.ruleset b/data/alien/effects.ruleset index d24788cfb1..f1e0fcb544 100644 --- a/data/alien/effects.ruleset +++ b/data/alien/effects.ruleset @@ -1049,8 +1049,16 @@ reqs = type = "Action_Success_Actor_Move_Cost" value = 4 reqs = - { "type", "name", "range", "present" - "Action", "Paradrop Unit", "Local", TRUE + { "type", "name", "range", "present" + "Action", "Paradrop Unit Enter", "Local", TRUE + } + +[effect_action_success_move_cost_paradrop_conquer] +type = "Action_Success_Actor_Move_Cost" +value = 4 +reqs = + { "type", "name", "range", "present" + "Action", "Paradrop Unit Enter Conquer", "Local", TRUE } [effect_fortified] diff --git a/data/alien/game.ruleset b/data/alien/game.ruleset index b6c4cd5adf..6bf1b38e24 100644 --- a/data/alien/game.ruleset +++ b/data/alien/game.ruleset @@ -459,7 +459,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -801,7 +804,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -809,6 +812,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "Extra", "Antigrav Base","Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -816,7 +820,7 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -829,8 +833,25 @@ target_reqs = "CityTile", "Claimed", "Local", FALSE } +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "4", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Antigrav Base","Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -838,6 +859,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -845,7 +867,7 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -858,6 +880,23 @@ target_reqs = "CityTile", "Claimed", "Local", FALSE } +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "4", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + [actionenabler_upgrade_unit] action = "Upgrade Unit" actor_reqs = diff --git a/data/civ2/game.ruleset b/data/civ2/game.ruleset index f758290de2..8b1c92b345 100644 --- a/data/civ2/game.ruleset +++ b/data/civ2/game.ruleset @@ -480,7 +480,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -989,7 +992,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -997,6 +1000,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "Extra", "Airbase", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1004,7 +1008,7 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1017,8 +1021,25 @@ target_reqs = "CityTile", "Claimed", "Local", FALSE } +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1026,6 +1047,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1033,7 +1055,7 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1046,6 +1068,23 @@ target_reqs = "CityTile", "Claimed", "Local", FALSE } +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + [actionenabler_upgrade_unit] action = "Upgrade Unit" actor_reqs = diff --git a/data/civ2civ3/game.ruleset b/data/civ2civ3/game.ruleset index 1c9808fb45..b1a13798d5 100644 --- a/data/civ2civ3/game.ruleset +++ b/data/civ2civ3/game.ruleset @@ -528,7 +528,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -1132,7 +1135,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1140,6 +1143,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "ExtraFlag", "ParadropFrom", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1147,7 +1151,7 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1160,8 +1164,25 @@ target_reqs = "CityTile", "Claimed", "Local", FALSE } +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "ExtraFlag", "ParadropFrom", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1169,6 +1190,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1176,7 +1198,7 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1189,6 +1211,23 @@ target_reqs = "CityTile", "Claimed", "Local", FALSE } +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + [actionenabler_upgrade_unit] action = "Upgrade Unit" actor_reqs = diff --git a/data/classic/game.ruleset b/data/classic/game.ruleset index 6c3bc68e1f..c0ffbc85cf 100644 --- a/data/classic/game.ruleset +++ b/data/classic/game.ruleset @@ -506,7 +506,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -1064,7 +1067,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1072,6 +1075,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "Extra", "Airbase", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1079,7 +1083,39 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_base_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1090,10 +1126,12 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1101,6 +1139,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1108,7 +1147,39 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_city_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1119,6 +1190,8 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_upgrade_unit] diff --git a/data/goldkeep/game.ruleset b/data/goldkeep/game.ruleset index 549089310c..91a900f494 100644 --- a/data/goldkeep/game.ruleset +++ b/data/goldkeep/game.ruleset @@ -506,7 +506,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -1078,7 +1081,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1086,6 +1089,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "Extra", "Airbase", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1093,7 +1097,39 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "9", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "9", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_base_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1104,10 +1140,12 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1115,6 +1153,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1122,7 +1161,39 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "9", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "9", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_city_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1133,6 +1204,8 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_upgrade_unit] diff --git a/data/multiplayer/game.ruleset b/data/multiplayer/game.ruleset index 754dda88d8..f60b696060 100644 --- a/data/multiplayer/game.ruleset +++ b/data/multiplayer/game.ruleset @@ -498,7 +498,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -1040,7 +1043,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1048,6 +1051,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "Extra", "Airbase", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1055,7 +1059,39 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_base_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1066,10 +1102,12 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1077,6 +1115,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1084,7 +1123,39 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_city_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1095,6 +1166,8 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_upgrade_unit] diff --git a/data/sandbox/game.ruleset b/data/sandbox/game.ruleset index edf1c3bbfd..2d4a6c040b 100644 --- a/data/sandbox/game.ruleset +++ b/data/sandbox/game.ruleset @@ -537,7 +537,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -1377,7 +1380,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed_not_forest] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1385,6 +1388,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "ExtraFlag", "ParadropFrom", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1393,7 +1397,41 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed_not_forest] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "ExtraFlag", "ParadropFrom", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "TerrainFlag", "DifficultLanding", "Local", FALSE + "Extra", "Castle", "Local", FALSE + "CityTile", "Claimed", "Local", FALSE + } + +[actionenabler_paradrop_base_to_war_conquer_not_forest] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "ExtraFlag", "ParadropFrom", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "TerrainFlag", "DifficultLanding", "Local", FALSE + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_base_to_unclaimed_base_not_forest] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1405,10 +1443,12 @@ target_reqs = { "type", "name", "range", "present" "TerrainFlag", "DifficultLanding", "Local", FALSE "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Castle", "Local", TRUE } [actionenabler_paradrop_veteran_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1417,6 +1457,7 @@ actor_reqs = "MinVeteran", 1, "Local", TRUE "ExtraFlag", "ParadropFrom", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1424,7 +1465,41 @@ target_reqs = } [actionenabler_paradrop_veteran_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "MinVeteran", 1, "Local", TRUE + "ExtraFlag", "ParadropFrom", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Castle", "Local", FALSE + } + +[actionenabler_paradrop_veteran_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "MinVeteran", 1, "Local", TRUE + "ExtraFlag", "ParadropFrom", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_veteran_base_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1436,10 +1511,12 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Castle", "Local", TRUE } [actionenabler_paradrop_city_to_claimed_not_forest] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1447,6 +1524,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1455,7 +1533,7 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed_not_forest] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1466,11 +1544,47 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "Extra", "Castle", "Local", FALSE "TerrainFlag", "DifficultLanding", "Local", FALSE } +[actionenabler_paradrop_city_to_war_conquer_not_forest] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + "TerrainFlag", "DifficultLanding", "Local", FALSE + } + +[actionenabler_paradrop_city_to_unclaimed_base_not_forest] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "TerrainFlag", "DifficultLanding", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Castle", "Local", TRUE + } + [actionenabler_paradrop_veteran_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1479,6 +1593,7 @@ actor_reqs = "MinVeteran", 1, "Local", TRUE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1486,7 +1601,41 @@ target_reqs = } [actionenabler_paradrop_veteran_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "MinVeteran", 1, "Local", TRUE + "CityTile", "Center", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Castle", "Local", FALSE + } + +[actionenabler_paradrop_veteran_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "6", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "MinVeteran", 1, "Local", TRUE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_veteran_city_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1498,6 +1647,8 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Castle", "Local", TRUE } [actionenabler_upgrade_unit] diff --git a/data/webperimental/game.ruleset b/data/webperimental/game.ruleset index c1f095ba4b..6b276223bf 100644 --- a/data/webperimental/game.ruleset +++ b/data/webperimental/game.ruleset @@ -494,7 +494,10 @@ ui_name_home_city = _("Set %sHome City%s") ui_name_upgrade_unit = _("%sUpgrade Unit%s") ; /* TRANS: Drop _Paratrooper (100% chance of success). */ -ui_name_paradrop_unit = _("Drop %sParatrooper%s") +ui_name_paradrop_unit_enter = _("Drop %sParatrooper%s") + +; /* TRANS: _Paradrop to Contested Landing (100% chance of success). */ +ui_name_paradrop_unit_enter_conquer = _("%sParadrop to Contested Landing%s") ; /* TRANS: _Airlift to City (100% chance of success). */ ui_name_airlift_unit = _("%sAirlift to City%s") @@ -1318,7 +1321,7 @@ actor_reqs = } [actionenabler_paradrop_base_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1326,6 +1329,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "Extra", "Airbase", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1333,7 +1337,39 @@ target_reqs = } [actionenabler_paradrop_base_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_base_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "Extra", "Airbase", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_base_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1344,10 +1380,12 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_paradrop_city_to_claimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1355,6 +1393,7 @@ actor_reqs = "UnitState", "Transporting", "Local", FALSE "CityTile", "Center", "Local", TRUE "DiplRel", "Peace", "Local", FALSE + "DiplRel", "War", "Local", FALSE } target_reqs = { "type", "name", "range", "present" @@ -1362,7 +1401,39 @@ target_reqs = } [actionenabler_paradrop_city_to_unclaimed] -action = "Paradrop Unit" +action = "Paradrop Unit Enter" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", FALSE + "Extra", "Fortress","Local", FALSE + } + +[actionenabler_paradrop_city_to_war_conquer] +action = "Paradrop Unit Enter Conquer" +actor_reqs = + { "type", "name", "range", "present" + "UnitFlag", "Paratroopers", "Local", TRUE + "MinMoveFrags", "3", "Local", TRUE + "UnitState", "Transporting", "Local", FALSE + "CityTile", "Center", "Local", TRUE + "DiplRel", "War", "Local", TRUE + "UnitClassFlag","CanOccupyCity","Local", TRUE + "UnitFlag", "NonMil", "Local", FALSE + } +target_reqs = + { "type", "name", "range", "present" + "CityTile", "Claimed", "Local", TRUE + } + +[actionenabler_paradrop_city_to_unclaimed_base] +action = "Paradrop Unit Enter Conquer" actor_reqs = { "type", "name", "range", "present" "UnitFlag", "Paratroopers", "Local", TRUE @@ -1373,6 +1444,8 @@ actor_reqs = target_reqs = { "type", "name", "range", "present" "CityTile", "Claimed", "Local", FALSE + "CityTile", "Center", "Local", FALSE + "Extra", "Fortress","Local", TRUE } [actionenabler_upgrade_unit] diff --git a/doc/README.actions b/doc/README.actions index 4835b47110..d2e18ffb10 100644 --- a/doc/README.actions +++ b/doc/README.actions @@ -819,22 +819,81 @@ Actions done by a unit against a tile "Paradrop Unit" - move the actor unit to the target tile. * UI name can be set using ui_name_paradrop_unit - * can result in the conquest of the city at the target tile if - - the actor player isn't an animal barbarian. - - the actor unit has the "CanOccupyCity" unit class flag - - the actor don't have the "NonMil" unit type flag - - the actor's relationship to the target is War - - the target city contains 0 units + * the distance between actor and target is from 1 to paratroopers_range + * the actor unit hasn't paradropped this turn + * the actor unit isn't transporting another unit (!) + * the actor unit can't be diplomatically forbidden from entering the target + tile. (!) + * the target tile is known (doesn't have to be seen) by the actor + * if the target tile is seen: + - the actor unit must be able to exist outside a transport on the target + tile if the target tile doesn't have a visible transport the actor unit + is able to load into on landing + - the target tile can't contain a city belonging to a player the actor + has peace, cease-fire or armistice with. + - the target tile can't contain any seen unit belonging to a player the + actor player has peace, cease-fire or armistice with. + +"Paradrop Unit Conquer" - move the actor unit to the target tile. + * UI name can be set using ui_name_paradrop_unit_conquer + * can result in the conquest of the city at the target tile + if the target tile has a city * can result in the conquest of the extras at the target tile if - - one of the extras at the target tile claims territory and is native to - the actor unit. - - the actor's relationship to the target is War or the target is unowned - * can result in hut entry if - - the actor unit has a hut_behavior of "Normal" + one of the extras at the target tile claims territory and is native to + the actor unit. + * the distance between actor and target is from 1 to paratroopers_range + * the actor unit hasn't paradropped this turn + * the actor unit isn't transporting another unit (!) + * the actor unit can't be diplomatically forbidden from entering the target + tile. (!) + * the actor unit doesn't have the NonMil unit type flag unless the target + tile doesn't have a city. (!) + * the actor unit has the CanOccupyCity unit class flag unless the target + tile doesn't have a city. (!) + * the actor owner must be at war with the target owner unless the target + tile doesn't have a city. (!) + * the actor owner can't be an animal unless the target tile doesn't have a + city. (!) + * the target tile is foreign or unclaimed. (!) + * the target tile is known (doesn't have to be seen) by the actor + * if the target tile is seen: + - the actor unit must be able to exist outside a transport on the target + tile if the target tile doesn't have a visible transport the actor unit + is able to load into on landing + - the target tile can't contain a city belonging to a player the actor + has peace, cease-fire or armistice with. + - the target tile can't contain any seen unit belonging to a player the + actor player has peace, cease-fire or armistice with. + +"Paradrop Unit Frighten" - move the actor unit to the target tile. + * UI name can be set using ui_name_paradrop_unit_frighten + * 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 + * the distance between actor and target is from 1 to paratroopers_range + * the actor unit hasn't paradropped this turn + * the actor unit isn't transporting another unit (!) + * the actor unit can't be diplomatically forbidden from entering the target + tile. (!) + * the actor unit has the hut_behavior "Frighten" + * the target tile is known (doesn't have to be seen) by the actor + * if the target tile is seen: + - the actor unit must be able to exist outside a transport on the target + tile if the target tile doesn't have a visible transport the actor unit + is able to load into on landing + - the target tile can't contain a city belonging to a player the actor + has peace, cease-fire or armistice with. + - the target tile can't contain any seen unit belonging to a player the + actor player has peace, cease-fire or armistice with. + +"Paradrop Unit Frighten Conquer" - move the actor unit to the target tile. + * UI name can be set using ui_name_paradrop_unit_frighten_conquer + * can result in the conquest of the city at the target tile + if the target tile has a city + * can result in the conquest of the extras at the target tile if + one of the extras at the target tile claims territory and is native to + the actor unit. * can result in hut frightening if - - the actor unit has a hut_behavior of "Frighten" - the target tile has an extra with "Enter" in its rmcauses (a Hut) - the target tile's Hut's rmreqs are fulfilled * the distance between actor and target is from 1 to paratroopers_range @@ -842,6 +901,72 @@ Actions done by a unit against a tile * the actor unit isn't transporting another unit (!) * the actor unit can't be diplomatically forbidden from entering the target tile. (!) + * the actor unit has the hut_behavior "Frighten" + * the actor unit doesn't have the NonMil unit type flag unless the target + tile doesn't have a city. (!) + * the actor unit has the CanOccupyCity unit class flag unless the target + tile doesn't have a city. (!) + * the actor owner must be at war with the target owner unless the target + tile doesn't have a city. (!) + * the actor owner can't be an animal unless the target tile doesn't have a + city. (!) + * the target tile is foreign or unclaimed. (!) + * the target tile is known (doesn't have to be seen) by the actor + * if the target tile is seen: + - the actor unit must be able to exist outside a transport on the target + tile if the target tile doesn't have a visible transport the actor unit + is able to load into on landing + - the target tile can't contain a city belonging to a player the actor + has peace, cease-fire or armistice with. + - the target tile can't contain any seen unit belonging to a player the + actor player has peace, cease-fire or armistice with. + +"Paradrop Unit Enter" - move the actor unit to the target tile. + * UI name can be set using ui_name_paradrop_unit_enter + * can result in hut entry if + - the target tile has an extra with "Enter" in its rmcauses (a Hut) + - the target tile's Hut's rmreqs are fulfilled + * the distance between actor and target is from 1 to paratroopers_range + * the actor unit hasn't paradropped this turn + * the actor unit isn't transporting another unit (!) + * the actor unit can't be diplomatically forbidden from entering the target + tile. (!) + * the actor unit has the hut_behavior "Normal" + * the target tile is known (doesn't have to be seen) by the actor + * if the target tile is seen: + - the actor unit must be able to exist outside a transport on the target + tile if the target tile doesn't have a visible transport the actor unit + is able to load into on landing + - the target tile can't contain a city belonging to a player the actor + has peace, cease-fire or armistice with. + - the target tile can't contain any seen unit belonging to a player the + actor player has peace, cease-fire or armistice with. + +"Paradrop Unit Enter Conquer" - move the actor unit to the target tile. + * UI name can be set using ui_name_paradrop_unit_enter_conquer + * can result in the conquest of the city at the target tile + if the target tile has a city + * can result in the conquest of the extras at the target tile if + one of the extras at the target tile claims territory and is native to + the actor unit. + * can result in hut entry if + - the target tile has an extra with "Enter" in its rmcauses (a Hut) + - the target tile's Hut's rmreqs are fulfilled + * the distance between actor and target is from 1 to paratroopers_range + * the actor unit hasn't paradropped this turn + * the actor unit isn't transporting another unit (!) + * the actor unit can't be diplomatically forbidden from entering the target + tile. (!) + * the actor unit has the hut_behavior "Normal" + * the actor unit doesn't have the NonMil unit type flag unless the target + tile doesn't have a city. (!) + * the actor unit has the CanOccupyCity unit class flag unless the target + tile doesn't have a city. (!) + * the actor owner must be at war with the target owner unless the target + tile doesn't have a city. (!) + * the actor owner can't be an animal unless the target tile doesn't have a + city. (!) + * the target tile is foreign or unclaimed. (!) * the target tile is known (doesn't have to be seen) by the actor * if the target tile is seen: - the actor unit must be able to exist outside a transport on the target diff --git a/server/advisors/advdata.c b/server/advisors/advdata.c index a6563467e2..f75f274344 100644 --- a/server/advisors/advdata.c +++ b/server/advisors/advdata.c @@ -218,7 +218,12 @@ static void count_my_units(struct player *pplayer) if (utype_can_do_action(unit_type_get(punit), ACTION_SUICIDE_ATTACK)) { adv->stats.units.suicide_attackers++; } - if (unit_can_do_action(punit, ACTION_PARADROP)) { + if (unit_can_do_action(punit, ACTION_PARADROP) + || unit_can_do_action(punit, ACTION_PARADROP_CONQUER) + || unit_can_do_action(punit, ACTION_PARADROP_FRIGHTEN) + || unit_can_do_action(punit, ACTION_PARADROP_FRIGHTEN_CONQUER) + || unit_can_do_action(punit, ACTION_PARADROP_ENTER) + || unit_can_do_action(punit, ACTION_PARADROP_ENTER_CONQUER)) { adv->stats.units.paratroopers++; } if (utype_can_do_action(punit->utype, ACTION_AIRLIFT)) { @@ -932,6 +937,7 @@ void adv_best_government(struct player *pplayer) case ACTRES_FOUND_CITY: case ACTRES_DISBAND_UNIT: case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: case ACTRES_FORTIFY: /* Wants the ability to do this to it self. Don't want others * to target it. Do nothing since action_immune_government() diff --git a/server/citytools.c b/server/citytools.c index bcfa1011b7..88ea703517 100644 --- a/server/citytools.c +++ b/server/citytools.c @@ -1900,7 +1900,11 @@ bool unit_conquer_city(struct unit *punit, struct city *pcity) * effects below. */ fc_assert_ret_val_msg(unit_can_take_over(punit) || utype_can_do_action(unit_type_get(punit), - ACTION_PARADROP), + ACTION_PARADROP_CONQUER) + || utype_can_do_action(unit_type_get(punit), + ACTION_PARADROP_FRIGHTEN_CONQUER) + || utype_can_do_action(unit_type_get(punit), + ACTION_PARADROP_ENTER_CONQUER), FALSE, "Bad unit for city occupation."); /* A transported unit trying to conquer a city should already have been diff --git a/server/rscompat.c b/server/rscompat.c index 19a3a7c9d5..2eb5970582 100644 --- a/server/rscompat.c +++ b/server/rscompat.c @@ -462,6 +462,18 @@ bool rscompat_names(struct rscompat_info *info) return TRUE; } +/**********************************************************************//** + Copy the ui_name of an existing action to the ui_name of its copy by + inserting it at the first %s in name_modification string. +**************************************************************************/ +static void split_action_name_update(struct action *original, + struct action *copy, + const char *name_modification) +{ + fc_snprintf(copy->ui_name, MAX_LEN_NAME, + name_modification, original->ui_name); +} + /**********************************************************************//** Handle a universal being separated from an original universal. @@ -542,12 +554,53 @@ static bool effect_list_compat_cb(struct effect *peffect, void *data) FALSE, FALSE, "Transport Disembark 2")); } + + /* "Paradrop Unit" has been split by side effects. */ + effect_handle_split_universal(peffect, + universal_by_number(VUT_ACTION, ACTION_PARADROP), + universal_by_number(VUT_ACTION, ACTION_PARADROP_CONQUER)); + effect_handle_split_universal(peffect, + universal_by_number(VUT_ACTION, ACTION_PARADROP), + universal_by_number(VUT_ACTION, ACTION_PARADROP_ENTER)); + effect_handle_split_universal(peffect, + universal_by_number(VUT_ACTION, ACTION_PARADROP), + universal_by_number(VUT_ACTION, ACTION_PARADROP_ENTER_CONQUER)); + effect_handle_split_universal(peffect, + universal_by_number(VUT_ACTION, ACTION_PARADROP), + universal_by_number(VUT_ACTION, ACTION_PARADROP_FRIGHTEN)); + effect_handle_split_universal(peffect, + universal_by_number(VUT_ACTION, ACTION_PARADROP), + universal_by_number(VUT_ACTION, ACTION_PARADROP_FRIGHTEN_CONQUER)); } /* Go to the next effect. */ return TRUE; } +/**********************************************************************//** + Turn paratroopers_mr_sub into the Action_Success_Actor_Move_Cost effect +**************************************************************************/ +static void paratroopers_mr_sub_to_effect(struct unit_type *putype, + struct action *paction) +{ + struct effect *peffect; + + /* Subtract the value via the Action_Success_Actor_Move_Cost effect */ + peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST, + putype->rscompat_cache.paratroopers_mr_sub, + NULL); + + /* The reduction only applies to this action. */ + effect_req_append(peffect, + req_from_str("Action", "Local", FALSE, TRUE, FALSE, + action_rule_name(paction))); + + /* The reduction only applies to this unit type. */ + effect_req_append(peffect, + req_from_str("UnitType", "Local", FALSE, TRUE, FALSE, + utype_rule_name(putype))); +} + /**********************************************************************//** Do compatibility things after regular ruleset loading. **************************************************************************/ @@ -712,20 +765,12 @@ void rscompat_postprocess(struct rscompat_info *info) continue; } - /* Subtract the value via the Action_Success_Actor_Move_Cost effect */ - peffect = effect_new(EFT_ACTION_SUCCESS_MOVE_COST, - putype->rscompat_cache.paratroopers_mr_sub, - NULL); - - /* The reduction only applies to "Paradrop Unit". */ - effect_req_append(peffect, - req_from_str("Action", "Local", FALSE, TRUE, FALSE, - "Paradrop Unit")); - - /* The reduction only applies to this unit type. */ - effect_req_append(peffect, - req_from_str("UnitType", "Local", FALSE, TRUE, FALSE, - utype_rule_name(putype))); + action_by_result_iterate(paction, act_id, ACTRES_PARADROP) { + paratroopers_mr_sub_to_effect(putype, paction); + } action_by_result_iterate_end; + action_by_result_iterate(paction, act_id, ACTRES_PARADROP_CONQUER) { + paratroopers_mr_sub_to_effect(putype, paction); + } action_by_result_iterate_end; } unit_type_iterate_end; /* Fortifying rules have been unhardcoded to effects. */ @@ -1211,6 +1256,139 @@ void rscompat_postprocess(struct rscompat_info *info) BV_SET(game.info.diplchance_initial_odds, act->id); } } action_iterate_end; + + + /* "Paradrop Unit" has been split by side effects. */ + split_action_name_update(action_by_number(ACTION_PARADROP), + action_by_number(ACTION_PARADROP_CONQUER), + "Contested %s"); + split_action_name_update(action_by_number(ACTION_PARADROP), + action_by_number(ACTION_PARADROP_ENTER), + "Enter Hut %s"); + split_action_name_update(action_by_number(ACTION_PARADROP), + action_by_number( + ACTION_PARADROP_ENTER_CONQUER), + "Enter Hut Contested %s"); + split_action_name_update(action_by_number(ACTION_PARADROP), + action_by_number(ACTION_PARADROP_FRIGHTEN), + "Frighten Hut %s"); + split_action_name_update(action_by_number(ACTION_PARADROP), + action_by_number( + ACTION_PARADROP_FRIGHTEN_CONQUER), + "Frighten Hut Contested %s"); + + action_enabler_list_iterate( + action_enablers_for_action(ACTION_PARADROP), ae) { + struct action_enabler *edit; + + action_by_result_iterate(para_action, para_id, + ACTRES_PARADROP_CONQUER) { + /* Conquer City and/or owned Extra during war if one is there */ + edit = action_enabler_copy(ae); + edit->action = para_action->id; + e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, DS_WAR); + requirement_vector_append(&edit->actor_reqs, e_req); + e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, CITYT_CLAIMED); + if (!is_req_in_vec(&e_req, &ae->target_reqs)) { + requirement_vector_append(&edit->target_reqs, e_req); + } + e_req = req_from_values(VUT_UCFLAG, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, + UCF_CAN_OCCUPY_CITY); + requirement_vector_append(&edit->actor_reqs, e_req); + e_req = req_from_values(VUT_UTFLAG, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, + UTYF_CIVILIAN); + requirement_vector_append(&edit->actor_reqs, e_req); + action_enabler_add(edit); + + /* Conquer owned Extra during war if there */ + edit = action_enabler_copy(ae); + edit->action = para_action->id; + e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, DS_WAR); + requirement_vector_append(&edit->actor_reqs, e_req); + e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, CITYT_CLAIMED); + if (!is_req_in_vec(&e_req, &ae->target_reqs)) { + requirement_vector_append(&edit->target_reqs, e_req); + } + e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, CITYT_CENTER); + requirement_vector_append(&edit->target_reqs, e_req); + action_enabler_add(edit); + + /* Unowned Extra conquest */ + extra_type_by_cause_iterate(EC_BASE, pextra) { + if (!territory_claiming_base(extra_base_get(pextra))) { + /* Only territory claiming bases can be conquered in 3.0 */ + continue; + } + + edit = action_enabler_copy(ae); + edit->action = para_action->id; + e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, CITYT_CLAIMED); + if (!is_req_in_vec(&e_req, &ae->target_reqs)) { + requirement_vector_append(&edit->target_reqs, e_req); + } + e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, CITYT_CENTER); + requirement_vector_append(&edit->target_reqs, e_req); + e_req = req_from_values(VUT_EXTRA, REQ_RANGE_LOCAL, + FALSE, TRUE, TRUE, pextra->id); + requirement_vector_append(&edit->target_reqs, e_req); + action_enabler_add(edit); + } extra_type_by_cause_iterate_end; + } action_by_result_iterate_end; + + action_by_result_iterate(para_action, para_id, ACTRES_PARADROP) { + if (para_action->id == ACTION_PARADROP) { + /* Use when not at war and against unclaimed tiles. */ + e_req = req_from_values(VUT_CITYTILE, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, CITYT_CLAIMED); + if (is_req_in_vec(&e_req, &ae->target_reqs)) { + /* Use Conquer version for unowned Extras */ + extra_type_by_cause_iterate(EC_BASE, pextra) { + if (!territory_claiming_base(extra_base_get(pextra))) { + /* Only territory claiming bases can be conquered in 3.0 */ + continue; + } + + e_req = req_from_values(VUT_EXTRA, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, pextra->id); + requirement_vector_append(&ae->target_reqs, e_req); + } extra_type_by_cause_iterate_end; + } else { + /* Use Conquer version during war. */ + e_req = req_from_values(VUT_DIPLREL, REQ_RANGE_LOCAL, + FALSE, FALSE, TRUE, DS_WAR); + requirement_vector_append(&ae->actor_reqs, e_req); + } + } else { + /* !War req requirement added before the copy. */ + edit = action_enabler_copy(ae); + edit->action = para_action->id; + action_enabler_add(edit); + } + } action_by_result_iterate_end; + } action_enabler_list_iterate_end; + + /* The non hut popping version is only legal when hut_behavior is + * "Nothing". */ + action_enablers_iterate(ae) { + if (ae->action != ACTION_PARADROP + && ae->action != ACTION_PARADROP_CONQUER) { + /* Not relevant. */ + continue; + } + + e_req = req_from_str("UnitClassFlag", "local", + FALSE, TRUE, FALSE, "HutNothing"); + requirement_vector_append(&ae->actor_reqs, e_req); + } action_enablers_iterate_end; } if (info->ver_units < 20) { @@ -1224,6 +1402,10 @@ void rscompat_postprocess(struct rscompat_info *info) } unit_class_iterate_end; } + /* Make sure that all action enablers added or modified by the + * compatibility post processing fulfills all hard action requirements. */ + rscompat_enablers_add_obligatory_hard_reqs(); + /* The ruleset may need adjustments it didn't need before compatibility * post processing. * diff --git a/server/ruleset.c b/server/ruleset.c index b81d98726c..9545675c23 100644 --- a/server/ruleset.c +++ b/server/ruleset.c @@ -6887,12 +6887,24 @@ static bool load_ruleset_game(struct section_file *file, bool act, } /* Hard code action sub results for now. */ + + /* Unit Enter Hut */ action_by_result_iterate(paction, act_id, ACTRES_HUT_ENTER) { BV_SET(paction->sub_results, ACT_SUB_RES_HUT_ENTER); } action_by_result_iterate_end; + BV_SET(action_by_number(ACTION_PARADROP_ENTER)->sub_results, + ACT_SUB_RES_HUT_ENTER); + BV_SET(action_by_number(ACTION_PARADROP_ENTER_CONQUER)->sub_results, + ACT_SUB_RES_HUT_ENTER); + + /* Unit Frighten Hut */ action_by_result_iterate(paction, act_id, ACTRES_HUT_FRIGHTEN) { BV_SET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN); } action_by_result_iterate_end; + BV_SET(action_by_number(ACTION_PARADROP_FRIGHTEN)->sub_results, + ACT_SUB_RES_HUT_FRIGHTEN); + BV_SET(action_by_number(ACTION_PARADROP_FRIGHTEN_CONQUER)->sub_results, + ACT_SUB_RES_HUT_FRIGHTEN); } if (ok) { diff --git a/server/unithand.c b/server/unithand.c index 64a8305d54..2e0faff4fe 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -807,6 +807,7 @@ static struct player *need_war_player_hlp(const struct unit *actor, break; case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: /* Target is a tile but a city or unit can block it. */ fc_assert_action(action_get_target_kind(paction) == ATK_TILE, break); if (target_tile @@ -1293,7 +1294,8 @@ static struct ane_expl *expl_act_not_enabl(struct unit *punit, TER_NO_CITIES)) { explnat->kind = ANEK_BAD_TERRAIN_TGT; explnat->no_act_terrain = tile_terrain(target_tile); - } else if (action_has_result_safe(paction, ACTRES_PARADROP) + } else if ((action_has_result_safe(paction, ACTRES_PARADROP) + || action_has_result_safe(paction, ACTRES_PARADROP_CONQUER)) && target_tile && map_is_known_and_seen(target_tile, unit_owner(punit), V_MAIN) @@ -1420,7 +1422,8 @@ static struct ane_expl *expl_act_not_enabl(struct unit *punit, unit_tile(target_unit)))))) { explnat->kind = ANEK_DISTANCE_FAR; explnat->distance = paction->max_distance; - } else if (action_has_result_safe(paction, ACTRES_PARADROP) + } else if ((action_has_result_safe(paction, ACTRES_PARADROP_CONQUER) + || action_has_result_safe(paction, ACTRES_PARADROP)) && punit && target_tile && real_map_distance(unit_tile(punit), target_tile) > unit_type_get(punit)->paratroopers_range) { @@ -1491,7 +1494,8 @@ static struct ane_expl *expl_act_not_enabl(struct unit *punit, } else if (action_has_result_safe(paction, ACTRES_FOUND_CITY) && citymindist_prevents_city_on_tile(target_tile)) { explnat->kind = ANEK_CITY_TOO_CLOSE_TGT; - } else if (action_has_result_safe(paction, ACTRES_PARADROP) + } else if ((action_has_result_safe(paction, ACTRES_PARADROP_CONQUER) + || action_has_result_safe(paction, ACTRES_PARADROP)) && target_tile && !map_is_known(target_tile, unit_owner(punit))) { explnat->kind = ANEK_TGT_TILE_UNKNOWN; @@ -3455,6 +3459,7 @@ bool unit_perform_action(struct player *pplayer, paction)); break; case ACTRES_PARADROP: + case ACTRES_PARADROP_CONQUER: ACTION_STARTED_UNIT_TILE(action_type, actor_unit, target_tile, do_paradrop(actor_unit, target_tile, paction)); break; diff --git a/server/unittools.c b/server/unittools.c index 8a7d04134e..d7b307ae47 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -2932,22 +2932,11 @@ bool do_paradrop(struct unit *punit, struct tile *ptile, /* Done by Action_Success_Actor_Move_Cost */ 0, NULL, game.info.paradrop_to_transport, - /* A paradrop into a non allied city results in a city - * occupation. */ - /* FIXME: move the following actor requirements to the - * ruleset. One alternative is to split "Paradrop Unit". - * Another is to use different enablers. */ - (pplayer->ai_common.barbarian_type != ANIMAL_BARBARIAN - && uclass_has_flag(unit_class_get(punit), - UCF_CAN_OCCUPY_CITY) - && !unit_has_type_flag(punit, UTYF_CIVILIAN) - && is_non_allied_city_tile(ptile, pplayer)), - (extra_owner(ptile) == NULL - || pplayers_at_war(extra_owner(ptile), unit_owner(punit))) - && tile_has_claimable_base(ptile, unit_type_get(punit)), - /* TODO: Split "Paradrop Unit" so hut entry / frightening - * action sub results can be set for it. */ - unit_class_get(punit)->hut_behavior != HUT_NOTHING)) { + paction->result == ACTRES_PARADROP_CONQUER, + paction->result == ACTRES_PARADROP_CONQUER, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER) + || BV_ISSET(paction->sub_results, + ACT_SUB_RES_HUT_FRIGHTEN))) { /* Ensure we finished on valid state. */ fc_assert(can_unit_exist_at_tile(&(wld.map), punit, unit_tile(punit)) || unit_transported(punit)); -- 2.20.1