summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-05-21 16:39:12 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-05-21 16:39:12 +0200
commit0157365585c1201c53aa29cac84cd977de7434a1 (patch)
tree44c301187f2809be974dbe8afcbc1032002ec1e8 /src/battle/mechanic/turn_action/btl_turn_actions_move.erl
parentfb4159dbfb49f71d23c2616e7b8c9be453953883 (diff)
Working on Attacks of Opportunity.
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.erl154
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.