summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src/battle/mechanic/turn_action/btl_turn_actions_move.erl')
-rw-r--r-- | src/battle/mechanic/turn_action/btl_turn_actions_move.erl | 154 |
1 files changed, 118 insertions, 36 deletions
diff --git a/src/battle/mechanic/turn_action/btl_turn_actions_move.erl b/src/battle/mechanic/turn_action/btl_turn_actions_move.erl index a0cd138..70b42c9 100644 --- a/src/battle/mechanic/turn_action/btl_turn_actions_move.erl +++ b/src/battle/mechanic/turn_action/btl_turn_actions_move.erl @@ -18,16 +18,23 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec cross ( + non_neg_integer(), shr_map:type(), list(shr_location:type()), list(shr_direction:enum()), non_neg_integer(), shr_location:type() ) - -> {shr_location:type(), non_neg_integer()}. -cross (_Map, _ForbiddenLocations, [], Cost, Location) -> - {Location, Cost}; -cross (Map, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> + -> + { + shr_location:type(), + list(shr_direction:type()), + non_neg_integer(), + list(shr_map_marker:type()) + }. +cross (_PlayerIX, _Map, _ForbiddenLocations, [], Cost, Location) -> + {Location, [], Cost, []}; +cross (PlayerIX, Map, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> NextLocation = shr_location:apply_direction(Step, Location), NextTileInstance = shr_map:get_tile_instance(NextLocation, Map), NextTileClassID = shr_tile_instance:get_tile_id(NextTileInstance), @@ -43,20 +50,60 @@ cross (Map, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> ForbiddenLocations ), - IsForbidden = false, + false = IsForbidden, + + Interruptions = + list:foldl + ( + fun (MarkerName, CurrentInterruptions) -> + case shr_map:get_marker(MarkerName, Map) of + {ok, Marker} -> + case shr_map_marker:interrupts_movement(PlayerIX, Marker) of + true -> [Marker|CurrentInterruptions]; + _ -> CurrentInterruptions + end; + + error -> + %% TODO: Error. + CurrentInterruptions + end + end, + [], + shr_tile_instance:get_triggers(NextTileInstance) + ), + + case Interruptions of + [] -> + cross + ( + PlayerIX, + Map, + ForbiddenLocations, + NextSteps, + NextCost, + NextLocation + ); - cross(Map, ForbiddenLocations, NextSteps, NextCost, NextLocation). + _ -> {NextLocation, NextSteps, NextCost, Interruptions} + end. -spec cross ( + non_neg_integer(), shr_map:type(), list(shr_location:type()), list(shr_direction:enum()), shr_location:type() ) - -> {shr_location:type(), non_neg_integer()}. -cross (Map, ForbiddenLocations, Path, Location) -> - cross(Map, ForbiddenLocations, Path, 0, Location). + -> + { + shr_location:type(), + list(shr_direction:type()), + non_neg_integer(), + list(shr_map_marker:type()) + }. +cross (PlayerIX, Map, ForbiddenLocations, Path, Location) -> + cross(PlayerIX, Map, ForbiddenLocations, Path, 0, Location). -spec get_path_cost_and_destination ( @@ -67,6 +114,8 @@ cross (Map, ForbiddenLocations, Path, Location) -> { non_neg_integer(), shr_location:type(), + list(shr_direction:type()), + list(shr_map_marker:type()), btl_character_turn_update:type() }. get_path_cost_and_destination (Update, Path) -> @@ -75,6 +124,9 @@ get_path_cost_and_destination (Update, Path) -> CharacterIX = btl_character_turn_update:get_character_ix(S1Update), Map = btl_battle:get_map(Battle), + % FIXME: This is recalculated at every move action, despite there be no need + % to: The client will not allow the character to go somewhere that would + % only be freed because of an event. ForbiddenLocations = orddict:fold ( @@ -91,42 +143,35 @@ get_path_cost_and_destination (Update, Path) -> btl_battle:get_characters(Battle) ), - {NewLocation, Cost} = + {NewLocation, RemainingPath, Cost, Interruptions} = cross ( + btl_character:get_player_index(Character), Map, ForbiddenLocations, Path, btl_character:get_location(Character) ), - {Cost, NewLocation, S1Update}. + {Cost, NewLocation, RemainingPath, Interruptions, S1Update}. --spec assert_character_can_move +-spec get_movement_points ( - btl_character:type(), - non_neg_integer() + btl_action:type(), + btl_character:type() ) - -> ('ok' | 'error'). -assert_character_can_move (Char, Cost) -> - CharacterMovementPoints = - shr_statistics:get_movement_points - ( - shr_character:get_statistics + -> non_neg_integer(). +get_movement_points (Action, Char) -> + case btl_action:get_category(Action) of + interrupted_move -> btl_action:get_movement_points(Action); + _ -> + shr_statistics:get_movement_points ( - btl_character:get_base_character(Char) + shr_character:get_statistics + ( + btl_character:get_base_character(Char) + ) ) - ), - - case (Cost =< CharacterMovementPoints) of - true -> ok; - false -> - io:format - ( - "~n[E] Character trying to move ~p dist with ~p points.~n", - [Cost, CharacterMovementPoints] - ), - error end. -spec commit_move @@ -183,14 +228,51 @@ commit_move (Character, Update, Path, NewLocation) -> btl_action:type(), btl_character_turn_update:type() ) - -> btl_character_turn_update:type(). + -> + ( + {'ok', btl_character_turn_update:type()} + | {'events', list(btl_action:type()), btl_character_turn_update:type()} + ). handle (BattleAction, Update) -> {S0Update, Character} = btl_character_turn_update:get_character(Update), + Path = btl_action:get_path(BattleAction), - {PathCost, NewLocation, S1Update} = + {PathCost, NewLocation, RemainingPath, Interruptions, S1Update} = get_path_cost_and_destination(S0Update, Path), - ok = assert_character_can_move(Character, PathCost), + MovementPoints = get_movement_points(BattleAction, Character), + + true = (MovementPoints >= PathCost), + + S2Update = commit_move(Character, S1Update, Path, NewLocation), - commit_move(Character, S1Update, Path, NewLocation). + case RemainingPath of + [] -> {ok, S2Update}; + _ -> + {events, + ( + lists:foldl + ( + fun (Marker, CurrentActions) -> + ( + btl_action:from_map_marker(Character, Marker) + ++ + CurrentActions + ) + end, + [], + Interruptions + ) + ++ + [ + btl_action:new_interrupted_move + ( + RemainingPath, + (MovementPoints - PathCost) + ) + ] + ), + S2Update + } + end. |