| 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. | 


