From 3ad25c8be9ef035b87a66bc13bbf7cda747dc789 Mon Sep 17 00:00:00 2001 From: Sveinung Kvilhaugsvik Date: Wed, 10 Mar 2021 20:52:06 +0100 Subject: [PATCH] move_unit(): add frighten_hut parameter. Make move_unit() take a parameter that specifies that any entered huts should be frightened. This allows its users to order different hut popping behavior than standard. Example: A unit that is teleported from Lua in a scary way may scare away a tribal village even if it normally would be able to enter it. Take this opportunity to take hut behavior from sub_results in the action performer functions. See osdn #41729 --- server/maphand.c | 2 +- server/scripting/api_server_edit.c | 8 ++++---- server/unithand.c | 26 +++++++++++++++++++------- server/unittools.c | 26 ++++++++++++-------------- server/unittools.h | 2 +- 5 files changed, 37 insertions(+), 27 deletions(-) diff --git a/server/maphand.c b/server/maphand.c index 24c964c18c..1e57e69736 100644 --- a/server/maphand.c +++ b/server/maphand.c @@ -1759,7 +1759,7 @@ static void check_units_single_tile(struct tile *ptile) * isn't enabled? Kept like it was to preserve the old rules for * now. -- Sveinung */ unit_alive = unit_move(punit, ptile2, 0, - NULL, TRUE, FALSE, FALSE, FALSE); + NULL, TRUE, FALSE, FALSE, FALSE, FALSE); if (unit_alive && punit->activity == ACTIVITY_SENTRY) { unit_activity_handling(punit, ACTIVITY_IDLE); } diff --git a/server/scripting/api_server_edit.c b/server/scripting/api_server_edit.c index 3f7a0f04a2..93fb8273ee 100644 --- a/server/scripting/api_server_edit.c +++ b/server/scripting/api_server_edit.c @@ -193,8 +193,8 @@ bool api_edit_unit_teleport(lua_State *L, Unit *punit, Tile *dest) * return without doing anything if the unit was * HUT_NOTHING. Setting this parameter to FALSE makes * sure unit_enter_hut() isn't called. */ - unit_can_do_action_result(punit, ACTRES_HUT_FRIGHTEN) - || unit_can_do_action_result(punit, ACTRES_HUT_ENTER)); + unit_can_do_action_result(punit, ACTRES_HUT_ENTER), + unit_can_do_action_result(punit, ACTRES_HUT_FRIGHTEN)); if (alive) { struct player *owner = unit_owner(punit); @@ -855,8 +855,8 @@ bool api_edit_unit_move(lua_State *L, Unit *punit, Tile *ptile, * return without doing anything if the unit was * HUT_NOTHING. Setting this parameter to FALSE makes * sure unit_enter_hut() isn't called. */ - unit_can_do_action_result(punit, ACTRES_HUT_FRIGHTEN) - || unit_can_do_action_result(punit, ACTRES_HUT_ENTER)); + unit_can_do_action_result(punit, ACTRES_HUT_ENTER), + unit_can_do_action_result(punit, ACTRES_HUT_FRIGHTEN)); } /*************************************************************************//** diff --git a/server/unithand.c b/server/unithand.c index 6d19d4130f..1884129207 100644 --- a/server/unithand.c +++ b/server/unithand.c @@ -495,7 +495,9 @@ static bool do_conquer_extras(struct player *act_player, act_utype = unit_type_get(act_unit); unit_move(act_unit, tgt_tile, move_cost, - NULL, FALSE, FALSE, TRUE, FALSE); + NULL, FALSE, FALSE, TRUE, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); success = extra_owner(tgt_tile) == act_player; @@ -672,7 +674,9 @@ static bool do_disembark(struct player *act_player, fc_assert_ret_val(paction, FALSE); unit_move(act_unit, tgt_tile, move_cost, - NULL, FALSE, FALSE, FALSE, FALSE); + NULL, FALSE, FALSE, FALSE, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); return TRUE; } @@ -697,7 +701,9 @@ static bool do_unit_hut(struct player *act_player, fc_assert_ret_val(paction, FALSE); unit_move(act_unit, tgt_tile, move_cost, - NULL, FALSE, FALSE, FALSE, TRUE); + NULL, FALSE, FALSE, FALSE, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); return TRUE; } @@ -733,7 +739,9 @@ static bool do_unit_embark(struct player *act_player, tgt_tile = unit_tile(tgt_unit); move_cost = map_move_cost_unit(&(wld.map), act_unit, tgt_tile); unit_move(act_unit, tgt_tile, move_cost, tgt_unit, FALSE, - FALSE, FALSE, FALSE); + FALSE, FALSE, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); return TRUE; } @@ -4793,7 +4801,9 @@ static bool do_unit_conquer_city(struct player *act_player, /* Sanity check */ fc_assert_ret_val(tgt_tile, FALSE); - unit_move(act_unit, tgt_tile, move_cost, NULL, FALSE, TRUE, TRUE, FALSE); + unit_move(act_unit, tgt_tile, move_cost, NULL, FALSE, TRUE, TRUE, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); /* The city may have been destroyed during the conquest. */ success = (!city_exist(tgt_city_id) @@ -4898,8 +4908,8 @@ static bool unit_do_regular_move(struct player *actor_player, FALSE, /* Don't override "Conquer Extras" */ FALSE, - /* Don't override "Enter Hut" */ - FALSE); + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); /* May cause an incident */ action_consequence_success(paction, actor_player, act_utype, @@ -5104,6 +5114,8 @@ bool unit_move_igzoc(struct unit *punit, struct tile *pdesttile) /* Don't override "Conquer Extras" */ FALSE, /* Don't override "Enter Hut" */ + FALSE, + /* Don't override "Frighten Hut" */ FALSE); return TRUE; diff --git a/server/unittools.c b/server/unittools.c index 621d2fd78d..db3125cb2d 100644 --- a/server/unittools.c +++ b/server/unittools.c @@ -1206,7 +1206,7 @@ bool teleport_unit_to_city(struct unit *punit, struct city *pcity, move_cost = punit->moves_left; } unit_move(punit, dst_tile, move_cost, - NULL, FALSE, FALSE, FALSE, FALSE); + NULL, FALSE, FALSE, FALSE, FALSE, FALSE); return TRUE; } @@ -1269,7 +1269,7 @@ void bounce_unit(struct unit *punit, bool verbose) * because the transport is Unreachable and the unit doesn't have it in * its embarks field or because "Transport Embark" isn't enabled? Kept * like it was to preserve the old rules for now. -- Sveinung */ - unit_move(punit, ptile, 0, NULL, TRUE, FALSE, FALSE, FALSE); + unit_move(punit, ptile, 0, NULL, TRUE, FALSE, FALSE, FALSE, FALSE); return; } @@ -2782,7 +2782,9 @@ bool do_airline(struct unit *punit, struct city *pdest_city, unit_move(punit, pdest_city->tile, punit->moves_left, NULL, /* Can only airlift to allied and domestic cities */ - FALSE, FALSE, FALSE, FALSE); + FALSE, FALSE, FALSE, + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_ENTER), + BV_ISSET(paction->sub_results, ACT_SUB_RES_HUT_FRIGHTEN)); /* Update airlift fields. */ if (!(game.info.airlifting_style & AIRLIFTING_UNLIMITED_SRC)) { @@ -2917,9 +2919,8 @@ bool do_paradrop(struct unit *punit, struct tile *ptile, NULL, game.info.paradrop_to_transport, 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))) { + 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)); @@ -2967,16 +2968,13 @@ static bool hut_get_limited(struct unit *punit) Due to the effects in the scripted hut behavior can not be predicted, unit_enter_hut returns nothing. **************************************************************************/ -static void unit_enter_hut(struct unit *punit) +static void unit_enter_hut(struct unit *punit, bool frighten_hut) { struct player *pplayer = unit_owner(punit); int id = punit->id; - enum hut_behavior behavior = unit_class_get(punit)->hut_behavior; struct tile *ptile = unit_tile(punit); bool hut = FALSE; - fc_assert_ret(behavior != HUT_NOTHING); - extra_type_by_rmcause_iterate(ERM_ENTER, pextra) { if (tile_has_extra(ptile, pextra) && are_reqs_active(pplayer, tile_owner(ptile), NULL, NULL, ptile, @@ -2992,7 +2990,7 @@ static void unit_enter_hut(struct unit *punit) /* FIXME: enable different classes * to behave differently with different huts */ - if (behavior == HUT_FRIGHTEN) { + if (frighten_hut) { script_server_signal_emit("hut_frighten", punit, extra_rule_name(pextra)); } else if (is_ai(pplayer) && has_handicap(pplayer, H_LIMITEDHUTS)) { @@ -3614,7 +3612,7 @@ static void unit_move_data_unref(struct unit_move_data *pdata) bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed, bool conquer_extras_allowed, - bool enter_hut_allowed) + bool enter_hut, bool frighten_hut) { struct player *pplayer; struct tile *psrctile; @@ -4003,9 +4001,9 @@ bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, unit_lives = unit_survive_autoattack(punit); } - if (unit_lives && enter_hut_allowed) { + if (unit_lives && (enter_hut || frighten_hut)) { /* Is there a hut? */ - unit_enter_hut(punit); + unit_enter_hut(punit, frighten_hut); unit_lives = unit_is_alive(saved_id); } diff --git a/server/unittools.h b/server/unittools.h index 98b5d43e81..1eb7169193 100644 --- a/server/unittools.h +++ b/server/unittools.h @@ -160,7 +160,7 @@ void unit_transport_unload_send(struct unit *punit); bool unit_move(struct unit *punit, struct tile *pdesttile, int move_cost, struct unit *embark_to, bool find_embark_target, bool conquer_city_allowed, bool conquer_extras_allowed, - bool enter_hut_allowed); + bool enter_hut, bool frighten_hut); bool execute_orders(struct unit *punit, const bool fresh); bool unit_can_do_action_now(const struct unit *punit); -- 2.20.1