summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2019-04-25 14:19:44 +0200
committernsensfel <SpamShield0@noot-noot.org>2019-04-25 14:19:44 +0200
commit4fb024b4ee52ccbb9f25b17eaa606ce0b5e0296a (patch)
treecb89cdde37bd6f091ed175c076e607f4d311a01e /src/battle/mechanic/btl_victory_progression.erl
parente68004ee70c9102d00df2925c05d1354a6315bc0 (diff)
Merging btl_character_turn_{data,update}...
Diffstat (limited to 'src/battle/mechanic/btl_victory_progression.erl')
-rw-r--r--src/battle/mechanic/btl_victory_progression.erl196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/battle/mechanic/btl_victory_progression.erl b/src/battle/mechanic/btl_victory_progression.erl
new file mode 100644
index 0000000..f50718a
--- /dev/null
+++ b/src/battle/mechanic/btl_victory_progression.erl
@@ -0,0 +1,196 @@
+-module(btl_victory_progression).
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export
+(
+ [
+ handle_character_lost_health/3
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec mark_characters_of_player_as_defeated
+ (
+ non_neg_integer(),
+ btl_battle:type()
+ )
+ ->
+ {
+ btl_battle:type(),
+ ataxic:basic()
+ }.
+mark_characters_of_player_as_defeated (PlayerIX, Battle) ->
+ AllCharacters = btl_battle:get_characters(Battle),
+
+ {ResultingBattle, BattleAtaxiaUpdates} =
+ orddict:fold
+ (
+ fun (IX, Character, {CurrentBattle, CurrentBattleAtaxiaUpdates}) ->
+ case (btl_character:get_player_index(Character) == PlayerIX) of
+ false -> {CurrentBattle, CurrentBattleAtaxiaUpdates};
+ true ->
+ {UpdatedCharacter, CharacterAtaxiaUpdate} =
+ btl_character:ataxia_set_is_defeated(true, Character),
+
+ {UpdatedBattle, NewBattleAtaxiaUpdate} =
+ btl_battle:ataxia_set_character
+ (
+ IX,
+ UpdatedCharacter,
+ CharacterAtaxiaUpdate,
+ Battle
+ ),
+
+ {
+ UpdatedBattle,
+ [NewBattleAtaxiaUpdate|CurrentBattleAtaxiaUpdates]
+ }
+ end
+ end,
+ {Battle, []},
+ AllCharacters
+ ),
+
+ {ResultingBattle, ataxic:optimize(ataxic:sequence(BattleAtaxiaUpdates))}.
+
+-spec mark_player_as_inactive
+ (
+ non_neg_integer(),
+ btl_battle:type()
+ )
+ -> {btl_battle:type(), ataxic:basic()}.
+mark_player_as_inactive (PlayerIX, Battle) ->
+ Player = btl_battle:get_player(PlayerIX, Battle),
+
+ {UpdatedPlayer, PlayerAtaxicUpdate} =
+ btl_player:ataxia_set_is_active(false, Player),
+
+ {UpdateBattle, BattleAtaxicUpdate} =
+ btl_battle:ataxia_set_player
+ (
+ PlayerIX,
+ UpdatedPlayer,
+ PlayerAtaxicUpdate,
+ Battle
+ ),
+
+ {UpdateBattle, BattleAtaxicUpdate}.
+
+-spec handle_player_defeat
+ (
+ non_neg_integer(),
+ btl_character_turn_update:type()
+ )
+ -> btl_character_turn_update:type().
+handle_player_defeat (PlayerIX, Update) ->
+ Data = btl_character_turn_update:get_data(Update),
+ Battle = btl_character_turn_data:get_battle(Data),
+
+ {S0Battle, BattleAtaxicUpdate0} =
+ mark_characters_of_player_as_defeated(PlayerIX, Battle),
+ {S1Battle, BattleAtaxicUpdate1} =
+ mark_player_as_inactive(PlayerIX, S0Battle),
+
+ UpdatedData = btl_character_turn_data:set_battle(S1Battle, Data),
+ S0Update = btl_character_turn_update:set_data(UpdatedData, Update),
+
+ S1Update =
+ btl_character_turn_update:add_to_timeline
+ (
+ btl_turn_result:new_player_lost(PlayerIX),
+ ataxia:sequence([BattleAtaxicUpdate0, BattleAtaxicUpdate1]),
+ S0Update
+ ),
+
+ S1Update.
+
+-spec actually_handle_character_lost_health
+ (
+ non_neg_integer(),
+ btl_character_turn_update:type()
+ )
+ -> btl_character_turn_update:type().
+actually_handle_character_lost_health (CharIX, Update) ->
+ Data = btl_character_turn_update:get_data(Update),
+ Battle = btl_character_turn_data:get_battle(Data),
+ Character = btl_battle:get_character(CharIX, Battle),
+ Characters = btl_battle:get_characters(Battle),
+ CharacterPlayerIX = btl_character:get_player_index(Character),
+
+ case btl_character:get_rank(Character) of
+ optional ->
+ %% Let's not assume there is a commander, meaning that we still have
+ %% to check if at least one character is alive, despite the fact that
+ %% if there is a commander, it being killed would have triggered
+ %% the defeat.
+ StillHasAliveChar =
+ lists:any
+ (
+ fun ({IX, Char}) ->
+ (
+ (CharacterPlayerIX == btl_character:get_player_index(Char))
+ and (IX /= CharIX)
+ and btl_character:get_is_alive(Char)
+ )
+ end,
+ orddict:to_list(Characters)
+ ),
+
+ case StillHasAliveChar of
+ true -> Update;
+ _ -> handle_player_defeat(CharacterPlayerIX, Update)
+ end;
+
+ commander -> handle_player_defeat(CharacterPlayerIX, Update);
+
+ target ->
+ StillHasAliveTargetChar =
+ lists:any
+ (
+ fun ({IX, Char}) ->
+ (
+ (CharacterPlayerIX == btl_character:get_player_index(Char))
+ and (IX /= CharIX)
+ and btl_character:get_is_alive(Char)
+ and (blt_character:get_rank(Char) == target)
+ )
+ end,
+ orddict:to_list(Characters)
+ ),
+
+ case StillHasAliveTargetChar of
+ true -> Update;
+ _ -> handle_player_defeat(CharacterPlayerIX, Update)
+ end
+ end.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec handle_character_lost_health
+ (
+ non_neg_integer(),
+ integer(),
+ btl_character_turn_update:type()
+ )
+ -> btl_character_turn_update:type().
+handle_character_lost_health (_, Health, Update) when (Health > 0) -> Update;
+handle_character_lost_health (CharIX, _Health, Update) ->
+ Data = btl_character_turn_update:get_data(Update),
+ S1Data = btl_character_turn_data:clean_battle(Data),
+ S1Update = btl_character_turn_update:set_data(S1Data, Update),
+
+ S2Update = actually_handle_character_lost_health(CharIX, S1Update),
+
+ S2Data = btl_character_turn_update:get_data(S2Update),
+ S3Data = btl_character_turn_data:refresh_character(S2Data),
+ S3Update = btl_character_turn_update:set_data(S3Data, S2Update),
+
+ S3Update.