summaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | src/battle/attack.erl (renamed from src/battlemap/attack.erl) | 0 | ||||
-rw-r--r-- | src/battle/battle_turn.erl | 135 | ||||
-rw-r--r-- | src/battle/movement.erl (renamed from src/battlemap/movement.erl) | 10 | ||||
-rw-r--r-- | src/battle/roll.erl (renamed from src/battlemap/roll.erl) | 0 | ||||
-rw-r--r-- | src/handler.erl | 2 | ||||
-rw-r--r-- | src/query/character_turn.erl | 208 | ||||
-rw-r--r-- | src/query/load_state.erl | 24 | ||||
-rw-r--r-- | src/shim/database_shim.erl | 6 | ||||
-rw-r--r-- | src/struct/battle.erl (renamed from src/struct/battlemap_instance.erl) | 81 | ||||
-rw-r--r-- | src/struct/battle_action.erl | 123 |
10 files changed, 345 insertions, 244 deletions
diff --git a/src/battlemap/attack.erl b/src/battle/attack.erl index 7384f78..7384f78 100644 --- a/src/battlemap/attack.erl +++ b/src/battle/attack.erl diff --git a/src/battle/battle_turn.erl b/src/battle/battle_turn.erl new file mode 100644 index 0000000..e295f09 --- /dev/null +++ b/src/battle/battle_turn.erl @@ -0,0 +1,135 @@ +-module(battle_turn). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + handle_post_play/1 + ] +). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec activate_relevant_character_instances + ( + list(non_neg_integer()), + array:array(character_instance:struct()), + player:id(), + (-1 | non_neg_integer()) + ) + -> {list(non_neg_integer()), array:array(character_instance:struct())}. +activate_relevant_character_instances (IXs, CharacterInstances, _Owner, -1) -> + {IXs, CharacterInstances}; +activate_relevant_character_instances (IXs, CharacterInstances, Owner, IX) -> + CharacterInstance = array:get(IX, CharacterInstances), + Character = character_instance:get_character(CharacterInstance), + case character:get_owner_id(Character) of + OwnerID when (OwnerID == Owner) -> + activate_relevant_character_instances + ( + [IX|IXs], + array:set + ( + IX, + character_instance:set_is_active(true, CharacterInstance), + CharacterInstances + ), + Owner, + (IX - 1) + ); + + _ -> + activate_relevant_character_instances + ( + IXs, + CharacterInstances, + Owner, + (IX - 1) + ) + end. + +-spec start_next_players_turn (battle:struct()) -> + {list(non_neg_integer()), battle:struct()}. +start_next_players_turn (Battle) -> + PlayerIDs = battle:get_player_ids(Battle), + PlayerTurn = battle:get_current_player_turn(Battle), + CurrentPlayerIX = player_turn:get_player_ix(PlayerTurn), + CurrentTurnNumber = player_turn:get_number(PlayerTurn), + CharacterInstances = battle:get_character_instances(Battle), + + NextPlayerIX = ((CurrentPlayerIX + 1) rem (array:size(PlayerIDs))), + NextPlayerTurn = + player_turn:new + ( + case NextPlayerIX of + 0 -> (CurrentTurnNumber + 1); + _ -> CurrentTurnNumber + end, + NextPlayerIX + ), + + {ActivatedCharacterInstanceIXs, UpdatedCharacterInstances} = + activate_relevant_character_instances + ( + [], + CharacterInstances, + array:get(NextPlayerIX, PlayerIDs), + (array:size(CharacterInstances) - 1) + ), + UpdatedBattle = + battle:set_character_instances + ( + UpdatedCharacterInstances, + battle:set_current_player_turn + ( + NextPlayerTurn, + Battle + ) + ), + {ActivatedCharacterInstanceIXs, UpdatedBattle}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-spec handle_post_play (battle:struct()) -> + {database_diff:struct(), battle:struct()}. +handle_post_play (Battle) -> + CharacterInstances = battle:get_character_instances(Battle), + + AnActiveCharacterInstanceRemains = + array:foldl + ( + fun (_IX, CharacterInstance, Prev) -> + (Prev or character_instance:get_is_active(CharacterInstance)) + end, + false, + CharacterInstances + ), + + case AnActiveCharacterInstanceRemains of + true -> + io:format("~nThere are still active characters.~n"), + {[], Battle}; + + false -> + io:format("~nThere are no more active characters.~n"), + {UpdatedCharacterInstanceIXs, UpdatedBattle} = + start_next_players_turn(Battle), + { + lists:map + ( + fun (IX) -> + {set, character_instance, IX, is_active, true} + end, + UpdatedCharacterInstanceIXs + ), + UpdatedBattle + } + end. diff --git a/src/battlemap/movement.erl b/src/battle/movement.erl index 02f0ebc..720b60c 100644 --- a/src/battlemap/movement.erl +++ b/src/battle/movement.erl @@ -20,7 +20,7 @@ -spec cross ( battlemap:struct(), - array:array(location:type()), + list(location:type()), list(direction:enum()), non_neg_integer(), location:type() @@ -29,13 +29,13 @@ cross (_Battlemap, _ForbiddenLocations, [], Cost, Location) -> {Location, Cost}; cross (Battlemap, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> - NextLocation = direction:apply_to(Step, Location), - NextTile = battlemap:get_tile_id(Battlemap, NextLocation), + NextLocation = location:apply_direction(Step, Location), + NextTile = battlemap:get_tile_id(NextLocation, Battlemap), NextCost = (Cost + tile:get_cost(NextTile)), IsForbidden = - array:foldl + lists:foldl ( - fun (_IX, ForbiddenLocation, Prev) -> + fun (ForbiddenLocation, Prev) -> (Prev or (NextLocation == ForbiddenLocation)) end, false, diff --git a/src/battlemap/roll.erl b/src/battle/roll.erl index 074054b..074054b 100644 --- a/src/battlemap/roll.erl +++ b/src/battle/roll.erl diff --git a/src/handler.erl b/src/handler.erl index f1cc1a0..0ecc8be 100644 --- a/src/handler.erl +++ b/src/handler.erl @@ -19,5 +19,5 @@ start (_YawsParams) -> {ok, Pid} = timed_caches_manager:start(), database_shim:generate_db(Pid), - timed_caches_manager:new_cache(Pid, battlemap_instance_db, none), + timed_caches_manager:new_cache(Pid, battle_db, none), ok. diff --git a/src/query/character_turn.erl b/src/query/character_turn.erl index adfc542..818ac8a 100644 --- a/src/query/character_turn.erl +++ b/src/query/character_turn.erl @@ -27,19 +27,7 @@ } ). --record -( - query_result, - { - is_new_turn :: boolean(), - updated_character_instance_ixs :: list(non_neg_integer()), - updated_battle :: battle:struct() - } -). - -type input() :: #input{}. --type query_result() :: #query_result{}. - -type relevant_data() :: #relevant_data{}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -117,6 +105,8 @@ finalize_and_fuse_relevant_data (RData, Input) -> Battle = RData#relevant_data.battle, CharacterInstance = RData#relevant_data.played_character_instance, + io:format("~nNot a character instance? ~p~n", [CharacterInstance]), + FinalizedCharacterInstance = character_instance:set_is_active(false, CharacterInstance), @@ -127,125 +117,6 @@ finalize_and_fuse_relevant_data (RData, Input) -> Battle ). --spec activate_relevant_character_instances - ( - list(non_neg_integer()), - array:array(character_instance:struct()), - player:id(), - (-1 | non_neg_integer()) - ) - -> {list(non_neg_integer()), array:array(character_instance:struct())}. -activate_relevant_character_instances (IXs, CharacterInstances, _Owner, -1) -> - {IXs, CharacterInstances}; -activate_relevant_character_instances (IXs, CharacterInstances, Owner, IX) -> - CharacterInstance = array:get(IX, CharacterInstances), - Character = character_instance:get_character(CharacterInstance), - case character:get_owner_id(Character) of - OwnerID when (OwnerID == Owner) -> - activate_relevant_character_instances - ( - [IX|IXs], - array:set - ( - IX, - character_instance:set_is_active(true, CharacterInstance), - CharacterInstances - ), - Owner, - (IX - 1) - ); - - _ -> - activate_relevant_character_instances - ( - IXs, - CharacterInstances, - Owner, - (IX - 1) - ) - end. - --spec start_next_players_turn - ( - query_state() - ) - -> {list(non_neg_integer()), battle:struct()}. -start_next_players_turn (QueryState) -> - Battle = QueryState#query_state.battle, - PlayerIDs = battle:get_player_ids(Battle), - PlayerTurn = battle:get_current_player_turn(Battle), - CurrentPlayerIX = player_turn:get_player_ix(PlayerTurn), - CurrentTurnNumber = player_turn:get_number(PlayerTurn), - CharacterInstances = battle:get_character_instances(Battle), - - NextPlayerIX = ((CurrentPlayerIX + 1) rem (array:size(PlayerIDs))), - NextPlayerTurn = - player_turn:new - ( - case NextPlayerIX of - 0 -> (CurrentTurnNumber + 1); - _ -> CurrentTurnNumber - end, - NextPlayerIX - ), - - {ActivatedCharacterInstanceIXs, UpdatedCharacterInstances} = - activate_relevant_character_instances - ( - [], - CharacterInstances, - array:get(NextPlayerIX, PlayerIDs), - (array:size(CharacterInstances) - 1) - ), - UpdatedBattle = - battle:set_character_instances - ( - UpdatedCharacterInstances, - battle:set_current_player_turn - ( - NextPlayerTurn, - Battle - ) - ), - {ActivatedCharacterInstanceIXs, UpdatedBattle}. - --spec finalize_character_turn (query_state()) -> query_result(). -finalize_character_turn (QueryState) -> - Battle = QueryState#query_state.battle, - CharacterInstances = - battle:get_character_instances(Battle), - - AnActiveCharacterInstanceRemains = - array:foldl - ( - fun (_IX, CharacterInstance, Prev) -> - (Prev or character_instance:get_is_active(CharacterInstance)) - end, - false, - CharacterInstances - ), - - case AnActiveCharacterInstanceRemains of - true -> - io:format("~nThere are still active characters.~n"), - #query_result - { - is_new_turn = false, - updated_character_instance_ixs = [], - updated_battle = Battle - }; - false -> - io:format("~nThere are no more active characters.~n"), - {UpdatedCharacterInstanceIXs, UpdatedBattle} = - start_next_players_turn(QueryState), - #query_result - { - is_new_turn = true, - updated_character_instance_ixs = UpdatedCharacterInstanceIXs, - updated_battle = UpdatedBattle - } - end. - %-spec send_to_database (list(database_diff:struct()), input()) -> 'ok'. -spec send_to_database (battle:struct(), input()) -> 'ok'. send_to_database (FinalizedBattle, Input) -> @@ -261,11 +132,10 @@ send_to_database (FinalizedBattle, Input) -> FinalizedBattle ). --spec update_cache (query_result(), input()) -> 'ok'. -update_cache (QueryResult, Input) -> +-spec update_cache (battle:struct(), input()) -> 'ok'. +update_cache (Battle, Input) -> PlayerID = Input#input.player_id, BattleID = Input#input.battle_id, - Battle = QueryResult#query_result.updated_battle, timed_cache:update ( @@ -292,12 +162,68 @@ generate_reply (ClientUpdate) -> ] ). +handle_actions (RData, Input) -> + Battle = RData#relevant_data.battle, + CharacterInstance= RData#relevant_data.played_character_instance, + CharacterInstanceIX = Input#input.character_instance_ix, + Actions = Input#input.actions, + + { + ActionsDiffUpdates, + ClientUpdates, + PostActionCharacterInstance, + PostActionBattle + } = + lists:foldl + ( + fun + ( + Action, + { + CurrActionsDiffUpdates, + CurrClientUpdates, + CurrCharacterInstance, + CurrBattle + } + ) -> + { + NewActionsDiffUpdates, + NewClientUpdates, + NewCharacterInstance, + NewBattle + } = + battle_action:handle + ( + CurrBattle, + CurrCharacterInstance, + CharacterInstanceIX, + Action + ), + { + (CurrActionsDiffUpdates ++ NewActionsDiffUpdates), + (CurrClientUpdates ++ NewClientUpdates), + NewCharacterInstance, + NewBattle + } + end, + {[], [], CharacterInstance, Battle}, + Actions + ), + { + ActionsDiffUpdates, + ClientUpdates, + RData#relevant_data + { + battle = PostActionBattle, + played_character_instance = PostActionCharacterInstance + } + }. + -spec handle (binary()) -> binary(). handle (Req) -> Input = parse_input(Req), PlayerID = Input#input.player_id, PlayerSessionToken = Input#input.session_token, - Actions = Input#input.actions, security:assert_identity(PlayerID, PlayerSessionToken), security:lock_queries(PlayerID), @@ -307,18 +233,12 @@ handle (Req) -> assert_character_instance_can_be_played(RData, Input), {ActionsDiffUpdate, ClientUpdate, UpdatedRData} = - lists:foldl - ( - fun (Action, Prev) -> - battle_action:handle(Action, Prev) - end, - {[], [], RData}, - Actions - ), + handle_actions(RData, Input), UpdatedBattle = finalize_and_fuse_relevant_data(UpdatedRData, Input), - {TurnDiffUpdate, FinalizedBattle} = end_of_turn:apply_to(UpdatedBattle), + {TurnDiffUpdate, FinalizedBattle} = + battle_turn:handle_post_play(UpdatedBattle), DiffUpdate = (TurnDiffUpdate ++ ActionsDiffUpdate), diff --git a/src/query/load_state.erl b/src/query/load_state.erl index 9999050..eb27b9e 100644 --- a/src/query/load_state.erl +++ b/src/query/load_state.erl @@ -11,7 +11,7 @@ { player_id :: player:id(), session_token :: binary(), - battlemap_instance_id :: binary() + battle_id :: binary() } ). @@ -19,7 +19,7 @@ ( query_state, { - battlemap_instance :: battlemap_instance:struct() + battle :: battle:struct() } ). @@ -39,42 +39,42 @@ parse_input (Req) -> JSONReqMap = jiffy:decode(Req, [return_maps]), PlayerID = maps:get(<<"pid">>, JSONReqMap), SessionToken = maps:get(<<"stk">>, JSONReqMap), - BattlemapInstanceID = maps:get(<<"bmi">>, JSONReqMap), + BattleID = maps:get(<<"bmi">>, JSONReqMap), #input { player_id = PlayerID, session_token = SessionToken, - battlemap_instance_id = BattlemapInstanceID + battle_id = BattleID }. -spec fetch_data (input()) -> query_state(). fetch_data (Input) -> PlayerID = Input#input.player_id, - BattlemapInstanceID = Input#input.battlemap_instance_id, + BattleID = Input#input.battle_id, - BattlemapInstance = + Battle = timed_cache:fetch ( - battlemap_instance_db, + battle_db, PlayerID, - BattlemapInstanceID + BattleID ), #query_state { - battlemap_instance = BattlemapInstance + battle = Battle }. -spec generate_reply(query_state(), input()) -> binary(). generate_reply (QueryState, Input) -> PlayerID = Input#input.player_id, - BattlemapInstance = QueryState#query_state.battlemap_instance, + Battle = QueryState#query_state.battle, jiffy:encode ( [ - set_map:generate(battlemap_instance:get_battlemap(BattlemapInstance)) + set_map:generate(battle:get_battlemap(Battle)) | array:sparse_to_list ( @@ -83,7 +83,7 @@ generate_reply (QueryState, Input) -> fun (IX, CharacterInstance) -> add_char:generate(IX, CharacterInstance, PlayerID) end, - battlemap_instance:get_character_instances(BattlemapInstance) + battle:get_character_instances(Battle) ) ) ] diff --git a/src/shim/database_shim.erl b/src/shim/database_shim.erl index 12d5bd5..e5afd2b 100644 --- a/src/shim/database_shim.erl +++ b/src/shim/database_shim.erl @@ -113,8 +113,8 @@ generate_db (Heir) -> Battlemap = battlemap:random(0, BattlemapWidth, BattlemapHeight), Characters = generate_random_characters(1, 8, 8, 0, []), PlayersAsList = [<<"0">>, <<"1">>], - BattlemapInstance = - battlemap_instance:random + Battle = + battle:random ( <<"0">>, PlayersAsList, @@ -122,7 +122,7 @@ generate_db (Heir) -> Characters ), - add_to_db({battlemap_instance_db, <<"0">>}, BattlemapInstance). + add_to_db({battle_db, <<"0">>}, Battle). -spec fetch (atom(), any()) -> ({'ok', any()} | 'nothing'). fetch (DB, ObjectID) -> diff --git a/src/struct/battlemap_instance.erl b/src/struct/battle.erl index c3b411b..bfa0e8d 100644 --- a/src/struct/battlemap_instance.erl +++ b/src/struct/battle.erl @@ -1,4 +1,4 @@ --module(battlemap_instance). +-module(battle). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -7,7 +7,7 @@ -record ( - battlemap_instance, + battle, { id :: id(), battlemap :: battlemap:struct(), @@ -18,7 +18,7 @@ } ). --opaque struct() :: #battlemap_instance{}. +-opaque struct() :: #battle{}. -export_type([struct/0, id/0]). @@ -32,12 +32,15 @@ get_id/1, get_battlemap/1, get_character_instances/1, + get_character_instance/2, get_player_ids/1, + get_player_id/2, get_current_player_turn/1, get_last_turns_effects/1, set_battlemap/2, set_character_instances/2, + set_character_instance/3, set_player_ids/2, set_current_player_turn/2, set_last_turns_effects/2 @@ -60,32 +63,41 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Accessors -spec get_id (struct()) -> id(). -get_id (BattlemapInstance) -> BattlemapInstance#battlemap_instance.id. +get_id (Battle) -> Battle#battle.id. -spec get_battlemap (struct()) -> battlemap:struct(). -get_battlemap (BattlemapInstance) -> - BattlemapInstance#battlemap_instance.battlemap. +get_battlemap (Battle) -> + Battle#battle.battlemap. -spec get_character_instances (struct()) -> array:array(character_instance:struct()). -get_character_instances (BattlemapInstance) -> - BattlemapInstance#battlemap_instance.character_instances. +get_character_instances (Battle) -> + Battle#battle.character_instances. + +-spec get_character_instance (non_neg_integer(), struct()) -> + character_instance:struct(). +get_character_instance (IX, Battle) -> + array:get(IX, Battle#battle.character_instances). -spec get_player_ids (struct()) -> array:array(player:id()). -get_player_ids (BattlemapInstance) -> - BattlemapInstance#battlemap_instance.player_ids. +get_player_ids (Battle) -> + Battle#battle.player_ids. + +-spec get_player_id (non_neg_integer(), struct()) -> player:id(). +get_player_id (IX, Battle) -> + array:get(IX, Battle#battle.player_ids). -spec get_current_player_turn (struct()) -> player_turn:struct(). -get_current_player_turn (BattlemapInstance) -> - BattlemapInstance#battlemap_instance.current_player_turn. +get_current_player_turn (Battle) -> + Battle#battle.current_player_turn. -spec get_last_turns_effects (struct()) -> list(any()). -get_last_turns_effects (BattlemapInstance) -> - BattlemapInstance#battlemap_instance.last_turns_effects. +get_last_turns_effects (Battle) -> + Battle#battle.last_turns_effects. -spec set_battlemap (battlemap:struct(), struct()) -> struct(). -set_battlemap (Battlemap, BattlemapInstance) -> - BattlemapInstance#battlemap_instance +set_battlemap (Battlemap, Battle) -> + Battle#battle { battlemap = Battlemap }. @@ -96,20 +108,39 @@ set_battlemap (Battlemap, BattlemapInstance) -> struct() ) -> struct(). -set_character_instances (CharacterInstances, BattlemapInstance) -> - BattlemapInstance#battlemap_instance +set_character_instances (CharacterInstances, Battle) -> + Battle#battle { character_instances = CharacterInstances }. +-spec set_character_instance + ( + non_neg_integer(), + character_instance:struct(), + struct() + ) + -> struct(). +set_character_instance (IX, CharacterInstance, Battle) -> + Battle#battle + { + character_instances = + array:set + ( + IX, + CharacterInstance, + Battle#battle.character_instances + ) + }. + -spec set_player_ids ( array:array(player:id()), struct() ) -> struct(). -set_player_ids (Players, BattlemapInstance) -> - BattlemapInstance#battlemap_instance +set_player_ids (Players, Battle) -> + Battle#battle { player_ids = Players }. @@ -120,8 +151,8 @@ set_player_ids (Players, BattlemapInstance) -> struct() ) -> struct(). -set_current_player_turn (PlayerTurn, BattlemapInstance) -> - BattlemapInstance#battlemap_instance +set_current_player_turn (PlayerTurn, Battle) -> + Battle#battle { current_player_turn = PlayerTurn }. @@ -132,8 +163,8 @@ set_current_player_turn (PlayerTurn, BattlemapInstance) -> struct() ) -> struct(). -set_last_turns_effects (Effects, BattlemapInstance) -> - BattlemapInstance#battlemap_instance +set_last_turns_effects (Effects, Battle) -> + Battle#battle { last_turns_effects = Effects }. @@ -185,7 +216,7 @@ random (ID, PlayersAsList, Battlemap, Characters) -> Characters ), - #battlemap_instance + #battle { id = ID, battlemap = Battlemap, diff --git a/src/struct/battle_action.erl b/src/struct/battle_action.erl index 7287a95..c1bccc7 100644 --- a/src/struct/battle_action.erl +++ b/src/struct/battle_action.erl @@ -22,7 +22,7 @@ ( attack, { - target :: non_neg_integer() + target_ix :: non_neg_integer() } ). @@ -57,18 +57,76 @@ decode_mov_action (JSONMap) -> decode_atk_action (JSONMap) -> TargetIX = maps:get(<<"tix">>, JSONMap), - #attack { target = TargetIX }. + #attack { target_ix = TargetIX }. -spec decode_swp_action (map()) -> struct(). decode_swp_action (_JSONMap) -> #switch_weapon{}. + +handle_attack_sequence +( + CharacterInstance, + TargetCharacterInstance, + AttackSequence +) -> + Character = character_instance:get_character(CharacterInstance), + TargetCharacter = character_instance:get_character(TargetCharacterInstance), + CharacterStatistics = character:get_statistics(Character), + TargetCharacterStatistics = character:get_statistics(TargetCharacter), + + AttackPlannedEffects = + lists:map + ( + fun (AttackStep) -> + attack:get_description_of + ( + AttackStep, + CharacterStatistics, + TargetCharacterStatistics + ) + end, + AttackSequence + ), + + lists:foldl + ( + fun + ( + AttackEffectCandidate, + {AttackValidEffects, AttackerHealth, DefenderHealth} + ) -> + {AttackResult, NewAttackerHealth, NewDefenderHealth} = + attack:apply_to_healths + ( + AttackEffectCandidate, + AttackerHealth, + DefenderHealth + ), + case AttackResult of + nothing -> {AttackValidEffects, AttackerHealth, DefenderHealth}; + _ -> + { + [AttackResult|AttackValidEffects], + NewAttackerHealth, + NewDefenderHealth + } + end + end, + { + [], + character_instance:get_current_health(CharacterInstance), + character_instance:get_current_health(TargetCharacterInstance) + }, + AttackPlannedEffects + ). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec decode (binary()) -> struct(). decode (EncodedAction) -> - JSONActionMap = jiffy:decode(EncodedAction, [return_maps]), + JSONActionMap = EncodedAction, %jiffy:decode(EncodedAction, [return_maps]), ActionType = maps:get(<<"t">>, JSONActionMap), case ActionType of <<"mov">> -> decode_mov_action(JSONActionMap); @@ -175,16 +233,13 @@ when is_record(BattleAction, move) -> ], UpdatedCharacterInstance, Battle - }. -handle (Battle, CharacterInstance, CharacterInstanceIX, BattleAction) + }; +handle (Battle, CharacterInstance, _CharacterInstanceIX, BattleAction) when is_record(BattleAction, attack) -> Character = character_instance:get_character(CharacterInstance), - CharacterStatistics = character:get_statistics(Character), - Battlemap = battle:get_battlemap(Battle), TargetIX = BattleAction#attack.target_ix, TargetCharacterInstance = battle:get_character_instance(TargetIX, Battle), TargetCharacter = character_instance:get_character(TargetCharacterInstance), - TargetCharacterStatistics = character:get_statistics(TargetCharacter), Range = location:dist @@ -202,54 +257,14 @@ when is_record(BattleAction, attack) -> AttackSequence = attack:get_sequence(Range, AttackingWeapon, DefendingWeapon), - AttackPlannedEffects = - lists:map + {AttackEffects, RemainingAttackerHealth, RemainingDefenderHealth} = + handle_attack_sequence ( - fun (AttackStep) -> - attack:get_description_of - ( - AttackStep, - CharacterStatistics, - TargetCharacterStatistics - ) - end, + CharacterInstance, + TargetCharacterInstance, AttackSequence ), - % FIXME: may warrant a separate function - {AttackEffects, RemainingAttakerHealth, RemainingDefenderHealth} = - lists:foldl - ( - fun - ( - AttackEffectCandidate, - {AttackValidEffects, AttackerHealth, DefenderHealth } - ) -> - {AttackResult, NewAttackerHealth, NewDefenderHealth} = - attack:apply_to_healths - ( - AttackPlannedEffect, - AttackerHealth, - DefenderHealth - ), - case AttackResult of - nothing -> {AttackValidEffects, AttackerHealth, DefenderHealth}; - _ -> - { - [AttackResult|AttackValidEffects], - NewAttackerHealth, - NewDefenderHealth - } - end, - end, - { - [], - character_instance:get_current_health(CharacterInstance), - character_instance:get_current_health(TargetCharacterInstance) - }, - AttackPlannedEffects - ), - UpdatedCharacterInstance = character_instance:set_current_health ( @@ -267,12 +282,12 @@ when is_record(BattleAction, attack) -> TargetCharacterInstance ), Battle - ) + ), { % TODO: hide that into database_diff structs. [], % TODO % TODO: hide that into turn_result structs. - AttackEffets, + AttackEffects, UpdatedCharacterInstance, UpdatedBattle }. |