summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/battlemap/game-logic')
-rw-r--r--src/battlemap/game-logic/bm_next_turn.erl4
-rw-r--r--src/battlemap/game-logic/bm_turn_actions.erl163
2 files changed, 164 insertions, 3 deletions
diff --git a/src/battlemap/game-logic/bm_next_turn.erl b/src/battlemap/game-logic/bm_next_turn.erl
index 3cd63b4..56e7f7e 100644
--- a/src/battlemap/game-logic/bm_next_turn.erl
+++ b/src/battlemap/game-logic/bm_next_turn.erl
@@ -60,14 +60,14 @@ reset_next_player_timeline (Battle) ->
-spec activate_next_players_characters (bm_battle:type(), bm_player:type())
-> {bm_battle:type(), list(sh_db_query:op())}.
activate_next_players_characters (Battle, NextPlayer) ->
- NextPlayerID = bm_player:get_id(NextPlayer),
+ NextPlayerIX = bm_player:get_index(NextPlayer),
Characters = bm_battle:get_characters(Battle),
{UpdatedCharacters, ModifiedIXs} =
sh_array_util:mapiff
(
fun (Character) ->
- (bm_character:get_owner_id(Character) == NextPlayerID)
+ (bm_character:get_player_index(Character) == NextPlayerIX)
end,
fun (Character) ->
bm_character:set_is_active(true, Character)
diff --git a/src/battlemap/game-logic/bm_turn_actions.erl b/src/battlemap/game-logic/bm_turn_actions.erl
index 87e14aa..2dfcf63 100644
--- a/src/battlemap/game-logic/bm_turn_actions.erl
+++ b/src/battlemap/game-logic/bm_turn_actions.erl
@@ -16,6 +16,149 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec handle_player_defeat
+ (
+ non_neg_integer(),
+ bm_character_turn_update:type()
+ )
+ -> bm_character_turn_update:type().
+handle_player_defeat (PlayerIX, Update) ->
+ Data = bm_character_turn_update:get_data(Update),
+ Battle = bm_character_turn_data:get_battle(Data),
+ Characters = bm_battle:get_characters(Battle),
+
+ %% FIXME: The controlled character might slip through.
+ {UpdatedCharacters, ModifiedIXs} =
+ sh_array_util:mapiff
+ (
+ fun (Character) ->
+ (bm_character:get_player_index(Character) == PlayerIX)
+ end,
+ fun (Character) ->
+ bm_character:set_rank(defeated, Character)
+ end,
+ Characters
+ ),
+
+ S1Update =
+ lists:foldl
+ (
+ fun (NextUpdate, IX) ->
+ bm_character_turn_update:add_to_db
+ (
+ sh_db_query:update_indexed
+ (
+ bm_battle:get_characters_field(),
+ IX,
+ [
+ sh_db_query:set_field
+ (
+ bm_character:get_rank_field(),
+ defeated
+ )
+ ]
+ ),
+ NextUpdate
+ )
+ end,
+ Update,
+ ModifiedIXs
+ ),
+
+ %% TODO: Battle.player[PlayerIX].is_active <- false
+
+ UpdatedBattle = bm_battle:set_characters(UpdatedCharacters, Battle),
+ UpdatedData = bm_character_turn_data:set_battle(UpdatedBattle, Data),
+ S2Update = bm_character_turn_update:set_data(UpdatedData, S1Update),
+
+ DBQuery =
+ sh_db_query:update_indexed
+ (
+ bm_battle:get_players_field(),
+ PlayerIX,
+ [
+ sh_db_query:set_field
+ (
+ bm_character:get_is_active_field(),
+ false
+ )
+ ]
+ ),
+
+ S3Update =
+ bm_character_turn_update:add_to_timeline
+ (
+ bm_turn_result:new_player_lost(PlayerIX),
+ DBQuery,
+ S2Update
+ ),
+
+ S3Update.
+
+-spec handle_victory_condition
+ (
+ non_neg_integer(),
+ integer(),
+ bm_character_turn_update:type()
+ )
+ -> bm_character_turn_update:type().
+handle_victory_condition (_, Health, Update) when (Health > 0) -> Update;
+handle_victory_condition (CharIX, _Health, Update) ->
+ Data = bm_character_turn_update:get_data(Update),
+ Battle = bm_character_turn_data:get_battle(Data),
+ Character = bm_battle:get_character(CharIX, Battle),
+ Characters = bm_battle:get_characters(Battle),
+ CharacterPlayerIX = bm_character:get_player_index(Character),
+
+ case bm_character:get_rank(Character) of
+ optional ->
+ %% Let's not assume there is a commander
+ StillHasAliveChar =
+ sh_array_util:any_indexed
+ (
+ fun (IX, Char) ->
+ (
+ (CharacterPlayerIX == bm_character:get_player_index(Char))
+ and (IX /= CharIX)
+ and bm_character:get_is_alive(Char)
+ )
+ end,
+ %% FIXME: Potential issue if it's the controlled player and Data
+ %% is dirty.
+ Characters
+ ),
+
+ case StillHasAliveChar of
+ true -> Update;
+ _ -> handle_player_defeat(CharacterPlayerIX, Update)
+ end;
+
+ commander -> handle_player_defeat(CharacterPlayerIX, Update);
+
+ target ->
+ StillHasAliveChar =
+ sh_array_util:any_indexed
+ (
+ fun (IX, Char) ->
+ (
+ (CharacterPlayerIX == bm_character:get_player_index(Char))
+ and (IX /= CharIX)
+ and bm_character:get_is_alive(Char)
+ and (bm_character:get_rank(Char) == target)
+ )
+ end,
+ %% FIXME: Potential issue if it's the controlled player and Data
+ %% is dirty.
+ Characters
+ ),
+
+ case StillHasAliveChar of
+ true -> Update;
+ _ -> handle_player_defeat(CharacterPlayerIX, Update)
+ end;
+
+ defeated -> Update
+ end.
%%%% SWITCHING WEAPON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-spec handle_switch_weapon
@@ -353,7 +496,25 @@ handle_attack (BattleAction, Update) ->
S0Update
),
- bm_character_turn_update:set_data(S1Data, S1Update).
+ S2Update = bm_character_turn_update:set_data(S1Data, S1Update),
+
+ S3Update =
+ handle_victory_condition
+ (
+ CharacterIX,
+ RemainingAttackerHealth,
+ S2Update
+ ),
+
+ S4Update =
+ handle_victory_condition
+ (
+ TargetIX,
+ RemainingDefenderHealth,
+ S3Update
+ ),
+
+ S4Update.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%