From 0cab3650ea7befa54ad197a114fbf6c8c0814b89 Mon Sep 17 00:00:00 2001 From: Louis Moureaux Date: Sat, 26 Aug 2023 03:33:57 +0200 Subject: [PATCH] Force units to load after unloading to a sea tile Say we have two transports A and B next to the coast C, with a land unit in A. Consider the following orders for the land unit: 1. Unload from A to B->tile 2. Move from B->tile to C This sequence should not succeed because the unit should still be loaded after the first step. However, in practice the unit was not loaded after step 1, resulting in an invalid state that confused ORDER_MOVED. Do the same when bumping units after a transport is killed. The fix to that is obviously to load the unit after step 1. There is a catch though: this is (and has always been) done without considering action enablers. It might be possible to exploit this to bypass loading rules. Spotted by mu in LT78. --- server/unithand.cpp | 2 +- server/unittools.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/unithand.cpp b/server/unithand.cpp index 97e287bec9..c4eddd9ecf 100644 --- a/server/unithand.cpp +++ b/server/unithand.cpp @@ -645,7 +645,7 @@ static bool do_disembark(struct player *act_player, struct unit *act_unit, fc_assert_ret_val(tgt_tile, false); fc_assert_ret_val(paction, false); - unit_move(act_unit, tgt_tile, move_cost, nullptr, false, false); + unit_move(act_unit, tgt_tile, move_cost, nullptr, true, false); return true; } diff --git a/server/unittools.cpp b/server/unittools.cpp index 740554e942..1109c740dd 100644 --- a/server/unittools.cpp +++ b/server/unittools.cpp @@ -2522,7 +2522,7 @@ void kill_unit(struct unit *pkiller, struct unit *punit, bool vet) /* FIXME: Shouldn't unit_move_handling() be used here? This is * the unit escaping by moving itself. It should therefore * respect movement rules. */ - unit_move(vunit, dsttile, move_cost, nullptr, false, false); + unit_move(vunit, dsttile, move_cost, nullptr, true, false); num_escaped[player_index(vplayer)]++; escaped = true; unitcount--;