From fde827cba1ff3d889135c74ee1978098465fd200 Mon Sep 17 00:00:00 2001 From: nsensfel Date: Wed, 11 Jul 2018 17:54:14 +0200 Subject: "Battlemap" -> "Battle". --- conf/yaws.conf.m4 | 4 +- src/battle/btl_handler.erl | 33 ++ src/battle/btl_shim.erl | 183 ++++++++++ src/battle/game-logic/btl_movement.erl | 60 ++++ src/battle/game-logic/btl_next_turn.erl | 160 +++++++++ src/battle/game-logic/btl_turn_actions.erl | 391 +++++++++++++++++++++ src/battle/game-logic/btl_victory.erl | 194 ++++++++++ src/battle/io/btl_security.erl | 33 ++ src/battle/query/btl_character_turn.erl | 282 +++++++++++++++ src/battle/query/btl_load_state.erl | 159 +++++++++ src/battle/reply/btl_add_armor.erl | 34 ++ src/battle/reply/btl_add_char.erl | 83 +++++ src/battle/reply/btl_add_tile.erl | 30 ++ src/battle/reply/btl_add_weapon.erl | 54 +++ src/battle/reply/btl_set_map.erl | 31 ++ src/battle/reply/btl_set_timeline.erl | 27 ++ src/battle/reply/btl_turn_results.erl | 27 ++ src/battle/struct/btl_attack.erl | 306 ++++++++++++++++ src/battle/struct/btl_battle.erl | 216 ++++++++++++ src/battle/struct/btl_battle_action.erl | 114 ++++++ src/battle/struct/btl_battlemap.erl | 100 ++++++ src/battle/struct/btl_character.erl | 290 +++++++++++++++ src/battle/struct/btl_character_turn_data.erl | 115 ++++++ src/battle/struct/btl_character_turn_request.erl | 84 +++++ src/battle/struct/btl_character_turn_update.erl | 85 +++++ src/battle/struct/btl_direction.erl | 38 ++ src/battle/struct/btl_location.erl | 90 +++++ src/battle/struct/btl_player.erl | 104 ++++++ src/battle/struct/btl_player_turn.erl | 106 ++++++ src/battle/struct/btl_tile.erl | 124 +++++++ src/battle/struct/btl_turn_result.erl | 215 +++++++++++ src/battlemap/bm_handler.erl | 33 -- src/battlemap/bm_shim.erl | 183 ---------- src/battlemap/game-logic/bm_movement.erl | 60 ---- src/battlemap/game-logic/bm_next_turn.erl | 160 --------- src/battlemap/game-logic/bm_turn_actions.erl | 391 --------------------- src/battlemap/game-logic/bm_victory.erl | 194 ---------- src/battlemap/io/bm_security.erl | 33 -- src/battlemap/query/bm_character_turn.erl | 282 --------------- src/battlemap/query/bm_load_state.erl | 159 --------- src/battlemap/reply/bm_add_armor.erl | 34 -- src/battlemap/reply/bm_add_char.erl | 83 ----- src/battlemap/reply/bm_add_tile.erl | 30 -- src/battlemap/reply/bm_add_weapon.erl | 54 --- src/battlemap/reply/bm_set_map.erl | 31 -- src/battlemap/reply/bm_set_timeline.erl | 27 -- src/battlemap/reply/bm_turn_results.erl | 27 -- src/battlemap/struct/bm_attack.erl | 306 ---------------- src/battlemap/struct/bm_battle.erl | 216 ------------ src/battlemap/struct/bm_battle_action.erl | 114 ------ src/battlemap/struct/bm_battlemap.erl | 100 ------ src/battlemap/struct/bm_character.erl | 290 --------------- src/battlemap/struct/bm_character_turn_data.erl | 115 ------ src/battlemap/struct/bm_character_turn_request.erl | 84 ----- src/battlemap/struct/bm_character_turn_update.erl | 85 ----- src/battlemap/struct/bm_direction.erl | 38 -- src/battlemap/struct/bm_location.erl | 90 ----- src/battlemap/struct/bm_player.erl | 104 ------ src/battlemap/struct/bm_player_turn.erl | 106 ------ src/battlemap/struct/bm_tile.erl | 124 ------- src/battlemap/struct/bm_turn_result.erl | 215 ----------- src/query/qry_handler.erl | 23 ++ 62 files changed, 3793 insertions(+), 3770 deletions(-) create mode 100644 src/battle/btl_handler.erl create mode 100644 src/battle/btl_shim.erl create mode 100644 src/battle/game-logic/btl_movement.erl create mode 100644 src/battle/game-logic/btl_next_turn.erl create mode 100644 src/battle/game-logic/btl_turn_actions.erl create mode 100644 src/battle/game-logic/btl_victory.erl create mode 100644 src/battle/io/btl_security.erl create mode 100644 src/battle/query/btl_character_turn.erl create mode 100644 src/battle/query/btl_load_state.erl create mode 100644 src/battle/reply/btl_add_armor.erl create mode 100644 src/battle/reply/btl_add_char.erl create mode 100644 src/battle/reply/btl_add_tile.erl create mode 100644 src/battle/reply/btl_add_weapon.erl create mode 100644 src/battle/reply/btl_set_map.erl create mode 100644 src/battle/reply/btl_set_timeline.erl create mode 100644 src/battle/reply/btl_turn_results.erl create mode 100644 src/battle/struct/btl_attack.erl create mode 100644 src/battle/struct/btl_battle.erl create mode 100644 src/battle/struct/btl_battle_action.erl create mode 100644 src/battle/struct/btl_battlemap.erl create mode 100644 src/battle/struct/btl_character.erl create mode 100644 src/battle/struct/btl_character_turn_data.erl create mode 100644 src/battle/struct/btl_character_turn_request.erl create mode 100644 src/battle/struct/btl_character_turn_update.erl create mode 100644 src/battle/struct/btl_direction.erl create mode 100644 src/battle/struct/btl_location.erl create mode 100644 src/battle/struct/btl_player.erl create mode 100644 src/battle/struct/btl_player_turn.erl create mode 100644 src/battle/struct/btl_tile.erl create mode 100644 src/battle/struct/btl_turn_result.erl delete mode 100644 src/battlemap/bm_handler.erl delete mode 100644 src/battlemap/bm_shim.erl delete mode 100644 src/battlemap/game-logic/bm_movement.erl delete mode 100644 src/battlemap/game-logic/bm_next_turn.erl delete mode 100644 src/battlemap/game-logic/bm_turn_actions.erl delete mode 100644 src/battlemap/game-logic/bm_victory.erl delete mode 100644 src/battlemap/io/bm_security.erl delete mode 100644 src/battlemap/query/bm_character_turn.erl delete mode 100644 src/battlemap/query/bm_load_state.erl delete mode 100644 src/battlemap/reply/bm_add_armor.erl delete mode 100644 src/battlemap/reply/bm_add_char.erl delete mode 100644 src/battlemap/reply/bm_add_tile.erl delete mode 100644 src/battlemap/reply/bm_add_weapon.erl delete mode 100644 src/battlemap/reply/bm_set_map.erl delete mode 100644 src/battlemap/reply/bm_set_timeline.erl delete mode 100644 src/battlemap/reply/bm_turn_results.erl delete mode 100644 src/battlemap/struct/bm_attack.erl delete mode 100644 src/battlemap/struct/bm_battle.erl delete mode 100644 src/battlemap/struct/bm_battle_action.erl delete mode 100644 src/battlemap/struct/bm_battlemap.erl delete mode 100644 src/battlemap/struct/bm_character.erl delete mode 100644 src/battlemap/struct/bm_character_turn_data.erl delete mode 100644 src/battlemap/struct/bm_character_turn_request.erl delete mode 100644 src/battlemap/struct/bm_character_turn_update.erl delete mode 100644 src/battlemap/struct/bm_direction.erl delete mode 100644 src/battlemap/struct/bm_location.erl delete mode 100644 src/battlemap/struct/bm_player.erl delete mode 100644 src/battlemap/struct/bm_player_turn.erl delete mode 100644 src/battlemap/struct/bm_tile.erl delete mode 100644 src/battlemap/struct/bm_turn_result.erl create mode 100644 src/query/qry_handler.erl diff --git a/conf/yaws.conf.m4 b/conf/yaws.conf.m4 index 3f5b36b..abd174e 100644 --- a/conf/yaws.conf.m4 +++ b/conf/yaws.conf.m4 @@ -110,6 +110,6 @@ keepalive_timeout = 30000 listen = 0.0.0.0 docroot = __MAKEFILE_WWW_DIR auth_log = true - appmods = bm_character_turn bm_load_state - start_mod = bm_handler + appmods = btl_character_turn btl_load_state + start_mod = qry_handler diff --git a/src/battle/btl_handler.erl b/src/battle/btl_handler.erl new file mode 100644 index 0000000..19b0e20 --- /dev/null +++ b/src/battle/btl_handler.erl @@ -0,0 +1,33 @@ +-module(btl_handler). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([start/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec start (pid()) -> 'ok'. +start (TimedCachesManagerPid) -> + case sh_database:fetch(battle_db, <<"0">>) of + {ok, _} -> ok; + not_found -> + sh_database:insert + ( + battle_db, + <<"0">>, + any, + btl_shim:generate_random_battle() + ) + end, + sh_timed_caches_manager:new_cache(TimedCachesManagerPid, battle_db, none), + ok. diff --git a/src/battle/btl_shim.erl b/src/battle/btl_shim.erl new file mode 100644 index 0000000..07d5854 --- /dev/null +++ b/src/battle/btl_shim.erl @@ -0,0 +1,183 @@ +-module(btl_shim). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate_random_battle/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-spec generate_random_characters + ( + non_neg_integer(), + non_neg_integer(), + non_neg_integer(), + non_neg_integer(), + btl_battlemap:type(), + list(btl_location:type()), + list(btl_character:type()) + ) + -> list(btl_character:type()). +generate_random_characters +( + 0, + 0, + _CharactersPerPlayer, + _TotalCharacterCount, + _Battlemap, + _ForbiddenLocations, + Result +) -> + Result; +generate_random_characters +( + MaxPlayerIX, + 0, + CharactersPerPlayer, + TotalCharacterCount, + Battlemap, + ForbiddenLocations, + Result +) -> + generate_random_characters + ( + (MaxPlayerIX - 1), + CharactersPerPlayer, + CharactersPerPlayer, + TotalCharacterCount, + Battlemap, + ForbiddenLocations, + Result + ); +generate_random_characters +( + MaxPlayerIX, + PlayerCharacterCount, + CharactersPerPlayer, + TotalCharacterCount, + Battlemap, + ForbiddenLocations, + Result +) -> + NewCharacter = + btl_character:random + ( + TotalCharacterCount, + MaxPlayerIX, + btl_battlemap:get_width(Battlemap), + btl_battlemap:get_height(Battlemap), + ForbiddenLocations + ), + Character = + case MaxPlayerIX of + 0 -> btl_character:set_is_active(true, NewCharacter); + _ -> NewCharacter + end, + + generate_random_characters + ( + MaxPlayerIX, + (PlayerCharacterCount - 1), + CharactersPerPlayer, + (TotalCharacterCount + 1), + Battlemap, + [btl_character:get_location(Character)|ForbiddenLocations], + [Character|Result] + ). +-spec demo_map () -> list(non_neg_integer()). +demo_map () -> + [ + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 2, + 2, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 2, + 2, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, + 2, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 1, 2, + 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 6, 6, 6, 6, 9, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 2, + 2, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 2, + 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 2, + 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 2, + 2, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, + 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 0, 0, 2, 1, 1, 0, 1, 2, + 2, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 0, 0, 4, 3, 3, 3, 3, 5, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 2, + 2, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 2, + 2, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,11, 7, 7, 7, 7,10, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 2, + 2, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 2, + 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 6, 6, 6, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0, 0, 0, 1, 2, + 2, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 0, 0, 0, 0, 1, 0, 2, + 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 0, 1, 1, 0, 2, 0, 2, + 2, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 1, 1, 0, 0, 0, 0, 2, + 2, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 0, 1, 1, 0, 1, 0, 2, + 2, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 8, 6, 6,16,15, 7, 7, 7, 7, 7, 7, 7,10, 0, 0, 1, 2, 0, 1, 0, 2, + 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 4, 3, 3, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, + 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 8,16, 3, 3, 3, 5, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 2, + 2, 1, 0, 1, 1, 0, 0, 0, 1, 1, 4, 3, 3, 3, 3, 5, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, + 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3,15, 7, 7,10, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 0, 1, 2, + 2, 0, 0, 1, 0, 1, 0, 1, 0, 1, 4, 3, 5, 8, 6, 6, 9, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 1, 2, + 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3,17,16, 3, 3, 5, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 2, + 2, 0, 0, 1, 0, 0, 1, 1, 0, 1, 4, 3,15, 7, 7, 7,10, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, 1, 2, + 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 4, 3, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2, + 2, 1, 1, 1, 0, 1, 0, 1, 0, 1, 4, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 2, + 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,16, 3,17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 + ]. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate_random_battle () -> btl_battle:type(). +generate_random_battle () -> + %BattlemapWidth = 32, % sh_roll:between(16, 32), + %BattlemapHeight = 32, %sh_roll:between(16, 32), + %Battlemap = btl_battlemap:random(0, BattlemapWidth, BattlemapHeight), + Battlemap = btl_battlemap:from_list(0, 32, 32, demo_map()), + Characters = generate_random_characters(1, 8, 8, 0, Battlemap, [], []), + PlayersAsList = [btl_player:new(0, 8, <<"0">>), btl_player:new(1, 0, <<"1">>)], + + {UsedWeaponIDs, UsedArmorIDs} = + lists:foldl + ( + fun (Character, {UWIDs, UAIDs}) -> + {MWpID, SWpID} = btl_character:get_weapon_ids(Character), + AID = btl_character:get_armor_id(Character), + { + sets:add_element(MWpID, sets:add_element(SWpID, UWIDs)), + sets:add_element(AID, UAIDs) + } + end, + {sets:new(), sets:new()}, + Characters + ), + + UsedTileIDs = + array:sparse_foldl + ( + fun (_IX, TileClassID, CurrentTileIDs) -> + sets:add_element + ( + btl_tile:class_id_to_type_id(TileClassID), + CurrentTileIDs + ) + end, + sets:new(), + btl_battlemap:get_tile_class_ids(Battlemap) + ), + + Battle = + btl_battle:new + ( + <<"0">>, + PlayersAsList, + Battlemap, + Characters, + sets:to_list(UsedWeaponIDs), + sets:to_list(UsedArmorIDs), + sets:to_list(UsedTileIDs) + ), + + Battle. diff --git a/src/battle/game-logic/btl_movement.erl b/src/battle/game-logic/btl_movement.erl new file mode 100644 index 0000000..87b1806 --- /dev/null +++ b/src/battle/game-logic/btl_movement.erl @@ -0,0 +1,60 @@ +-module(btl_movement). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([cross/4]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec cross + ( + btl_battlemap:type(), + list(btl_location:type()), + list(btl_direction:enum()), + non_neg_integer(), + btl_location:type() + ) + -> {btl_location:type(), non_neg_integer()}. +cross (_Battlemap, _ForbiddenLocations, [], Cost, Location) -> + {Location, Cost}; +cross (Battlemap, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> + NextLocation = btl_location:apply_direction(Step, Location), + NextTileClassID = btl_battlemap:get_tile_class_id(NextLocation, Battlemap), + NextTileID = btl_tile:class_id_to_type_id(NextTileClassID), + NextTile = btl_tile:from_id(NextTileID), + NextCost = (Cost + btl_tile:get_cost(NextTile)), + IsForbidden = + lists:foldl + ( + fun (ForbiddenLocation, Prev) -> + (Prev or (NextLocation == ForbiddenLocation)) + end, + false, + ForbiddenLocations + ), + + IsForbidden = false, + + cross(Battlemap, ForbiddenLocations, NextSteps, NextCost, NextLocation). + +-spec cross + ( + btl_battlemap:type(), + list(btl_location:type()), + list(btl_direction:enum()), + btl_location:type() + ) + -> {btl_location:type(), non_neg_integer()}. +cross (Battlemap, ForbiddenLocations, Path, Location) -> + cross(Battlemap, ForbiddenLocations, Path, 0, Location). diff --git a/src/battle/game-logic/btl_next_turn.erl b/src/battle/game-logic/btl_next_turn.erl new file mode 100644 index 0000000..82eec98 --- /dev/null +++ b/src/battle/game-logic/btl_next_turn.erl @@ -0,0 +1,160 @@ +-module(btl_next_turn). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + update_if_needed/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec set_player_turn_to_next (btl_battle:type()) + -> {btl_battle:type(), sh_db_query:op()}. +set_player_turn_to_next (Battle) -> + Players = btl_battle:get_players(Battle), + CurrentPlayerTurn = btl_battle:get_current_player_turn(Battle), + + NextPlayerTurn = btl_player_turn:next(Players, CurrentPlayerTurn), + + UpdatedBattle = btl_battle:set_current_player_turn(NextPlayerTurn, Battle), + + DBQuery = + sh_db_query:set_field + ( + btl_battle:get_current_player_turn_field(), + NextPlayerTurn + ), + + {UpdatedBattle, DBQuery}. + +-spec reset_next_player_timeline (btl_battle:type()) + -> {btl_battle:type(), btl_player:type(), sh_db_query:op()}. +reset_next_player_timeline (Battle) -> + NextPlayerTurn = btl_battle:get_current_player_turn(Battle), + NextPlayerIX = btl_player_turn:get_player_ix(NextPlayerTurn), + NextPlayer = btl_battle:get_player(NextPlayerIX, Battle), + + UpdatedNextPlayer = btl_player:reset_timeline(NextPlayer), + UpdatedBattle = + btl_battle:set_player(NextPlayerIX, UpdatedNextPlayer, Battle), + + DBQuery = + sh_db_query:update_indexed + ( + btl_battle:get_players_field(), + NextPlayerIX, + [ sh_db_query:set_field(btl_player:get_timeline_field(), []) ] + ), + + {UpdatedBattle, UpdatedNextPlayer, DBQuery}. + + +-spec activate_next_players_characters (btl_battle:type(), btl_player:type()) + -> {btl_battle:type(), list(sh_db_query:op())}. +activate_next_players_characters (Battle, NextPlayer) -> + NextPlayerIX = btl_player:get_index(NextPlayer), + Characters = btl_battle:get_characters(Battle), + + {UpdatedCharacters, ModifiedIXs} = + sh_array_util:mapiff + ( + fun (Character) -> + (btl_character:get_player_index(Character) == NextPlayerIX) + end, + fun (Character) -> + btl_character:set_is_active(true, Character) + end, + Characters + ), + + DBQueries = + lists:map + ( + fun (IX) -> + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + IX, + [ + sh_db_query:set_field + ( + btl_character:get_is_active_field(), + true + ) + ] + ) + end, + ModifiedIXs + ), + + UpdatedBattle = btl_battle:set_characters(UpdatedCharacters, Battle), + + {UpdatedBattle, DBQueries}. + +-spec update + ( + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +update (Update) -> + Data = btl_character_turn_update:get_data(Update), + Battle = btl_character_turn_data:get_battle(Data), + + {S0Battle, DBQuery0} = set_player_turn_to_next(Battle), + {S1Battle, NextPlayer, DBQuery1} = reset_next_player_timeline(S0Battle), + {S2Battle, DBQueries} = + activate_next_players_characters(S1Battle, NextPlayer), + + S0Data = btl_character_turn_data:set_battle(S2Battle, Data), + S0Update = + btl_character_turn_update:add_to_timeline + ( + btl_turn_result:new_player_turn_started + ( + btl_player:get_index(NextPlayer) + ), + DBQuery0, + Update + ), + + S1Update = btl_character_turn_update:set_data(S0Data, S0Update), + + S2Update = + lists:foldl + ( + fun btl_character_turn_update:add_to_db/2, + S1Update, + [DBQuery1|DBQueries] + ), + + S2Update. + +-spec requires_update (btl_character_turn_update:type()) -> boolean(). +requires_update (Update) -> + Data = btl_character_turn_update:get_data(Update), + Battle = btl_character_turn_data:get_battle(Data), + Characters = btl_battle:get_characters(Battle), + + sh_array_util:none(fun btl_character:get_is_active/1, Characters). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec update_if_needed + ( + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +update_if_needed (Update) -> + case requires_update(Update) of + true -> update(Update); + _ -> Update + end. diff --git a/src/battle/game-logic/btl_turn_actions.erl b/src/battle/game-logic/btl_turn_actions.erl new file mode 100644 index 0000000..21205ac --- /dev/null +++ b/src/battle/game-logic/btl_turn_actions.erl @@ -0,0 +1,391 @@ +-module(btl_turn_actions). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + handle/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%% SWITCHING WEAPON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec handle_switch_weapon + ( + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +handle_switch_weapon (Update) -> + Data = btl_character_turn_update:get_data(Update), + Character = btl_character_turn_data:get_character(Data), + CharacterIX = btl_character_turn_data:get_character_ix(Data), + CharacterAttributes = btl_character:get_attributes(Character), + ArmorID = btl_character:get_armor_id(Character), + {PrimaryWeaponID, SecondaryWeaponID} = btl_character:get_weapon_ids(Character), + + UpdatedWeaponIDs = {SecondaryWeaponID, PrimaryWeaponID}, + UpdatedCharacterStatistics = + sh_statistics:new(CharacterAttributes, UpdatedWeaponIDs, ArmorID), + UpdatedCharacter = + btl_character:set_statistics + ( + UpdatedCharacterStatistics, + btl_character:set_weapon_ids(UpdatedWeaponIDs, Character) + ), + + TimelineItem = btl_turn_result:new_character_switched_weapons(CharacterIX), + + DBQuery = + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + CharacterIX, + [ + sh_db_query:set_field + ( + btl_character:get_weapons_field(), + UpdatedWeaponIDs + ), + sh_db_query:set_field + ( + btl_character:get_statistics_field(), + UpdatedCharacterStatistics + ) + ] + ), + + UpdatedData = btl_character_turn_data:set_character(UpdatedCharacter, Data), + + S0Update = btl_character_turn_update:set_data(UpdatedData, Update), + + btl_character_turn_update:add_to_timeline(TimelineItem, DBQuery, S0Update). + +%%%% MOVING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_path_cost_and_destination + ( + btl_character_turn_data:type(), + list(btl_direction:type()) + ) + -> {non_neg_integer(), btl_location:type()}. +get_path_cost_and_destination (Data, Path) -> + Character = btl_character_turn_data:get_character(Data), + CharacterIX = btl_character_turn_data:get_character_ix(Data), + Battle = btl_character_turn_data:get_battle(Data), + Battlemap = btl_battle:get_battlemap(Battle), + + ForbiddenLocations = + array:foldl + ( + fun (IX, Char, Prev) -> + IsAlive = btl_character:get_is_alive(Char), + if + (IX == CharacterIX) -> Prev; + (not IsAlive) -> Prev; + true -> [btl_character:get_location(Char)|Prev] + end + end, + [], + btl_battle:get_characters(Battle) + ), + + {NewLocation, Cost} = + btl_movement:cross + ( + Battlemap, + ForbiddenLocations, + Path, + btl_character:get_location(Character) + ), + + {Cost, NewLocation}. + +-spec assert_character_can_move + ( + btl_character_turn_data:type(), + non_neg_integer() + ) + -> 'ok'. +assert_character_can_move (Data, Cost) -> + Character = btl_character_turn_data:get_character(Data), + CharacterStatistics = btl_character:get_statistics(Character), + CharacterMovementPoints = + sh_statistics:get_movement_points(CharacterStatistics), + + true = (Cost =< CharacterMovementPoints), + + ok. + +-spec commit_move + ( + btl_character_turn_update:type(), + list(btl_direction:type()), + btl_location:type() + ) + -> btl_character_turn_update:type(). +commit_move (Update, Path, NewLocation) -> + Data = btl_character_turn_update:get_data(Update), + Character = btl_character_turn_data:get_character(Data), + CharacterIX = btl_character_turn_data:get_character_ix(Data), + + UpdatedCharacter = btl_character:set_location(NewLocation, Character), + + UpdatedData = btl_character_turn_data:set_character(UpdatedCharacter, Data), + + TimelineItem = + btl_turn_result:new_character_moved(CharacterIX, Path, NewLocation), + + DBQuery = + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + CharacterIX, + [ + sh_db_query:set_field + ( + btl_character:get_location_field(), + NewLocation + ) + ] + ), + + S0Update = + btl_character_turn_update:add_to_timeline + ( + TimelineItem, + DBQuery, + Update + ), + + btl_character_turn_update:set_data(UpdatedData, S0Update). + +-spec handle_move + ( + btl_battle_action:type(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +handle_move (BattleAction, Update) -> + Data = btl_character_turn_update:get_data(Update), + Path = btl_battle_action:get_path(BattleAction), + + {PathCost, NewLocation} = get_path_cost_and_destination(Data, Path), + assert_character_can_move(Data, PathCost), + + commit_move(Update, Path, NewLocation). + +%%%% ATTACKING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec handle_attack_sequence + ( + btl_character:type(), + btl_character:type(), + list(btl_attack:step()) + ) + -> {list(btl_attack:type()), non_neg_integer(), non_neg_integer()}. +handle_attack_sequence +( + Character, + TargetCharacter, + AttackSequence +) -> + AttackPlannedEffects = + lists:map + ( + fun (AttackStep) -> + btl_attack:get_description_of + ( + AttackStep, + Character, + TargetCharacter + ) + end, + AttackSequence + ), + + lists:foldl + ( + fun + ( + AttackEffectCandidate, + {AttackValidEffects, AttackerHealth, DefenderHealth} + ) -> + {AttackResult, NewAttackerHealth, NewDefenderHealth} = + btl_attack:apply_to_healths + ( + AttackEffectCandidate, + AttackerHealth, + DefenderHealth + ), + case AttackResult of + nothing -> {AttackValidEffects, AttackerHealth, DefenderHealth}; + _ -> + { + (AttackValidEffects ++ [AttackResult]), + NewAttackerHealth, + NewDefenderHealth + } + end + end, + { + [], + btl_character:get_current_health(Character), + btl_character:get_current_health(TargetCharacter) + }, + AttackPlannedEffects + ). + +-spec get_attack_sequence + ( + btl_character:type(), + btl_character:type() + ) + -> list(btl_attack:step()). +get_attack_sequence (Character, TargetCharacter) -> + Range = + btl_location:dist + ( + btl_character:get_location(Character), + btl_character:get_location(TargetCharacter) + ), + + {AttackingWeaponID, _} = btl_character:get_weapon_ids(Character), + {DefendingWeaponID, _} = btl_character:get_weapon_ids(TargetCharacter), + + AttackingWeapon = sh_weapon:from_id(AttackingWeaponID), + DefendingWeapon = sh_weapon:from_id(DefendingWeaponID), + + btl_attack:get_sequence(Range, AttackingWeapon, DefendingWeapon). + + +-spec handle_attack + ( + btl_battle_action:type(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +handle_attack (BattleAction, Update) -> + Data = btl_character_turn_update:get_data(Update), + Battle = btl_character_turn_data:get_battle(Data), + Character = btl_character_turn_data:get_character(Data), + CharacterIX = btl_character_turn_data:get_character_ix(Data), + TargetIX = btl_battle_action:get_target_ix(BattleAction), + TargetCharacter = btl_battle:get_character(TargetIX, Battle), + + true = btl_character:get_is_alive(TargetCharacter), + + AttackSequence = get_attack_sequence(Character, TargetCharacter), + + {AttackEffects, RemainingAttackerHealth, RemainingDefenderHealth} = + handle_attack_sequence(Character, TargetCharacter, AttackSequence), + + UpdatedCharacter = + btl_character:set_current_health(RemainingAttackerHealth, Character), + + UpdatedBattle = + btl_battle:set_character + ( + TargetIX, + btl_character:set_current_health + ( + RemainingDefenderHealth, + TargetCharacter + ), + Battle + ), + + S0Data = btl_character_turn_data:set_battle(UpdatedBattle, Data), + S1Data = btl_character_turn_data:set_character(UpdatedCharacter, S0Data), + + TimelineItem = + btl_turn_result:new_character_attacked + ( + CharacterIX, + TargetIX, + AttackEffects + ), + + DBQuery0 = + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + TargetIX, + [ + sh_db_query:set_field + ( + btl_character:get_current_health_field(), + RemainingDefenderHealth + ) + ] + ), + + DBQuery1 = + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + CharacterIX, + [ + sh_db_query:set_field + ( + btl_character:get_current_health_field(), + RemainingAttackerHealth + ) + ] + ), + + S0Update = + btl_character_turn_update:add_to_timeline + ( + TimelineItem, + DBQuery0, + Update + ), + + S1Update = + btl_character_turn_update:add_to_db + ( + DBQuery1, + S0Update + ), + + S2Update = btl_character_turn_update:set_data(S1Data, S1Update), + + S3Update = + btl_victory:handle_character_lost_health + ( + CharacterIX, + RemainingAttackerHealth, + S2Update + ), + + S4Update = + btl_victory:handle_character_lost_health + ( + TargetIX, + RemainingDefenderHealth, + S3Update + ), + + S4Update. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec handle +( + btl_battle_action:type(), + btl_character_turn_update:type() +) +-> btl_character_turn_update:type(). +handle (BattleAction, Update) -> + case btl_battle_action:get_category(BattleAction) of + move -> handle_move(BattleAction, Update); + switch_weapon -> handle_switch_weapon(Update); + attack -> handle_attack(BattleAction, Update) + end. diff --git a/src/battle/game-logic/btl_victory.erl b/src/battle/game-logic/btl_victory.erl new file mode 100644 index 0000000..eef42ad --- /dev/null +++ b/src/battle/game-logic/btl_victory.erl @@ -0,0 +1,194 @@ +-module(btl_victory). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + handle_character_lost_health/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-spec mark_players_characters_as_defeated + ( + non_neg_integer(), + array:array(btl_character:type()) + ) -> {array:array(btl_character:type()), list(non_neg_integer())}. +mark_players_characters_as_defeated (PlayerIX, Characters) -> + sh_array_util:mapiff + ( + fun (Character) -> + (btl_character:get_player_index(Character) == PlayerIX) + end, + fun (Character) -> + btl_character:set_is_defeated(true, Character) + end, + Characters + ). + +-spec add_db_query_to_mark_character_as_defeated + ( + non_neg_integer(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +add_db_query_to_mark_character_as_defeated (IX, Update) -> + btl_character_turn_update:add_to_db + ( + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + IX, + [ + sh_db_query:set_field + ( + btl_character:get_is_defeated_field(), + true + ) + ] + ), + Update + ). + +-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), + Characters = btl_battle:get_characters(Battle), + + %% FIXME: The controlled character might slip through. + {UpdatedCharacters, ModifiedIXs} = + mark_players_characters_as_defeated(PlayerIX, Characters), + + S1Update = + lists:foldl + ( + fun add_db_query_to_mark_character_as_defeated/2, + Update, + ModifiedIXs + ), + + %% TODO: Battle.player[PlayerIX].is_active <- false + + UpdatedBattle = btl_battle:set_characters(UpdatedCharacters, Battle), + UpdatedData = btl_character_turn_data:set_battle(UpdatedBattle, Data), + S2Update = btl_character_turn_update:set_data(UpdatedData, S1Update), + + DBQuery = + sh_db_query:update_indexed + ( + btl_battle:get_players_field(), + PlayerIX, + [ + sh_db_query:set_field + ( + btl_player:get_is_active_field(), + false + ) + ] + ), + + S3Update = + btl_character_turn_update:add_to_timeline + ( + btl_turn_result:new_player_lost(PlayerIX), + DBQuery, + S2Update + ), + + S3Update. + + +-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 + StillHasAliveChar = + sh_array_util:any_indexed + ( + fun (IX, Char) -> + ( + (CharacterPlayerIX == btl_character:get_player_index(Char)) + and (IX /= CharIX) + and btl_character:get_is_alive(Char) + ) + end, + 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 == btl_character:get_player_index(Char)) + and (IX /= CharIX) + and btl_character:get_is_alive(Char) + and (btl_character:get_rank(Char) == target) + ) + end, + Characters + ), + + case StillHasAliveChar 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. diff --git a/src/battle/io/btl_security.erl b/src/battle/io/btl_security.erl new file mode 100644 index 0000000..cf6bb9b --- /dev/null +++ b/src/battle/io/btl_security.erl @@ -0,0 +1,33 @@ +-module(btl_security). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + assert_identity/2, + lock_queries/1, + unlock_queries/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec assert_identity (any(), any()) -> 'unimplemented'. +assert_identity (_PlayerID, _SessionToken) -> unimplemented. + +-spec lock_queries (any()) -> 'unimplemented'. +lock_queries (_PlayerID) -> unimplemented. + +-spec unlock_queries (any()) -> 'unimplemented'. +unlock_queries (_PlayerID) -> unimplemented. diff --git a/src/battle/query/btl_character_turn.erl b/src/battle/query/btl_character_turn.erl new file mode 100644 index 0000000..c232ab0 --- /dev/null +++ b/src/battle/query/btl_character_turn.erl @@ -0,0 +1,282 @@ +-module(btl_character_turn). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../../include/yaws_api.hrl"). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([out/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%-spec send_to_database (list(database_diff:type()), character_turn_request:type()) -> 'ok'. + + +%%%% REQUEST DECODING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec decode_request (binary()) -> btl_character_turn_request:type(). +decode_request (BinaryRequest) -> + JSONMap = jiffy:decode(BinaryRequest, [return_maps]), + + btl_character_turn_request:decode(JSONMap). + +%%%% USER AUTHENTICATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec authenticate_user (btl_character_turn_request:type()) -> 'ok'. +authenticate_user (Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + SessionToken = btl_character_turn_request:get_session_token(Request), + + btl_security:assert_identity(PlayerID, SessionToken), + btl_security:lock_queries(PlayerID), + + ok. + +%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec fetch_data + ( + btl_character_turn_request:type() + ) + -> btl_character_turn_data:type(). +fetch_data (Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + BattleID = btl_character_turn_request:get_battle_id(Request), + CharacterIX = btl_character_turn_request:get_character_ix(Request), + Battle = sh_timed_cache:fetch(battle_db, PlayerID, BattleID), + + btl_character_turn_data:new(Battle, CharacterIX). + +%%%% ASSERTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec assert_user_is_current_player + ( + btl_character_turn_data:type(), + btl_character_turn_request:type() + ) -> 'ok'. +assert_user_is_current_player (Data, Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + Battle = btl_character_turn_data:get_battle(Data), + CurrentPlayerTurn = btl_battle:get_current_player_turn(Battle), + CurrentPlayerIX = btl_player_turn:get_player_ix(CurrentPlayerTurn), + CurrentPlayer = btl_battle:get_player(CurrentPlayerIX, Battle), + + true = (PlayerID == btl_player:get_id(CurrentPlayer)), + + ok. + +-spec assert_user_owns_played_character + ( + btl_character_turn_data:type(), + btl_character_turn_request:type() + ) -> 'ok'. +assert_user_owns_played_character (Data, Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + Battle = btl_character_turn_data:get_battle(Data), + Players = btl_battle:get_players(Battle), + Character = btl_character_turn_data:get_character(Data), + CharacterPlayerIX = btl_character:get_player_index(Character), + CharacterPlayer = array:get(CharacterPlayerIX, Players), + CharacterPlayerID = btl_player:get_id(CharacterPlayer), + + true = (PlayerID == CharacterPlayerID), + + ok. + +-spec assert_character_can_be_played (btl_character_turn_data:type()) -> 'ok'. +assert_character_can_be_played (Data) -> + Character = btl_character_turn_data:get_character(Data), + + true = btl_character:get_is_active(Character), + + ok. + +-spec assert_user_permissions + ( + btl_character_turn_data:type(), + btl_character_turn_request:type() + ) -> 'ok'. +assert_user_permissions (Data, Request) -> + assert_user_is_current_player(Data, Request), + assert_user_owns_played_character(Data, Request), + assert_character_can_be_played(Data), + + ok. + +%%%% QUERY LOGIC HANDLING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec finalize_character + ( + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +finalize_character (Update) -> + Data = btl_character_turn_update:get_data(Update), + Character = btl_character_turn_data:get_character(Data), + + DisabledCharacter = btl_character:set_is_active(false, Character), + UpdatedData = btl_character_turn_data:set_character(DisabledCharacter, Data), + FinalizedData = btl_character_turn_data:clean_battle(UpdatedData), + + DBQuery = + sh_db_query:update_indexed + ( + btl_battle:get_characters_field(), + btl_character_turn_data:get_character_ix(Data), + [ sh_db_query:set_field(btl_character:get_is_active_field(), false) ] + ), + + S0Update = btl_character_turn_update:set_data(FinalizedData, Update), + S1Update = btl_character_turn_update:add_to_db(DBQuery, S0Update), + + S1Update. + +-spec handle_actions + ( + btl_character_turn_data:type(), + btl_character_turn_request:type() + ) + -> btl_character_turn_update:type(). +handle_actions (Data, Request) -> + Actions = btl_character_turn_request:get_actions(Request), + + EmptyUpdate = btl_character_turn_update:new(Data), + PostActionsUpdate = + lists:foldl(fun btl_turn_actions:handle/2, EmptyUpdate, Actions), + + finalize_character(PostActionsUpdate). + +-spec update_timeline + ( + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +update_timeline (Update) -> + NewTimelineElements = btl_character_turn_update:get_timeline(Update), + Data = btl_character_turn_update:get_data(Update), + Battle = btl_character_turn_data:get_battle(Data), + PlayerTurn = btl_battle:get_current_player_turn(Battle), + PlayerIX = btl_player_turn:get_player_ix(PlayerTurn), + Player = btl_battle:get_player(PlayerIX, Battle), + + UpdatedPlayer = btl_player:add_to_timeline(NewTimelineElements, Player), + UpdatedBattle = btl_battle:set_player(PlayerIX, UpdatedPlayer, Battle), + UpdatedData = btl_character_turn_data:set_battle(UpdatedBattle, Data), + + DBQuery = + sh_db_query:update_indexed + ( + btl_battle:get_players_field(), + PlayerIX, + [ + sh_db_query:add_to_field + ( + btl_player:get_timeline_field(), + NewTimelineElements, + true % We add those to the start of the list + ) + ] + ), + + S0Update = btl_character_turn_update:set_data(UpdatedData, Update), + S1Update = btl_character_turn_update:add_to_db(DBQuery, S0Update), + + S1Update. + + +-spec update_data + ( + btl_character_turn_data:type(), + btl_character_turn_request:type() + ) + -> btl_character_turn_update:type(). +update_data (Data, Request) -> + PostActionsUpdate = handle_actions(Data, Request), + PostCharacterTurnUpdate = update_timeline(PostActionsUpdate), + + btl_next_turn:update_if_needed(PostCharacterTurnUpdate). + +%%%% DATABASE UPDATES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec send_to_database + ( + btl_character_turn_update:type(), + btl_character_turn_request:type() + ) + -> 'ok'. +send_to_database (Update, Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + BattleID = btl_character_turn_request:get_battle_id(Request), + Ops = btl_character_turn_update:get_db(Update), + Query = sh_db_query:new(battle_db, BattleID, {user, PlayerID}, Ops), + + sh_database:commit(Query), + + ok. + +-spec send_to_cache + ( + btl_character_turn_update:type(), + btl_character_turn_request:type() + ) + -> 'ok'. +send_to_cache (Update, Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + BattleID = btl_character_turn_request:get_battle_id(Request), + Data = btl_character_turn_update:get_data(Update), + Battle = btl_character_turn_data:get_battle(Data), + + sh_timed_cache:update(battle_db, PlayerID, BattleID, Battle), + + ok. + +-spec commit_update + ( + btl_character_turn_update:type(), + btl_character_turn_request:type() + ) + -> 'ok'. +commit_update (Update, Request) -> + send_to_database(Update, Request), + send_to_cache(Update, Request), + + ok. + +%%%% USER DISCONNECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec disconnect_user (btl_character_turn_request:type()) -> 'ok'. +disconnect_user (Request) -> + PlayerID = btl_character_turn_request:get_player_id(Request), + + btl_security:unlock_queries(PlayerID), + + ok. + +%%%% REPLY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate_reply (btl_character_turn_update:type()) -> binary(). +generate_reply (Update) -> + NewTimelineItems = btl_character_turn_update:get_timeline(Update), + + TurnResultReply = btl_turn_results:generate(NewTimelineItems), + + jiffy:encode([TurnResultReply]). + +%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec handle (binary()) -> binary(). +handle (EncodedRequest) -> + Request = decode_request(EncodedRequest), + authenticate_user(Request), + Data = fetch_data(Request), + assert_user_permissions(Data, Request), + Update = update_data(Data, Request), + commit_update(Update, Request), + disconnect_user(Request), + generate_reply(Update). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/battle/query/btl_load_state.erl b/src/battle/query/btl_load_state.erl new file mode 100644 index 0000000..f79e24e --- /dev/null +++ b/src/battle/query/btl_load_state.erl @@ -0,0 +1,159 @@ +-module(btl_load_state). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../../include/yaws_api.hrl"). + +-record +( + input, + { + player_id :: btl_player:id(), + session_token :: binary(), + battle_id :: binary() + } +). + +-record +( + query_state, + { + battle :: btl_battle:type() + } +). + +-type input() :: #input{}. +-type query_state() :: #query_state{}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([out/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec parse_input (binary()) -> input(). +parse_input (Req) -> + JSONReqMap = jiffy:decode(Req, [return_maps]), + PlayerID = maps:get(<<"pid">>, JSONReqMap), + SessionToken = maps:get(<<"stk">>, JSONReqMap), + BattleID = maps:get(<<"bid">>, JSONReqMap), + + #input + { + player_id = PlayerID, + session_token = SessionToken, + battle_id = BattleID + }. + +-spec fetch_data (input()) -> query_state(). +fetch_data (Input) -> + PlayerID = Input#input.player_id, + BattleID = Input#input.battle_id, + + Battle = sh_timed_cache:fetch(battle_db, PlayerID, BattleID), + + #query_state + { + battle = Battle + }. + +-spec generate_reply(query_state(), input()) -> binary(). +generate_reply (QueryState, Input) -> + PlayerID = Input#input.player_id, + Battle = QueryState#query_state.battle, + Players = btl_battle:get_players(Battle), + + PlayerIX = + sh_array_util:first + ( + fun (Player) -> + (btl_player:get_id(Player) == PlayerID) + end, + Players + ), + + true = (PlayerIX >= 0), + + SetTimeline = + btl_set_timeline:generate + ( + btl_battle:get_encoded_last_turns_effects(Battle) + ), + + SetMap = btl_set_map:generate(btl_battle:get_battlemap(Battle)), + + AddCharList = + array:sparse_to_list + ( + array:map + ( + fun (IX, Character) -> + btl_add_char:generate(IX, Character, PlayerIX) + end, + btl_battle:get_characters(Battle) + ) + ), + + AddWeaponList = + lists:map + ( + fun (WeaponID) -> + btl_add_weapon:generate(sh_weapon:from_id(WeaponID)) + end, + btl_battle:get_used_weapon_ids(Battle) + ), + + AddArmorList = + lists:map + ( + fun (ArmorID) -> + btl_add_armor:generate(sh_armor:from_id(ArmorID)) + end, + btl_battle:get_used_armor_ids(Battle) + ), + + AddTileList = + lists:map + ( + fun (TileID) -> + btl_add_tile:generate(btl_tile:from_id(TileID)) + end, + btl_battle:get_used_tile_ids(Battle) + ), + + OutputList = + ( + AddTileList + ++ [SetTimeline, SetMap | AddWeaponList] + ++ AddArmorList + ++ AddCharList + ), + Output = jiffy:encode(OutputList), + + Output. + +-spec handle (binary()) -> binary(). +handle (Req) -> + Input = parse_input(Req), + btl_security:assert_identity + ( + Input#input.player_id, + Input#input.session_token + ), + btl_security:lock_queries(Input#input.player_id), + QueryState = fetch_data(Input), + btl_security:unlock_queries(Input#input.player_id), + generate_reply(QueryState, Input). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/battle/reply/btl_add_armor.erl b/src/battle/reply/btl_add_armor.erl new file mode 100644 index 0000000..2c6a875 --- /dev/null +++ b/src/battle/reply/btl_add_armor.erl @@ -0,0 +1,34 @@ +-module(btl_add_armor). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec encode_category (sh_armor:category()) -> binary(). +encode_category (kinetic) -> <<"k">>; +encode_category (leather) -> <<"l">>; +encode_category (chain) -> <<"c">>; +encode_category (plate) -> <<"p">>. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (sh_armor:type()) -> {list(any())}. +generate (Armor) -> + { + [ + {<<"msg">>, <<"add_armor">>}, + {<<"id">>, sh_armor:get_id(Armor)}, + {<<"nam">>, sh_armor:get_name(Armor)}, + {<<"ct">>, encode_category(sh_armor:get_category(Armor))}, + {<<"cf">>, sh_armor:get_coefficient(Armor)} + ] + }. diff --git a/src/battle/reply/btl_add_char.erl b/src/battle/reply/btl_add_char.erl new file mode 100644 index 0000000..75b6fcd --- /dev/null +++ b/src/battle/reply/btl_add_char.erl @@ -0,0 +1,83 @@ +-module(btl_add_char). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/3]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec rank_to_string (btl_character:rank()) -> binary(). +rank_to_string (Rank) -> + case Rank of + optional -> <<"o">>; + target -> <<"t">>; + commander -> <<"c">> + end. + +-spec attributes_as_json + ( + sh_attributes:type() + ) -> + {list({binary(), non_neg_integer()})}. +attributes_as_json (Attributes) -> + { + [ + {<<"con">>, sh_attributes:get_constitution(Attributes)}, + {<<"dex">>, sh_attributes:get_dexterity(Attributes)}, + {<<"int">>, sh_attributes:get_intelligence(Attributes)}, + {<<"min">>, sh_attributes:get_mind(Attributes)}, + {<<"spe">>, sh_attributes:get_speed(Attributes)}, + {<<"str">>, sh_attributes:get_strength(Attributes)} + ] + }. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate + ( + non_neg_integer(), + btl_character:type(), + non_neg_integer() + ) + -> {list(any())}. +generate (IX, Character, PlayerIX) -> + Attributes = btl_character:get_attributes(Character), + {ActiveWeapon, SecondaryWeapon} = btl_character:get_weapon_ids(Character), + CharacterPlayerIX = btl_character:get_player_index(Character), + Location = btl_character:get_location(Character), + + { + [ + {<<"msg">>, <<"add_char">>}, + {<<"ix">>, IX}, + {<<"nam">>, btl_character:get_name(Character)}, + {<<"rnk">>, rank_to_string(btl_character:get_rank(Character))}, + {<<"ico">>, btl_character:get_icon(Character)}, + {<<"prt">>, btl_character:get_portrait(Character)}, + { + <<"hea">>, + btl_character:get_current_health(Character) + }, + {<<"lc">>, btl_location:encode(Location)}, + {<<"pla">>, CharacterPlayerIX}, + { + <<"ena">>, + ( + btl_character:get_is_active(Character) + and (CharacterPlayerIX == PlayerIX) + ) + }, + {<<"dea">>, btl_character:get_is_defeated(Character)}, + {<<"att">>, attributes_as_json(Attributes)}, + {<<"awp">>, ActiveWeapon}, + {<<"swp">>, SecondaryWeapon}, + {<<"ar">>, btl_character:get_armor_id(Character)} + ] + }. diff --git a/src/battle/reply/btl_add_tile.erl b/src/battle/reply/btl_add_tile.erl new file mode 100644 index 0000000..04c4ec2 --- /dev/null +++ b/src/battle/reply/btl_add_tile.erl @@ -0,0 +1,30 @@ +-module(btl_add_tile). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (btl_tile:type()) -> {list(any())}. +generate (Tile) -> + { + [ + {<<"msg">>, <<"add_tile">>}, + {<<"id">>, btl_tile:get_id(Tile)}, + {<<"nam">>, btl_tile:get_name(Tile)}, + {<<"ct">>, btl_tile:get_cost(Tile)}, + {<<"rmi">>, btl_tile:get_range_minimum(Tile)}, + {<<"rma">>, btl_tile:get_range_maximum(Tile)} + ] + }. diff --git a/src/battle/reply/btl_add_weapon.erl b/src/battle/reply/btl_add_weapon.erl new file mode 100644 index 0000000..d4edbef --- /dev/null +++ b/src/battle/reply/btl_add_weapon.erl @@ -0,0 +1,54 @@ +-module(btl_add_weapon). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec encode_range_type (sh_weapon:range_type()) -> binary(). +encode_range_type (melee) -> <<"m">>; +encode_range_type (ranged) -> <<"r">>. + +-spec encode_range_modifier (sh_weapon:range_modifier()) -> binary(). +encode_range_modifier (long) -> <<"l">>; +encode_range_modifier (short) -> <<"s">>. + +-spec encode_damage_type (sh_weapon:damage_type()) -> binary(). +encode_damage_type (slash) -> <<"s">>; +encode_damage_type (pierce) -> <<"p">>; +encode_damage_type (blunt) -> <<"b">>. + +-spec encode_damage_modifier (sh_weapon:damage_modifier()) -> binary(). +encode_damage_modifier (heavy) -> <<"h">>; +encode_damage_modifier (light) -> <<"l">>. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (sh_weapon:type()) -> {list(any())}. +generate (Weapon) -> + { + [ + {<<"msg">>, <<"add_weapon">>}, + {<<"id">>, sh_weapon:get_id(Weapon)}, + {<<"nam">>, sh_weapon:get_name(Weapon)}, + {<<"rt">>, encode_range_type(sh_weapon:get_range_type(Weapon))}, + { + <<"rm">>, + encode_range_modifier(sh_weapon:get_range_modifier(Weapon)) + }, + {<<"dt">>, encode_damage_type(sh_weapon:get_damage_type(Weapon))}, + { + <<"dm">>, + encode_damage_modifier(sh_weapon:get_damage_modifier(Weapon)) + }, + {<<"cf">>, sh_weapon:get_coefficient(Weapon)} + ] + }. diff --git a/src/battle/reply/btl_set_map.erl b/src/battle/reply/btl_set_map.erl new file mode 100644 index 0000000..37c6331 --- /dev/null +++ b/src/battle/reply/btl_set_map.erl @@ -0,0 +1,31 @@ +-module(btl_set_map). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (btl_battlemap:type()) -> {list(any())}. +generate (Battlemap) -> + { + [ + {<<"msg">>, <<"set_map">>}, + {<<"w">>, btl_battlemap:get_width(Battlemap)}, + {<<"h">>, btl_battlemap:get_height(Battlemap)}, + { + <<"t">>, + array:sparse_to_list(btl_battlemap:get_tile_class_ids(Battlemap)) + } + ] + }. diff --git a/src/battle/reply/btl_set_timeline.erl b/src/battle/reply/btl_set_timeline.erl new file mode 100644 index 0000000..e6f571f --- /dev/null +++ b/src/battle/reply/btl_set_timeline.erl @@ -0,0 +1,27 @@ +-module(btl_set_timeline). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (list(any())) -> {list(any())}. +generate (EncodedClientUpdate) -> + io:format("~nSending timeline:~n~p~n", [EncodedClientUpdate]), + { + [ + {<<"msg">>, <<"set_timeline">>}, + {<<"cnt">>, EncodedClientUpdate} + ] + }. diff --git a/src/battle/reply/btl_turn_results.erl b/src/battle/reply/btl_turn_results.erl new file mode 100644 index 0000000..361cab1 --- /dev/null +++ b/src/battle/reply/btl_turn_results.erl @@ -0,0 +1,27 @@ +-module(btl_turn_results). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (list(any())) -> {list(any())}. +generate (EncodedClientUpdate) -> + io:format("~nSending turn results:~n~p~n", [EncodedClientUpdate]), + { + [ + {<<"msg">>, <<"turn_results">>}, + {<<"cnt">>, EncodedClientUpdate} + ] + }. diff --git a/src/battle/struct/btl_attack.erl b/src/battle/struct/btl_attack.erl new file mode 100644 index 0000000..aa7659f --- /dev/null +++ b/src/battle/struct/btl_attack.erl @@ -0,0 +1,306 @@ +-module(btl_attack). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type order() :: ('first' | 'second' | 'counter'). +-type precision() :: ('misses' | 'grazes' | 'hits'). + +-record +( + attack, + { + order :: order(), + precision :: precision(), + is_critical :: boolean(), + is_parry :: boolean(), + damage :: non_neg_integer() + } +). + +-opaque type() :: #attack{}. +-type maybe_type() :: ('nothing' | type()). +-opaque step() :: {order(), boolean()}. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0, maybe_type/0, step/0]). + +-export +( + [ + get_sequence/3, + get_description_of/3, + apply_to_healths/3 + ] +). + +-export +( + [ + encode/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec roll_precision + ( + sh_statistics:type(), + sh_statistics:type() + ) + -> precision(). +roll_precision (AttackerStatistics, DefenderStatistics) -> + DefenderDodges = sh_statistics:get_dodges(DefenderStatistics), + AttackerAccuracy = sh_statistics:get_accuracy(AttackerStatistics), + MissChance = max(0, (DefenderDodges - AttackerAccuracy)), + case sh_roll:percentage() of + X when (X =< MissChance) -> misses; + X when (X =< (MissChance * 2)) -> grazes; + _ -> hits + end. + +-spec roll_damage + ( + sh_statistics:type(), + sh_statistics:type() + ) + -> {non_neg_integer(), boolean()}. +roll_damage (AttackerStatistics, _DefenderStatistics) -> + {MinimumDamage, MaximumDamage} = + sh_statistics:get_damages(AttackerStatistics), + MaximumRoll = max(1, MaximumDamage - MinimumDamage), + BaseDamage = MinimumDamage + (rand:uniform(MaximumRoll) - 1), + CriticalHitChance = sh_statistics:get_critical_hits(AttackerStatistics), + case sh_roll:percentage() of + X when (X =< CriticalHitChance) -> {(BaseDamage * 2), true}; + _ -> {BaseDamage, false} + end. + +-spec roll_parry (sh_statistics:type()) -> boolean(). +roll_parry (DefenderStatistics) -> + DefenderParryChance = sh_statistics:get_parries(DefenderStatistics), + (sh_roll:percentage() =< DefenderParryChance). + +-spec effect_of_attack + ( + order(), + btl_character:type(), + btl_character:type(), + boolean() + ) + -> type(). +effect_of_attack (Order, Attacker, Defender, CanParry) -> + AttackerStatistics = btl_character:get_statistics(Attacker), + DefenderStatistics = btl_character:get_statistics(Defender), + + ParryIsSuccessful = (CanParry and roll_parry(DefenderStatistics)), + + {ActualAtkStatistics, ActualDefStatistics} = + case ParryIsSuccessful of + true -> {DefenderStatistics, AttackerStatistics}; + false -> {AttackerStatistics, DefenderStatistics} + end, + {ActualAttacker, ActualDefender} = + case ParryIsSuccessful of + true -> {Defender, Attacker}; + false -> {Attacker, Defender} + end, + + ActualDefArmor = sh_armor:from_id(btl_character:get_armor_id(ActualDefender)), + {ActualAtkWeaponID, _} = btl_character:get_weapon_ids(ActualAttacker), + ActualAtkWeaponDmgType = + sh_weapon:get_damage_type(sh_weapon:from_id(ActualAtkWeaponID)), + + Precision = roll_precision(ActualAtkStatistics, ActualDefStatistics), + {Damage, IsCritical} = roll_damage(ActualAtkStatistics, ActualDefStatistics), + S0Damage = + case Precision of + misses -> 0; + grazes -> trunc(Damage / 2); + hits -> Damage + end, + ArmorResistance = + sh_armor:get_resistance_to(ActualAtkWeaponDmgType, ActualDefArmor), + ActualDamage = max(0, (S0Damage - ArmorResistance)), + + #attack + { + order = Order, + precision = Precision, + is_critical = IsCritical, + is_parry = ParryIsSuccessful, + damage = ActualDamage + }. + +-spec encode_order (order()) -> binary(). +encode_order (first) -> <<"f">>; +encode_order (counter) -> <<"c">>; +encode_order (second) -> <<"s">>. + +-spec encode_precision (precision()) -> binary(). +encode_precision (hits) -> <<"h">>; +encode_precision (grazes) -> <<"g">>; +encode_precision (misses) -> <<"m">>. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-spec get_description_of + ( + step(), + btl_character:type(), + btl_character:type() + ) + -> maybe_type(). +get_description_of ({first, CanParry}, Attacker, Defender) -> + effect_of_attack(first, Attacker, Defender, CanParry); +get_description_of ({second, CanParry}, Attacker, Defender) -> + AttackerStatistics = btl_character:get_statistics(Attacker), + AttackerDoubleAttackChange = + sh_statistics:get_double_hits(AttackerStatistics), + + case sh_roll:percentage() of + X when (X =< AttackerDoubleAttackChange) -> + effect_of_attack (second, Attacker, Defender, CanParry); + + _ -> + nothing + end; +get_description_of ({counter, CanParry}, Attacker, Defender) -> + effect_of_attack(counter, Defender, Attacker, CanParry). + +-spec apply_to_healths + ( + maybe_type(), + non_neg_integer(), + non_neg_integer() + ) + -> {maybe_type(), non_neg_integer(), non_neg_integer()}. +apply_to_healths +( + nothing, + AttackerHealth, + DefenderHealth +) -> + {nothing, AttackerHealth, DefenderHealth}; +apply_to_healths +( + _Attack, + AttackerHealth, + DefenderHealth +) +when +( + (AttackerHealth =< 0) + or (DefenderHealth =< 0) +) -> + {nothing, AttackerHealth, DefenderHealth}; +apply_to_healths +( + Attack, + AttackerHealth, + DefenderHealth +) +when +( + ( + (not Attack#attack.is_parry) + and ((Attack#attack.order == first) or (Attack#attack.order == second)) + ) + or + ( + Attack#attack.is_parry + and (Attack#attack.order == counter) + ) +) -> + Damage = Attack#attack.damage, + + { + Attack, + AttackerHealth, + (DefenderHealth - Damage) + }; +apply_to_healths +( + Attack, + AttackerHealth, + DefenderHealth +) +when +( + ( + (not Attack#attack.is_parry) + and (Attack#attack.order == counter) + ) + or + ( + Attack#attack.is_parry + and ((Attack#attack.order == first) or (Attack#attack.order == second)) + ) +) -> + Damage = Attack#attack.damage, + + { + Attack, + (AttackerHealth - Damage), + DefenderHealth + }. + +-spec get_sequence + ( + non_neg_integer(), + sh_weapon:type(), + sh_weapon:type() + ) + -> list(step()). +get_sequence (AttackRange, AttackerWeapon, DefenderWeapon) -> + {AttackerDefenseRange, AttackerAttackRange} = + sh_weapon:get_ranges(AttackerWeapon), + {DefenderDefenseRange, DefenderAttackRange} = + sh_weapon:get_ranges(DefenderWeapon), + + AttackerCanAttack = (AttackRange =< AttackerAttackRange), + AttackerCanAttack = true, + AttackerCanDefend = + (AttackerCanAttack and (AttackRange > AttackerDefenseRange)), + AttackerCanParry = + (AttackerCanDefend and sh_weapon:can_parry(AttackerWeapon)), + + DefenderCanAttack = (AttackRange =< DefenderAttackRange), + DefenderCanDefend = + (DefenderCanAttack and (AttackRange > DefenderDefenseRange)), + DefenderCanParry = + (DefenderCanDefend and sh_weapon:can_parry(DefenderWeapon)), + + First = {first, DefenderCanParry}, + Second = {second, DefenderCanParry}, + Counter = {counter, AttackerCanParry}, + + if + (not DefenderCanDefend) -> + [First, Second]; + + true -> + [First, Counter, Second] + end. + +-spec encode (type()) -> {list(any())}. +encode (Attack) -> + Order = Attack#attack.order, + Precision = Attack#attack.precision, + IsCritical = Attack#attack.is_critical, + IsParry = Attack#attack.is_parry, + Damage = Attack#attack.damage, + + { + [ + {<<"ord">>, encode_order(Order)}, + {<<"pre">>, encode_precision(Precision)}, + {<<"cri">>, IsCritical}, + {<<"par">>, IsParry}, + {<<"dmg">>, Damage} + ] + }. diff --git a/src/battle/struct/btl_battle.erl b/src/battle/struct/btl_battle.erl new file mode 100644 index 0000000..8befc4e --- /dev/null +++ b/src/battle/struct/btl_battle.erl @@ -0,0 +1,216 @@ +-module(btl_battle). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + battle, + { + id :: id(), + used_armor_ids :: list(sh_armor:id()), + used_weapon_ids :: list(sh_weapon:id()), + used_tile_ids :: list(btl_tile:id()), + battlemap :: btl_battlemap:type(), + characters :: array:array(btl_character:type()), + players :: array:array(btl_player:type()), + current_player_turn :: btl_player_turn:type() + } +). + +-opaque type() :: #battle{}. + +-export_type([type/0, id/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_used_weapon_ids/1, + get_used_armor_ids/1, + get_used_tile_ids/1, + get_battlemap/1, + get_characters/1, + get_character/2, + get_players/1, + get_player/2, + get_current_player_turn/1, + get_encoded_last_turns_effects/1, + + set_battlemap/2, + set_characters/2, + set_character/3, + set_players/2, + set_player/3, + set_current_player_turn/2, + + get_characters_field/0, + get_players_field/0, + get_current_player_turn_field/0 + ] +). + +-export +( + [ + new/7 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +get_all_timelines (Result, CurrentIndex, EndPoint, ArraySize, Players) -> + Player = array:get(CurrentIndex, Players), + Timeline = btl_player:get_timeline(Player), + NextIndex = ((CurrentIndex + 1) rem ArraySize), + NextResult = (Timeline ++ Result), + case CurrentIndex of + EndPoint -> + NextResult; + + _ -> + get_all_timelines(NextResult, NextIndex, EndPoint, ArraySize, Players) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Battle) -> Battle#battle.id. + +-spec get_used_weapon_ids (type()) -> list(sh_weapon:id()). +get_used_weapon_ids (Battle) -> Battle#battle.used_weapon_ids. + +-spec get_used_armor_ids (type()) -> list(sh_armor:id()). +get_used_armor_ids (Battle) -> Battle#battle.used_armor_ids. + +-spec get_used_tile_ids (type()) -> list(btl_tile:id()). +get_used_tile_ids (Battle) -> Battle#battle.used_tile_ids. + +-spec get_battlemap (type()) -> btl_battlemap:type(). +get_battlemap (Battle) -> Battle#battle.battlemap. + +-spec get_characters (type()) -> array:array(btl_character:type()). +get_characters (Battle) -> Battle#battle.characters. + +-spec get_character (non_neg_integer(), type()) -> btl_character:type(). +get_character (IX, Battle) -> + array:get(IX, Battle#battle.characters). + +-spec get_players (type()) -> array:array(btl_player:type()). +get_players (Battle) -> + Battle#battle.players. + +-spec get_player (non_neg_integer(), type()) -> btl_player:type(). +get_player (IX, Battle) -> + array:get(IX, Battle#battle.players). + +-spec get_current_player_turn (type()) -> btl_player_turn:type(). +get_current_player_turn (Battle) -> + Battle#battle.current_player_turn. + +-spec get_encoded_last_turns_effects (type()) -> list(any()). +get_encoded_last_turns_effects (Battle) -> + CurrentPlayerTurn = Battle#battle.current_player_turn, + Players = Battle#battle.players, + CurrentPlayerIX = btl_player_turn:get_player_ix(CurrentPlayerTurn), + + PlayersCount = array:size(Players), + StartingPoint = ((CurrentPlayerIX + 1) rem PlayersCount), + get_all_timelines([], StartingPoint, CurrentPlayerIX, PlayersCount, Players). + +-spec set_battlemap (btl_battlemap:type(), type()) -> type(). +set_battlemap (Battlemap, Battle) -> + Battle#battle + { + battlemap = Battlemap + }. + +-spec set_characters (array:array(btl_character:type()), type()) -> type(). +set_characters (Characters, Battle) -> + Battle#battle + { + characters = Characters + }. + +-spec set_character (non_neg_integer(), btl_character:type(), type()) -> type(). +set_character (IX, Character, Battle) -> + Battle#battle + { + characters = + array:set + ( + IX, + Character, + Battle#battle.characters + ) + }. + +-spec set_players (array:array(btl_player:type()), type()) -> type(). +set_players (Players, Battle) -> + Battle#battle + { + players = Players + }. + +-spec set_player (non_neg_integer(), btl_player:type(), type()) -> type(). +set_player (IX, Player, Battle) -> + Battle#battle + { + players = + array:set + ( + IX, + Player, + Battle#battle.players + ) + }. + +-spec set_current_player_turn (btl_player_turn:type(), type()) -> type(). +set_current_player_turn (PlayerTurn, Battle) -> + Battle#battle + { + current_player_turn = PlayerTurn + }. + +-spec new + ( + id(), + list(btl_player:type()), + btl_battlemap:type(), + list(btl_character:type()), + list(sh_weapon:id()), + list(sh_armor:id()), + list(btl_tile:id()) + ) + -> type(). +new (ID, PlayersAsList, Battlemap, CharactersAsList, UWIDs, UAIDs, UTIDs) -> + #battle + { + id = ID, + used_weapon_ids = UWIDs, + used_armor_ids = UAIDs, + used_tile_ids = UTIDs, + battlemap = Battlemap, + characters = array:from_list(CharactersAsList), + players = array:from_list(PlayersAsList), + current_player_turn = btl_player_turn:new(0, 0) + }. + + +-spec get_characters_field () -> non_neg_integer(). +get_characters_field () -> #battle.characters. + +-spec get_players_field () -> non_neg_integer(). +get_players_field () -> #battle.players. + +-spec get_current_player_turn_field () -> non_neg_integer(). +get_current_player_turn_field () -> #battle.current_player_turn. diff --git a/src/battle/struct/btl_battle_action.erl b/src/battle/struct/btl_battle_action.erl new file mode 100644 index 0000000..307043a --- /dev/null +++ b/src/battle/struct/btl_battle_action.erl @@ -0,0 +1,114 @@ +-module(btl_battle_action). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + move, + { + path :: list(btl_direction:enum()) + } +). + +-record +( + switch_weapon, + { + } +). + +-record +( + attack, + { + target_ix :: non_neg_integer() + } +). + +-type category() :: ('move' | 'switch_weapon' | 'attack' | 'nothing'). +-opaque type() :: (#move{} | #switch_weapon{} | #attack{}). + +-export_type([category/0, type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + decode/1, + can_follow/2 + ] +). + +-export +( + [ + get_path/1, + get_target_ix/1, + get_category/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec decode_mov_action (map()) -> type(). +decode_mov_action (JSONMap) -> + PathInBinary = maps:get(<<"p">>, JSONMap), + Path = lists:map(fun btl_direction:decode/1, PathInBinary), + + #move { path = Path }. + +-spec decode_atk_action (map()) -> type(). +decode_atk_action (JSONMap) -> + TargetIX = maps:get(<<"tix">>, JSONMap), + + #attack { target_ix = TargetIX }. + +-spec decode_swp_action (map()) -> type(). +decode_swp_action (_JSONMap) -> + #switch_weapon{}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec decode (map()) -> type(). +decode (EncodedAction) -> + JSONActionMap = EncodedAction, %jiffy:decode(EncodedAction, [return_maps]), + ActionType = maps:get(<<"t">>, JSONActionMap), + case ActionType of + <<"mov">> -> decode_mov_action(JSONActionMap); + <<"atk">> -> decode_atk_action(JSONActionMap); + <<"swp">> -> decode_swp_action(JSONActionMap) + end. + +-spec can_follow (category(), category()) -> boolean(). +can_follow (nothing, attack) -> true; +can_follow (nothing, switch_weapon) -> true; +can_follow (nothing, move) -> true; +can_follow (switch_weapon, attack) -> true; +can_follow (move, attack) -> true; +can_follow (_, _) -> false. + +-spec get_path (type()) -> list(btl_direction:type()). +get_path (Action) when is_record(Action, move) -> + Action#move.path; +get_path (_) -> + []. + +-spec get_target_ix (type()) -> non_neg_integer(). +get_target_ix (Action) when is_record(Action, attack) -> + Action#attack.target_ix; +get_target_ix (_) -> + []. + +-spec get_category (type()) -> category(). +get_category (Action) when is_record(Action, attack) -> attack; +get_category (Action) when is_record(Action, move) -> move; +get_category (Action) when is_record(Action, switch_weapon) -> switch_weapon; +get_category (Action) -> + io:format("How'd you get there?~p~n", [Action]), + true = Action. + diff --git a/src/battle/struct/btl_battlemap.erl b/src/battle/struct/btl_battlemap.erl new file mode 100644 index 0000000..886e2a9 --- /dev/null +++ b/src/battle/struct/btl_battlemap.erl @@ -0,0 +1,100 @@ +-module(btl_battlemap). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + battlemap, + { + id :: id(), + width :: integer(), + height :: integer(), + tile_class_ids :: array:array(btl_tile:class_id()) + } +). + +-opaque type() :: #battlemap{}. + +-export_type([type/0, id/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_width/1, + get_height/1, + get_tile_class_ids/1, + get_tile_class_id/2 + ] +). + +-export +( + [ + from_list/4 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec location_to_array_index + ( + non_neg_integer(), + btl_location:type() + ) + -> ('error' | non_neg_integer()). +location_to_array_index (ArrayWidth, {X, Y}) -> + if + (X < 0) -> error; + (Y < 0) -> error; + (X >= ArrayWidth) -> error; + true -> ((Y * ArrayWidth) + X) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Battlemap) -> Battlemap#battlemap.id. + +-spec get_width (type()) -> integer(). +get_width (Battlemap) -> Battlemap#battlemap.width. + +-spec get_height (type()) -> integer(). +get_height (Battlemap) -> Battlemap#battlemap.height. + +-spec get_tile_class_ids (type()) -> array:array(btl_tile:class_id()). +get_tile_class_ids (Battlemap) -> Battlemap#battlemap.tile_class_ids. + +-spec get_tile_class_id (btl_location:type(), type()) -> btl_tile:class_id(). +get_tile_class_id (Location, Battlemap) -> + TileIX = location_to_array_index(Battlemap#battlemap.width, Location), + array:get(TileIX, Battlemap#battlemap.tile_class_ids). + +-spec from_list + ( + non_neg_integer(), + non_neg_integer(), + non_neg_integer(), + list(non_neg_integer()) + ) + -> type(). +from_list (ID, Width, Height, List) -> + TileClassIDs = lists:map(fun btl_tile:class_id_from_int/1, List), + + #battlemap + { + id = list_to_binary(integer_to_list(ID)), + width = Width, + height = Height, + tile_class_ids = array:from_list(TileClassIDs) + }. diff --git a/src/battle/struct/btl_character.erl b/src/battle/struct/btl_character.erl new file mode 100644 index 0000000..841f4ea --- /dev/null +++ b/src/battle/struct/btl_character.erl @@ -0,0 +1,290 @@ +-module(btl_character). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: non_neg_integer(). +-type rank() :: ('optional' | 'target' | 'commander'). + +-record +( + character, + { + id :: id(), + player_ix :: non_neg_integer(), + name :: binary(), + rank :: rank(), + icon :: binary(), + portrait :: binary(), + attributes :: sh_attributes:type(), + statistics :: sh_statistics:type(), + weapon_ids :: {sh_weapon:id(), sh_weapon:id()}, + armor_id :: sh_armor:id(), + location :: {non_neg_integer(), non_neg_integer()}, + current_health :: integer(), %% Negative integers let us reverse attacks. + is_active :: boolean(), + is_defeated :: boolean() + } +). + +-opaque type() :: #character{}. + +-export_type([type/0, rank/0, id/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_player_index/1, + get_name/1, + get_rank/1, + get_icon/1, + get_portrait/1, + get_attributes/1, + get_statistics/1, + get_weapon_ids/1, + get_armor_id/1, + get_location/1, + get_current_health/1, + get_is_alive/1, + get_is_active/1, + get_is_defeated/1, + + set_rank/2, + set_weapon_ids/2, + set_armor_id/2, + set_statistics/2, + set_location/2, + set_current_health/2, + set_is_active/2, + set_is_defeated/2, + + get_rank_field/0, + get_statistics_field/0, + get_weapons_field/0, + get_location_field/0, + get_current_health_field/0, + get_is_active_field/0, + get_is_defeated_field/0 + ] +). + +-export +( + [ + random/5 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec find_random_location + ( + non_neg_integer(), + non_neg_integer(), + list({non_neg_integer(), non_neg_integer()}) + ) + -> {non_neg_integer(), non_neg_integer()}. +find_random_location (BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> + X = sh_roll:between(0, (BattlemapWidth - 1)), + Y = sh_roll:between(0, (BattlemapHeight - 1)), + + IsForbidden = lists:member({X, Y}, ForbiddenLocations), + + case IsForbidden of + true -> + find_random_location + ( + BattlemapWidth, + BattlemapHeight, + ForbiddenLocations + ); + + _ -> {X, Y} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Char) -> Char#character.id. + +-spec get_player_index (type()) -> non_neg_integer(). +get_player_index (Char) -> Char#character.player_ix. + +-spec get_name (type()) -> binary(). +get_name (Char) -> Char#character.name. + +-spec get_rank (type()) -> rank(). +get_rank (Char) -> Char#character.rank. + +-spec get_icon (type()) -> binary(). +get_icon (Char) -> Char#character.icon. + +-spec get_portrait (type()) -> binary(). +get_portrait (Char) -> Char#character.portrait. + +-spec get_attributes (type()) -> sh_attributes:type(). +get_attributes (Char) -> Char#character.attributes. + +-spec get_armor_id (type()) -> sh_armor:id(). +get_armor_id (Char) -> Char#character.armor_id. + +-spec get_weapon_ids (type()) -> {sh_weapon:id(), sh_weapon:id()}. +get_weapon_ids (Char) -> Char#character.weapon_ids. + +-spec get_statistics (type()) -> sh_statistics:type(). +get_statistics (Char) -> Char#character.statistics. + +-spec get_location (type()) -> {non_neg_integer(), non_neg_integer()}. +get_location (Char) -> Char#character.location. + +-spec get_current_health (type()) -> integer(). +get_current_health (Char) -> Char#character.current_health. + +-spec get_is_alive (type()) -> boolean(). +get_is_alive (Char) -> + ( + (not Char#character.is_defeated) + and (Char#character.current_health > 0) + ). + +-spec get_is_active (type()) -> boolean(). +get_is_active (Char) -> + ( + (not Char#character.is_defeated) + and Char#character.is_active + and get_is_alive(Char) + ). + +-spec get_is_defeated (type()) -> boolean(). +get_is_defeated (Char) -> Char#character.is_defeated. + +-spec set_rank (rank(), type()) -> type(). +set_rank (Rank, Char) -> + Char#character + { + rank = Rank + }. + +-spec set_location + ( + {non_neg_integer(), non_neg_integer()}, + type() + ) + -> type(). +set_location (Location, Char) -> + Char#character + { + location = Location + }. + +-spec set_current_health (integer(), type()) -> type(). +set_current_health (Health, Char) -> + Char#character + { + current_health = Health + }. + +-spec set_is_active (boolean(), type()) -> type(). +set_is_active (Active, Char) -> + Char#character + { + is_active = Active + }. + +-spec set_is_defeated (boolean(), type()) -> type(). +set_is_defeated (Defeated, Char) -> + Char#character + { + is_defeated = Defeated + }. + +-spec set_armor_id (sh_armor:id(), type()) -> type(). +set_armor_id (ArmorID, Char) -> + Char#character + { + armor_id = ArmorID + }. + +-spec set_weapon_ids ({sh_weapon:id(), sh_weapon:id()}, type()) -> type(). +set_weapon_ids (WeaponIDs, Char) -> + Char#character + { + weapon_ids = WeaponIDs + }. + +-spec set_statistics + ( + sh_statistics:type(), + type() + ) + -> type(). +set_statistics (Stats, Char) -> + Char#character + { + statistics = Stats + }. + +%%%% Utils +-spec random + ( + non_neg_integer(), + non_neg_integer(), + non_neg_integer(), + non_neg_integer(), + list({non_neg_integer(), non_neg_integer()}) + ) + -> type(). +random (ID, PlayerIX, BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> + Location = + find_random_location(BattlemapWidth, BattlemapHeight, ForbiddenLocations), + WeaponIDs = {sh_weapon:random_id(), sh_weapon:random_id()}, + ArmorID = sh_armor:random_id(), + Attributes = sh_attributes:random(), + Statistics = sh_statistics:new(Attributes, WeaponIDs, ArmorID), + IDAsListString = integer_to_list(ID), + IDAsBinaryString = list_to_binary(IDAsListString), + + #character + { + id = ID, + player_ix = PlayerIX, + name = list_to_binary("Char" ++ IDAsListString), + rank = + if + ((ID rem 8) == 0) -> commander; + ((ID rem 3) == 0) -> target; + true -> optional + end, + icon = IDAsBinaryString, + portrait = IDAsBinaryString, + attributes = Attributes, + weapon_ids = WeaponIDs, + armor_id = ArmorID, + statistics = Statistics, + location = Location, + current_health = sh_statistics:get_health(Statistics), + is_active = false, + is_defeated = false + }. + +-spec get_rank_field() -> non_neg_integer(). +get_rank_field () -> #character.rank. +-spec get_statistics_field() -> non_neg_integer(). +get_statistics_field () -> #character.statistics. +-spec get_weapons_field() -> non_neg_integer(). +get_weapons_field () -> #character.weapon_ids. +-spec get_location_field() -> non_neg_integer(). +get_location_field () -> #character.location. +-spec get_current_health_field() -> non_neg_integer(). +get_current_health_field () -> #character.current_health. +-spec get_is_active_field() -> non_neg_integer(). +get_is_active_field () -> #character.is_active. +-spec get_is_defeated_field() -> non_neg_integer(). +get_is_defeated_field () -> #character.is_defeated. diff --git a/src/battle/struct/btl_character_turn_data.erl b/src/battle/struct/btl_character_turn_data.erl new file mode 100644 index 0000000..31a4b7d --- /dev/null +++ b/src/battle/struct/btl_character_turn_data.erl @@ -0,0 +1,115 @@ +-module(btl_character_turn_data). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + type, + { + dirty :: boolean(), + battle :: btl_battle:type(), + character :: btl_character:type(), + character_ix :: non_neg_integer() + } +). + +-opaque type() :: #type{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + new/2, + + get_battle_is_dirty/1, + get_battle/1, + get_character/1, + get_character_ix/1, + + set_battle/2, + set_character/2 + ] +). + +-export +( + [ + clean_battle/1, + refresh_character/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (btl_battle:type(), non_neg_integer()) -> type(). +new (Battle, CharacterIX) -> + Character = btl_battle:get_character(CharacterIX, Battle), + + #type + { + dirty = false, + battle = Battle, + character = Character, + character_ix = CharacterIX + }. + +-spec get_battle_is_dirty (type()) -> boolean(). +get_battle_is_dirty (Data) -> Data#type.dirty. + +-spec get_battle (type()) -> btl_battle:type(). +get_battle (Data) -> Data#type.battle. + +-spec get_character (type()) -> btl_character:type(). +get_character (Data) -> Data#type.character. + +-spec get_character_ix (type()) -> non_neg_integer(). +get_character_ix (Data) -> Data#type.character_ix. + +-spec set_battle (btl_battle:type(), type()) -> type(). +set_battle (Battle, Data) -> + Data#type{ battle = Battle }. + +-spec set_character (btl_character:type(), type()) -> type(). +set_character (Character, Data) -> + Data#type + { + dirty = true, + character = Character + }. + +-spec clean_battle (type()) -> type(). +clean_battle (Data) -> + Data#type + { + dirty = false, + battle = + btl_battle:set_character + ( + Data#type.character_ix, + Data#type.character, + Data#type.battle + ) + }. + +-spec refresh_character (type()) -> type(). +refresh_character (Data) -> + Data#type + { + dirty = false, + character = + btl_battle:get_character + ( + Data#type.character_ix, + Data#type.battle + ) + }. diff --git a/src/battle/struct/btl_character_turn_request.erl b/src/battle/struct/btl_character_turn_request.erl new file mode 100644 index 0000000..a4f310d --- /dev/null +++ b/src/battle/struct/btl_character_turn_request.erl @@ -0,0 +1,84 @@ +-module(btl_character_turn_request). + +-define(PLAYER_ID_FIELD, <<"pid">>). +-define(SESSION_TOKEN_FIELD, <<"stk">>). +-define(BATTLE_ID_FIELD, <<"bid">>). +-define(CHAR_IX_FIELD, <<"cix">>). +-define(ACTIONS_FIELD, <<"act">>). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + type, + { + player_id :: btl_player:id(), + session_token :: binary(), + battle_id :: binary(), + character_ix :: non_neg_integer(), + actions :: list(btl_battle_action:type()) + } +). + +-opaque type() :: #type{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + decode/1 + ] +). + +-export +( + [ + get_player_id/1, + get_session_token/1, + get_battle_id/1, + get_character_ix/1, + get_actions/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec decode (map()) -> type(). +decode (Map) -> + CharacterIX = maps:get(?CHAR_IX_FIELD, Map), + EncodedActions = maps:get(?ACTIONS_FIELD, Map), + Actions = lists:map(fun btl_battle_action:decode/1, EncodedActions), + + #type + { + player_id = maps:get(?PLAYER_ID_FIELD, Map), + session_token = maps:get(?SESSION_TOKEN_FIELD, Map), + battle_id = maps:get(?BATTLE_ID_FIELD, Map), + character_ix = CharacterIX, + actions = Actions + }. + +-spec get_player_id (type()) -> btl_player:id(). +get_player_id (Request) -> Request#type.player_id. + +-spec get_session_token (type()) -> binary(). +get_session_token (Request) -> Request#type.session_token. + +-spec get_battle_id (type()) -> binary(). +get_battle_id (Request) -> Request#type.battle_id. + +-spec get_character_ix (type()) -> non_neg_integer(). +get_character_ix (Request) -> Request#type.character_ix. + +-spec get_actions (type()) -> list(btl_battle_action:type()). +get_actions (Request) -> Request#type.actions. diff --git a/src/battle/struct/btl_character_turn_update.erl b/src/battle/struct/btl_character_turn_update.erl new file mode 100644 index 0000000..a6b29d9 --- /dev/null +++ b/src/battle/struct/btl_character_turn_update.erl @@ -0,0 +1,85 @@ +-module(btl_character_turn_update). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + type, + { + data :: btl_character_turn_data:type(), + timeline :: list(any()), + db :: list(sh_db_query:op()) + } +). + +-opaque type() :: #type{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + new/1, + + get_data/1, + get_timeline/1, + get_db/1, + + set_data/2, + add_to_timeline/3, + add_to_db/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (btl_character_turn_data:type()) -> type(). +new (Data) -> + #type + { + data = Data, + timeline = [], + db = [] + }. + +-spec get_data (type()) -> btl_character_turn_data:type(). +get_data (Update) -> Update#type.data. + +-spec get_timeline (type()) -> list(any()). +get_timeline (Update) -> Update#type.timeline. + +-spec get_db (type()) -> list(sh_db_query:op()). +get_db (Update) -> Update#type.db. + +-spec set_data (btl_character_turn_data:type(), type()) -> type(). +set_data (Data, Update) -> + Update#type{ data = Data}. + +-spec add_to_timeline + ( + btl_turn_result:type(), + sh_db_query:op(), + type() + ) -> type(). +add_to_timeline (Item, DBUpdate, Update) -> + add_to_db + ( + DBUpdate, + Update#type + { + timeline = [btl_turn_result:encode(Item)|Update#type.timeline] + } + ). + +-spec add_to_db (sh_db_query:op(), type()) -> type(). +add_to_db (Item, Update) -> + Update#type{ db = [Item|Update#type.db] }. diff --git a/src/battle/struct/btl_direction.erl b/src/battle/struct/btl_direction.erl new file mode 100644 index 0000000..9fb5a01 --- /dev/null +++ b/src/battle/struct/btl_direction.erl @@ -0,0 +1,38 @@ +-module(btl_direction). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type enum() :: ('up' | 'down' | 'left' | 'right'). +-type type() :: enum(). + +-export_type([enum/0, type/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + decode/1, + encode/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec decode (binary()) -> enum(). +decode (<<"U">>) -> up; +decode (<<"D">>) -> down; +decode (<<"L">>) -> left; +decode (<<"R">>) -> right. + +-spec encode (enum()) -> binary(). +encode (up) -> <<"U">>; +encode (down) -> <<"D">>; +encode (left) -> <<"L">>; +encode (right) -> <<"R">>. diff --git a/src/battle/struct/btl_location.erl b/src/battle/struct/btl_location.erl new file mode 100644 index 0000000..9670cb0 --- /dev/null +++ b/src/battle/struct/btl_location.erl @@ -0,0 +1,90 @@ +-module(btl_location). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type type() :: ({non_neg_integer(), non_neg_integer()} | 'nowhere'). + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + decode/1, + encode/1, + get_nowhere/0 + ] +). + +-export +( + [ + apply_direction/2, + dist/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec validate ({integer(), integer()}) -> type(). +validate ({X, Y}) -> + if + (X < 0) -> nowhere; + (Y < 0) -> nowhere; + true -> {X, Y} + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_nowhere () -> type(). +get_nowhere () -> nowhere. + +-spec apply_direction (btl_direction:enum(), type()) -> type(). +apply_direction (left, {X, Y}) -> + validate({(X - 1), Y}); +apply_direction (right, {X, Y}) -> + validate({(X + 1), Y}); +apply_direction (up, {X, Y}) -> + validate({X, (Y - 1)}); +apply_direction (down, {X, Y}) -> + validate({X, (Y + 1)}); +apply_direction (_, nowhere) -> + error("Trying to move from 'nowhere'."), + nowhere. + +-spec dist(type(), type()) -> non_neg_integer(). +dist ({OX, OY}, {DX, DY}) -> + (abs(DY - OY) + abs(DX - OX)); +dist (_, _) -> + error("Trying to measure distance to 'nowhere'"), + 999. + +-spec encode (type()) -> {list(any())}. +encode ({X, Y}) -> + { + [ + {<<"x">>, X}, + {<<"y">>, Y} + ] + }; +encode (nowhere) -> + { + [ + {<<"x">>, -1}, + {<<"y">>, -1} + ] + }. + +-spec decode (map()) -> type(). +decode (Map) -> + X = maps:get(<<"x">>, Map), + Y = maps:get(<<"y">>, Map), + + true = (is_integer(X) and is_integer(Y)), + + validate({X, Y}). diff --git a/src/battle/struct/btl_player.erl b/src/battle/struct/btl_player.erl new file mode 100644 index 0000000..1cb1d93 --- /dev/null +++ b/src/battle/struct/btl_player.erl @@ -0,0 +1,104 @@ +-module(btl_player). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + player, + { + ix :: non_neg_integer(), + id :: id(), + character_ix :: non_neg_integer(), + timeline :: list(any()), + is_active :: boolean() + } +). + +-opaque type() :: #player{}. + +-export_type([type/0, id/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + get_id/1, + get_index/1, + get_character_index/1, + get_timeline/1, + + get_is_active/1, + set_is_active/2, + + add_to_timeline/2, + reset_timeline/1, + + get_timeline_field/0, + get_is_active_field/0 + ] +). + +-export +( + [ + new/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_id (type()) -> id(). +get_id (Player) -> Player#player.id. + +-spec get_index (type()) -> non_neg_integer(). +get_index (Player) -> Player#player.ix. + +-spec get_character_index (type()) -> non_neg_integer(). +get_character_index (Player) -> Player#player.character_ix. + +-spec get_timeline (type()) -> list(any()). +get_timeline (Player) -> Player#player.timeline. + +-spec get_is_active (type()) -> boolean(). +get_is_active (Player) -> Player#player.is_active. + +-spec set_is_active (boolean(), type()) -> type(). +set_is_active (Val, Player) -> Player#player{ is_active = Val }. + +-spec add_to_timeline (list(any()), type()) -> type(). +add_to_timeline (NewEvents, Player) -> + OldTimeline = Player#player.timeline, + + Player#player + { + timeline = (NewEvents ++ OldTimeline) + }. + +-spec reset_timeline (type()) -> type(). +reset_timeline (Player) -> Player#player{ timeline = [] }. + +-spec new (non_neg_integer(), non_neg_integer(), id()) -> type(). +new (IX, CharacterIX, ID) -> + #player + { + ix = IX, + character_ix = CharacterIX, + id = ID, + is_active = true, + timeline = [] + }. + +-spec get_timeline_field () -> non_neg_integer(). +get_timeline_field () -> #player.timeline. + +-spec get_is_active_field () -> non_neg_integer(). +get_is_active_field () -> #player.is_active. diff --git a/src/battle/struct/btl_player_turn.erl b/src/battle/struct/btl_player_turn.erl new file mode 100644 index 0000000..e0665f4 --- /dev/null +++ b/src/battle/struct/btl_player_turn.erl @@ -0,0 +1,106 @@ +-module(btl_player_turn). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + player_turn, + { + number :: non_neg_integer(), + player_ix :: non_neg_integer() + } +). + +-opaque type() :: #player_turn{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + new/2, + next/2 + ] +). + +%%%% Accessors +-export +( + [ + get_number/1, + get_player_ix/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-spec next_valid_player + ( + non_neg_integer(), + array:array(btl_player:type()), + non_neg_integer(), + non_neg_integer() + ) -> non_neg_integer(). +next_valid_player (StartingPoint, _Players, _PlayersCount, StartingPoint) -> + StartingPoint; +next_valid_player (CandidateIX, Players, PlayersCount, StartingPoint) -> + Candidate = array:get(CandidateIX, Players), + + case btl_player:get_is_active(Candidate) of + true -> CandidateIX; + _ -> + next_valid_player + ( + ((CandidateIX + 1) rem PlayersCount), + Players, + PlayersCount, + StartingPoint + ) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec new (non_neg_integer(), non_neg_integer()) -> type(). +new (Number, PlayerIX) -> + #player_turn + { + number = Number, + player_ix = PlayerIX + }. + +-spec get_number (type()) -> non_neg_integer(). +get_number (PlayerTurn) -> PlayerTurn#player_turn.number. + +-spec get_player_ix (type()) -> non_neg_integer(). +get_player_ix (PlayerTurn) -> PlayerTurn#player_turn.player_ix. + +-spec next (array:array(btl_player:type()), type()) -> type(). +next (Players, CurrentPlayerTurn) -> + CurrentPlayerIX = CurrentPlayerTurn#player_turn.player_ix, + CurrentTurnNumber = CurrentPlayerTurn#player_turn.number, + PlayersCount = array:size(Players), + + NextPlayerIX = + next_valid_player + ( + ((CurrentPlayerIX + 1) rem PlayersCount), + Players, + PlayersCount, + CurrentPlayerIX + ), + + NextTurnNumber = + case (NextPlayerIX < CurrentPlayerIX) of + true -> (CurrentTurnNumber + 1); + _ -> CurrentTurnNumber + end, + + new(NextTurnNumber, NextPlayerIX). diff --git a/src/battle/struct/btl_tile.erl b/src/battle/struct/btl_tile.erl new file mode 100644 index 0000000..16e671b --- /dev/null +++ b/src/battle/struct/btl_tile.erl @@ -0,0 +1,124 @@ +-module(btl_tile). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + tile, + { + id :: id(), + name :: binary(), + cost :: non_neg_integer(), + class_range_min :: non_neg_integer(), + class_range_max :: non_neg_integer() + } +). + +-opaque id() :: non_neg_integer(). +-opaque class_id() :: non_neg_integer(). +-opaque type() :: #tile{}. + +-export_type([type/0, class_id/0, id/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + get_id/1, + get_name/1, + get_cost/1, + get_range_minimum/1, + get_range_maximum/1, + from_id/1, + cost_when_oob/0 + ] +). + +-export +( + [ + class_id_to_type_id/1, + class_id_from_int/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-spec class_id_to_type_id (class_id()) -> id(). +class_id_to_type_id (ClassID) -> + case ClassID of + 0 -> 0; + 1 -> 1; + 2 -> 2; + N when ((N >= 3) and (N =< 17)) -> 3 + end. + +-spec from_id (id()) -> type(). +from_id (0) -> + #tile + { + id = 0, + name = <<"[Grassland] Grass">>, + cost = 6, + class_range_min = 0, + class_range_max = 0 + }; +from_id (1) -> + #tile + { + id = 1, + name = <<"[Grassland] Mushroom Infestation">>, + cost = 12, + class_range_min = 1, + class_range_max = 1 + }; +from_id (2) -> + #tile + { + id = 2, + name = <<"[Grassland] Tree Remains">>, + cost = 24, + class_range_min = 2, + class_range_max = 2 + }; +from_id (3) -> + #tile + { + id = 3, + name = <<"[Grassland] Clear Water">>, + cost = cost_when_occupied(), + class_range_min = 3, + class_range_max = 17 + }. + +-spec cost_when_oob () -> non_neg_integer(). +cost_when_oob () -> 255. + +-spec cost_when_occupied () -> non_neg_integer(). +cost_when_occupied () -> 201. + +-spec get_id (type()) -> non_neg_integer(). +get_id (Tile) -> Tile#tile.id. + +-spec get_cost (type()) -> non_neg_integer(). +get_cost (Tile) -> Tile#tile.cost. + +-spec get_name (type()) -> binary(). +get_name (Tile) -> Tile#tile.name. + +-spec get_range_minimum (type()) -> non_neg_integer(). +get_range_minimum (Tile) -> Tile#tile.class_range_min. + +-spec get_range_maximum (type()) -> non_neg_integer(). +get_range_maximum (Tile) -> Tile#tile.class_range_max. + +-spec class_id_from_int (non_neg_integer()) -> id(). +class_id_from_int (I) -> I. diff --git a/src/battle/struct/btl_turn_result.erl b/src/battle/struct/btl_turn_result.erl new file mode 100644 index 0000000..97169e3 --- /dev/null +++ b/src/battle/struct/btl_turn_result.erl @@ -0,0 +1,215 @@ +-module(btl_turn_result). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%% +-record +( + switched_weapon, + { + character_ix :: btl_character:id() + } +). + +-record +( + moved, + { + character_ix :: btl_character:id(), + path :: list(btl_direction:enum()), + new_location :: btl_location:type() + } +). + +-record +( + attacked, + { + attacker_ix :: btl_character:id(), + defender_ix :: btl_character:id(), + sequence :: list(btl_attack:type()) + } +). + +-record +( + player_won, + { + player_ix :: non_neg_integer() + } +). + +-record +( + player_lost, + { + player_ix :: non_neg_integer() + } +). + +-record +( + player_turn_started, + { + player_ix :: non_neg_integer() + } +). + +-opaque type() :: ( + #switched_weapon{} + | #moved{} + | #attacked{} + | #player_won{} + | #player_lost{} + | #player_turn_started{} +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0]). + +-export +( + [ + new_player_won/1, + new_player_lost/1, + new_player_turn_started/1, + new_character_switched_weapons/1, + new_character_moved/3, + new_character_attacked/3 + ] +). + +-export +( + [ + encode/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new_player_won (non_neg_integer()) -> type(). +new_player_won (PlayerIX) -> + #player_won { player_ix = PlayerIX }. + +-spec new_player_lost (non_neg_integer()) -> type(). +new_player_lost (PlayerIX) -> + #player_lost { player_ix = PlayerIX }. + +-spec new_player_turn_started (non_neg_integer()) -> type(). +new_player_turn_started (PlayerIX) -> + #player_turn_started { player_ix = PlayerIX }. + +-spec new_character_switched_weapons (btl_character:id()) -> type(). +new_character_switched_weapons (CharacterIX) -> + #switched_weapon { character_ix = CharacterIX }. + +-spec new_character_moved + ( + btl_character:id(), + list(btl_direction:enum()), + btl_location:type() + ) + -> type(). +new_character_moved (CharacterIX, Path, NewLocation) -> + #moved + { + character_ix = CharacterIX, + path = Path, + new_location = NewLocation + }. + +-spec new_character_attacked + ( + btl_character:id(), + btl_character:id(), + list(btl_attack:type()) + ) + -> type(). +new_character_attacked (AttackerIX, DefenderIX, AttackSequence) -> + #attacked + { + attacker_ix = AttackerIX, + defender_ix = DefenderIX, + sequence = AttackSequence + }. + +-spec encode (type()) -> {list(any())}. +encode (TurnResult) when is_record(TurnResult, switched_weapon) -> + CharacterIX = TurnResult#switched_weapon.character_ix, + + { + [ + {<<"t">>, <<"swp">>}, + {<<"ix">>, CharacterIX} + ] + }; +encode (TurnResult) when is_record(TurnResult, moved) -> + CharacterIX = TurnResult#moved.character_ix, + Path = TurnResult#moved.path, + NewLocation = TurnResult#moved.new_location, + + EncodedPath = lists:map(fun btl_direction:encode/1, Path), + EncodedNewLocation = btl_location:encode(NewLocation), + + { + [ + {<<"t">>, <<"mv">>}, + {<<"ix">>, CharacterIX}, + {<<"p">>, EncodedPath}, + {<<"nlc">>, EncodedNewLocation} + ] + }; +encode (TurnResult) when is_record(TurnResult, attacked) -> + AttackerIX = TurnResult#attacked.attacker_ix, + DefenderIX = TurnResult#attacked.defender_ix, + Sequence = TurnResult#attacked.sequence, + + EncodedSequence = lists:map(fun btl_attack:encode/1, Sequence), + + { + [ + {<<"t">>, <<"atk">>}, + {<<"aix">>, AttackerIX}, + {<<"dix">>, DefenderIX}, + {<<"seq">>, EncodedSequence} + ] + }; +encode (TurnResult) when is_record(TurnResult, player_won) -> + PlayerIX = TurnResult#player_won.player_ix, + + { + [ + {<<"t">>, <<"pwo">>}, + {<<"ix">>, PlayerIX} + ] + }; +encode (TurnResult) when is_record(TurnResult, player_lost) -> + PlayerIX = TurnResult#player_lost.player_ix, + + { + [ + {<<"t">>, <<"plo">>}, + {<<"ix">>, PlayerIX} + ] + }; +encode (TurnResult) when is_record(TurnResult, player_turn_started) -> + PlayerIX = TurnResult#player_turn_started.player_ix, + + { + [ + {<<"t">>, <<"pts">>}, + {<<"ix">>, PlayerIX} + ] + }; +encode (Other) -> + io:format("~n invalid encode param\"~p\"~n", [Other]), + true = Other. diff --git a/src/battlemap/bm_handler.erl b/src/battlemap/bm_handler.erl deleted file mode 100644 index d355ea1..0000000 --- a/src/battlemap/bm_handler.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(bm_handler). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([start/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -start (_YawsParams) -> - {ok, Pid} = sh_timed_caches_manager:start(), - case sh_database:fetch(battle_db, <<"0">>) of - {ok, _} -> ok; - not_found -> - sh_database:insert - ( - battle_db, - <<"0">>, - any, - bm_shim:generate_random_battle() - ) - end, - sh_timed_caches_manager:new_cache(Pid, battle_db, none), - ok. diff --git a/src/battlemap/bm_shim.erl b/src/battlemap/bm_shim.erl deleted file mode 100644 index 67e82bf..0000000 --- a/src/battlemap/bm_shim.erl +++ /dev/null @@ -1,183 +0,0 @@ --module(bm_shim). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate_random_battle/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --spec generate_random_characters - ( - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - bm_battlemap:type(), - list(bm_location:type()), - list(bm_character:type()) - ) - -> list(bm_character:type()). -generate_random_characters -( - 0, - 0, - _CharactersPerPlayer, - _TotalCharacterCount, - _Battlemap, - _ForbiddenLocations, - Result -) -> - Result; -generate_random_characters -( - MaxPlayerIX, - 0, - CharactersPerPlayer, - TotalCharacterCount, - Battlemap, - ForbiddenLocations, - Result -) -> - generate_random_characters - ( - (MaxPlayerIX - 1), - CharactersPerPlayer, - CharactersPerPlayer, - TotalCharacterCount, - Battlemap, - ForbiddenLocations, - Result - ); -generate_random_characters -( - MaxPlayerIX, - PlayerCharacterCount, - CharactersPerPlayer, - TotalCharacterCount, - Battlemap, - ForbiddenLocations, - Result -) -> - NewCharacter = - bm_character:random - ( - TotalCharacterCount, - MaxPlayerIX, - bm_battlemap:get_width(Battlemap), - bm_battlemap:get_height(Battlemap), - ForbiddenLocations - ), - Character = - case MaxPlayerIX of - 0 -> bm_character:set_is_active(true, NewCharacter); - _ -> NewCharacter - end, - - generate_random_characters - ( - MaxPlayerIX, - (PlayerCharacterCount - 1), - CharactersPerPlayer, - (TotalCharacterCount + 1), - Battlemap, - [bm_character:get_location(Character)|ForbiddenLocations], - [Character|Result] - ). --spec demo_map () -> list(non_neg_integer()). -demo_map () -> - [ - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1, 2, - 2, 0, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 1, 2, - 2, 0, 0, 0, 1, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 1, 0, 0, 2, - 2, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 2, 2, 0, 0, 0, 1, 2, - 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 8, 6, 6, 6, 6, 9, 0, 0, 0, 0, 2, 0, 0, 1, 0, 0, 2, - 2, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 2, - 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 2, - 2, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 1, 1, 1, 0, 1, 0, 2, - 2, 0, 0, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 2, - 2, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 0, 0, 2, 1, 1, 0, 1, 2, - 2, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 0, 0, 4, 3, 3, 3, 3, 5, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 2, - 2, 0, 1, 1, 1, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 4, 3, 3, 3, 3, 5, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 2, - 2, 0, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0,11, 7, 7, 7, 7,10, 0, 0, 0, 1, 0, 1, 1, 1, 0, 0, 2, - 2, 0, 1, 1, 1, 0, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 2, - 2, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 8, 6, 6, 6, 6, 6, 6, 6, 6, 9, 0, 0, 0, 0, 0, 0, 1, 2, - 2, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 0, 0, 0, 0, 1, 0, 2, - 2, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 0, 1, 1, 0, 2, 0, 2, - 2, 1, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 1, 1, 0, 0, 0, 0, 2, - 2, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 0, 0, 1, 1, 0, 1, 0, 2, - 2, 0, 0, 0, 1, 2, 2, 0, 0, 0, 0, 8, 6, 6,16,15, 7, 7, 7, 7, 7, 7, 7,10, 0, 0, 1, 2, 0, 1, 0, 2, - 2, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 4, 3, 3, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 2, - 2, 1, 0, 0, 1, 1, 0, 0, 0, 0, 8,16, 3, 3, 3, 5, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 2, - 2, 1, 0, 1, 1, 0, 0, 0, 1, 1, 4, 3, 3, 3, 3, 5, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 2, - 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3,15, 7, 7,10, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 1, 0, 0, 0, 1, 2, - 2, 0, 0, 1, 0, 1, 0, 1, 0, 1, 4, 3, 5, 8, 6, 6, 9, 0, 0, 0, 0, 0, 0, 0, 2, 0, 1, 0, 0, 0, 1, 2, - 2, 1, 0, 0, 0, 0, 0, 0, 0, 2, 4, 3,17,16, 3, 3, 5, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 2, - 2, 0, 0, 1, 0, 0, 1, 1, 0, 1, 4, 3,15, 7, 7, 7,10, 0, 1, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 1, 1, 2, - 2, 1, 1, 0, 0, 1, 0, 0, 0, 0, 4, 3, 5, 0, 0, 0, 0, 0, 1, 0, 2, 0, 1, 0, 1, 0, 0, 0, 1, 1, 1, 2, - 2, 1, 1, 1, 0, 1, 0, 1, 0, 1, 4, 3, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 1, 2, - 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,16, 3,17, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 - ]. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_random_battle () -> bm_battle:type(). -generate_random_battle () -> - %BattlemapWidth = 32, % sh_roll:between(16, 32), - %BattlemapHeight = 32, %sh_roll:between(16, 32), - %Battlemap = bm_battlemap:random(0, BattlemapWidth, BattlemapHeight), - Battlemap = bm_battlemap:from_list(0, 32, 32, demo_map()), - Characters = generate_random_characters(1, 8, 8, 0, Battlemap, [], []), - PlayersAsList = [bm_player:new(0, 8, <<"0">>), bm_player:new(1, 0, <<"1">>)], - - {UsedWeaponIDs, UsedArmorIDs} = - lists:foldl - ( - fun (Character, {UWIDs, UAIDs}) -> - {MWpID, SWpID} = bm_character:get_weapon_ids(Character), - AID = bm_character:get_armor_id(Character), - { - sets:add_element(MWpID, sets:add_element(SWpID, UWIDs)), - sets:add_element(AID, UAIDs) - } - end, - {sets:new(), sets:new()}, - Characters - ), - - UsedTileIDs = - array:sparse_foldl - ( - fun (_IX, TileClassID, CurrentTileIDs) -> - sets:add_element - ( - bm_tile:class_id_to_type_id(TileClassID), - CurrentTileIDs - ) - end, - sets:new(), - bm_battlemap:get_tile_class_ids(Battlemap) - ), - - Battle = - bm_battle:new - ( - <<"0">>, - PlayersAsList, - Battlemap, - Characters, - sets:to_list(UsedWeaponIDs), - sets:to_list(UsedArmorIDs), - sets:to_list(UsedTileIDs) - ), - - Battle. diff --git a/src/battlemap/game-logic/bm_movement.erl b/src/battlemap/game-logic/bm_movement.erl deleted file mode 100644 index 8bf2c5b..0000000 --- a/src/battlemap/game-logic/bm_movement.erl +++ /dev/null @@ -1,60 +0,0 @@ --module(bm_movement). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([cross/4]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec cross - ( - bm_battlemap:type(), - list(bm_location:type()), - list(bm_direction:enum()), - non_neg_integer(), - bm_location:type() - ) - -> {bm_location:type(), non_neg_integer()}. -cross (_Battlemap, _ForbiddenLocations, [], Cost, Location) -> - {Location, Cost}; -cross (Battlemap, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> - NextLocation = bm_location:apply_direction(Step, Location), - NextTileClassID = bm_battlemap:get_tile_class_id(NextLocation, Battlemap), - NextTileID = bm_tile:class_id_to_type_id(NextTileClassID), - NextTile = bm_tile:from_id(NextTileID), - NextCost = (Cost + bm_tile:get_cost(NextTile)), - IsForbidden = - lists:foldl - ( - fun (ForbiddenLocation, Prev) -> - (Prev or (NextLocation == ForbiddenLocation)) - end, - false, - ForbiddenLocations - ), - - IsForbidden = false, - - cross(Battlemap, ForbiddenLocations, NextSteps, NextCost, NextLocation). - --spec cross - ( - bm_battlemap:type(), - list(bm_location:type()), - list(bm_direction:enum()), - bm_location:type() - ) - -> {bm_location:type(), non_neg_integer()}. -cross (Battlemap, ForbiddenLocations, Path, Location) -> - cross(Battlemap, ForbiddenLocations, Path, 0, Location). diff --git a/src/battlemap/game-logic/bm_next_turn.erl b/src/battlemap/game-logic/bm_next_turn.erl deleted file mode 100644 index 56e7f7e..0000000 --- a/src/battlemap/game-logic/bm_next_turn.erl +++ /dev/null @@ -1,160 +0,0 @@ --module(bm_next_turn). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - update_if_needed/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec set_player_turn_to_next (bm_battle:type()) - -> {bm_battle:type(), sh_db_query:op()}. -set_player_turn_to_next (Battle) -> - Players = bm_battle:get_players(Battle), - CurrentPlayerTurn = bm_battle:get_current_player_turn(Battle), - - NextPlayerTurn = bm_player_turn:next(Players, CurrentPlayerTurn), - - UpdatedBattle = bm_battle:set_current_player_turn(NextPlayerTurn, Battle), - - DBQuery = - sh_db_query:set_field - ( - bm_battle:get_current_player_turn_field(), - NextPlayerTurn - ), - - {UpdatedBattle, DBQuery}. - --spec reset_next_player_timeline (bm_battle:type()) - -> {bm_battle:type(), bm_player:type(), sh_db_query:op()}. -reset_next_player_timeline (Battle) -> - NextPlayerTurn = bm_battle:get_current_player_turn(Battle), - NextPlayerIX = bm_player_turn:get_player_ix(NextPlayerTurn), - NextPlayer = bm_battle:get_player(NextPlayerIX, Battle), - - UpdatedNextPlayer = bm_player:reset_timeline(NextPlayer), - UpdatedBattle = - bm_battle:set_player(NextPlayerIX, UpdatedNextPlayer, Battle), - - DBQuery = - sh_db_query:update_indexed - ( - bm_battle:get_players_field(), - NextPlayerIX, - [ sh_db_query:set_field(bm_player:get_timeline_field(), []) ] - ), - - {UpdatedBattle, UpdatedNextPlayer, DBQuery}. - - --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) -> - NextPlayerIX = bm_player:get_index(NextPlayer), - Characters = bm_battle:get_characters(Battle), - - {UpdatedCharacters, ModifiedIXs} = - sh_array_util:mapiff - ( - fun (Character) -> - (bm_character:get_player_index(Character) == NextPlayerIX) - end, - fun (Character) -> - bm_character:set_is_active(true, Character) - end, - Characters - ), - - DBQueries = - lists:map - ( - fun (IX) -> - sh_db_query:update_indexed - ( - bm_battle:get_characters_field(), - IX, - [ - sh_db_query:set_field - ( - bm_character:get_is_active_field(), - true - ) - ] - ) - end, - ModifiedIXs - ), - - UpdatedBattle = bm_battle:set_characters(UpdatedCharacters, Battle), - - {UpdatedBattle, DBQueries}. - --spec update - ( - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -update (Update) -> - Data = bm_character_turn_update:get_data(Update), - Battle = bm_character_turn_data:get_battle(Data), - - {S0Battle, DBQuery0} = set_player_turn_to_next(Battle), - {S1Battle, NextPlayer, DBQuery1} = reset_next_player_timeline(S0Battle), - {S2Battle, DBQueries} = - activate_next_players_characters(S1Battle, NextPlayer), - - S0Data = bm_character_turn_data:set_battle(S2Battle, Data), - S0Update = - bm_character_turn_update:add_to_timeline - ( - bm_turn_result:new_player_turn_started - ( - bm_player:get_index(NextPlayer) - ), - DBQuery0, - Update - ), - - S1Update = bm_character_turn_update:set_data(S0Data, S0Update), - - S2Update = - lists:foldl - ( - fun bm_character_turn_update:add_to_db/2, - S1Update, - [DBQuery1|DBQueries] - ), - - S2Update. - --spec requires_update (bm_character_turn_update:type()) -> boolean(). -requires_update (Update) -> - Data = bm_character_turn_update:get_data(Update), - Battle = bm_character_turn_data:get_battle(Data), - Characters = bm_battle:get_characters(Battle), - - sh_array_util:none(fun bm_character:get_is_active/1, Characters). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec update_if_needed - ( - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -update_if_needed (Update) -> - case requires_update(Update) of - true -> update(Update); - _ -> Update - end. diff --git a/src/battlemap/game-logic/bm_turn_actions.erl b/src/battlemap/game-logic/bm_turn_actions.erl deleted file mode 100644 index c3e091a..0000000 --- a/src/battlemap/game-logic/bm_turn_actions.erl +++ /dev/null @@ -1,391 +0,0 @@ --module(bm_turn_actions). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - handle/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%% SWITCHING WEAPON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle_switch_weapon - ( - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -handle_switch_weapon (Update) -> - Data = bm_character_turn_update:get_data(Update), - Character = bm_character_turn_data:get_character(Data), - CharacterIX = bm_character_turn_data:get_character_ix(Data), - CharacterAttributes = bm_character:get_attributes(Character), - ArmorID = bm_character:get_armor_id(Character), - {PrimaryWeaponID, SecondaryWeaponID} = bm_character:get_weapon_ids(Character), - - UpdatedWeaponIDs = {SecondaryWeaponID, PrimaryWeaponID}, - UpdatedCharacterStatistics = - sh_statistics:new(CharacterAttributes, UpdatedWeaponIDs, ArmorID), - UpdatedCharacter = - bm_character:set_statistics - ( - UpdatedCharacterStatistics, - bm_character:set_weapon_ids(UpdatedWeaponIDs, Character) - ), - - TimelineItem = bm_turn_result:new_character_switched_weapons(CharacterIX), - - DBQuery = - sh_db_query:update_indexed - ( - bm_battle:get_characters_field(), - CharacterIX, - [ - sh_db_query:set_field - ( - bm_character:get_weapons_field(), - UpdatedWeaponIDs - ), - sh_db_query:set_field - ( - bm_character:get_statistics_field(), - UpdatedCharacterStatistics - ) - ] - ), - - UpdatedData = bm_character_turn_data:set_character(UpdatedCharacter, Data), - - S0Update = bm_character_turn_update:set_data(UpdatedData, Update), - - bm_character_turn_update:add_to_timeline(TimelineItem, DBQuery, S0Update). - -%%%% MOVING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_path_cost_and_destination - ( - bm_character_turn_data:type(), - list(bm_direction:type()) - ) - -> {non_neg_integer(), bm_location:type()}. -get_path_cost_and_destination (Data, Path) -> - Character = bm_character_turn_data:get_character(Data), - CharacterIX = bm_character_turn_data:get_character_ix(Data), - Battle = bm_character_turn_data:get_battle(Data), - Battlemap = bm_battle:get_battlemap(Battle), - - ForbiddenLocations = - array:foldl - ( - fun (IX, Char, Prev) -> - IsAlive = bm_character:get_is_alive(Char), - if - (IX == CharacterIX) -> Prev; - (not IsAlive) -> Prev; - true -> [bm_character:get_location(Char)|Prev] - end - end, - [], - bm_battle:get_characters(Battle) - ), - - {NewLocation, Cost} = - bm_movement:cross - ( - Battlemap, - ForbiddenLocations, - Path, - bm_character:get_location(Character) - ), - - {Cost, NewLocation}. - --spec assert_character_can_move - ( - bm_character_turn_data:type(), - non_neg_integer() - ) - -> 'ok'. -assert_character_can_move (Data, Cost) -> - Character = bm_character_turn_data:get_character(Data), - CharacterStatistics = bm_character:get_statistics(Character), - CharacterMovementPoints = - sh_statistics:get_movement_points(CharacterStatistics), - - true = (Cost =< CharacterMovementPoints), - - ok. - --spec commit_move - ( - bm_character_turn_update:type(), - list(bm_direction:type()), - bm_location:type() - ) - -> bm_character_turn_update:type(). -commit_move (Update, Path, NewLocation) -> - Data = bm_character_turn_update:get_data(Update), - Character = bm_character_turn_data:get_character(Data), - CharacterIX = bm_character_turn_data:get_character_ix(Data), - - UpdatedCharacter = bm_character:set_location(NewLocation, Character), - - UpdatedData = bm_character_turn_data:set_character(UpdatedCharacter, Data), - - TimelineItem = - bm_turn_result:new_character_moved(CharacterIX, Path, NewLocation), - - DBQuery = - sh_db_query:update_indexed - ( - bm_battle:get_characters_field(), - CharacterIX, - [ - sh_db_query:set_field - ( - bm_character:get_location_field(), - NewLocation - ) - ] - ), - - S0Update = - bm_character_turn_update:add_to_timeline - ( - TimelineItem, - DBQuery, - Update - ), - - bm_character_turn_update:set_data(UpdatedData, S0Update). - --spec handle_move - ( - bm_battle_action:type(), - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -handle_move (BattleAction, Update) -> - Data = bm_character_turn_update:get_data(Update), - Path = bm_battle_action:get_path(BattleAction), - - {PathCost, NewLocation} = get_path_cost_and_destination(Data, Path), - assert_character_can_move(Data, PathCost), - - commit_move(Update, Path, NewLocation). - -%%%% ATTACKING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle_attack_sequence - ( - bm_character:type(), - bm_character:type(), - list(bm_attack:step()) - ) - -> {list(bm_attack:type()), non_neg_integer(), non_neg_integer()}. -handle_attack_sequence -( - Character, - TargetCharacter, - AttackSequence -) -> - AttackPlannedEffects = - lists:map - ( - fun (AttackStep) -> - bm_attack:get_description_of - ( - AttackStep, - Character, - TargetCharacter - ) - end, - AttackSequence - ), - - lists:foldl - ( - fun - ( - AttackEffectCandidate, - {AttackValidEffects, AttackerHealth, DefenderHealth} - ) -> - {AttackResult, NewAttackerHealth, NewDefenderHealth} = - bm_attack:apply_to_healths - ( - AttackEffectCandidate, - AttackerHealth, - DefenderHealth - ), - case AttackResult of - nothing -> {AttackValidEffects, AttackerHealth, DefenderHealth}; - _ -> - { - (AttackValidEffects ++ [AttackResult]), - NewAttackerHealth, - NewDefenderHealth - } - end - end, - { - [], - bm_character:get_current_health(Character), - bm_character:get_current_health(TargetCharacter) - }, - AttackPlannedEffects - ). - --spec get_attack_sequence - ( - bm_character:type(), - bm_character:type() - ) - -> list(bm_attack:step()). -get_attack_sequence (Character, TargetCharacter) -> - Range = - bm_location:dist - ( - bm_character:get_location(Character), - bm_character:get_location(TargetCharacter) - ), - - {AttackingWeaponID, _} = bm_character:get_weapon_ids(Character), - {DefendingWeaponID, _} = bm_character:get_weapon_ids(TargetCharacter), - - AttackingWeapon = sh_weapon:from_id(AttackingWeaponID), - DefendingWeapon = sh_weapon:from_id(DefendingWeaponID), - - bm_attack:get_sequence(Range, AttackingWeapon, DefendingWeapon). - - --spec handle_attack - ( - bm_battle_action:type(), - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -handle_attack (BattleAction, Update) -> - Data = bm_character_turn_update:get_data(Update), - Battle = bm_character_turn_data:get_battle(Data), - Character = bm_character_turn_data:get_character(Data), - CharacterIX = bm_character_turn_data:get_character_ix(Data), - TargetIX = bm_battle_action:get_target_ix(BattleAction), - TargetCharacter = bm_battle:get_character(TargetIX, Battle), - - true = bm_character:get_is_alive(TargetCharacter), - - AttackSequence = get_attack_sequence(Character, TargetCharacter), - - {AttackEffects, RemainingAttackerHealth, RemainingDefenderHealth} = - handle_attack_sequence(Character, TargetCharacter, AttackSequence), - - UpdatedCharacter = - bm_character:set_current_health(RemainingAttackerHealth, Character), - - UpdatedBattle = - bm_battle:set_character - ( - TargetIX, - bm_character:set_current_health - ( - RemainingDefenderHealth, - TargetCharacter - ), - Battle - ), - - S0Data = bm_character_turn_data:set_battle(UpdatedBattle, Data), - S1Data = bm_character_turn_data:set_character(UpdatedCharacter, S0Data), - - TimelineItem = - bm_turn_result:new_character_attacked - ( - CharacterIX, - TargetIX, - AttackEffects - ), - - DBQuery0 = - sh_db_query:update_indexed - ( - bm_battle:get_characters_field(), - TargetIX, - [ - sh_db_query:set_field - ( - bm_character:get_current_health_field(), - RemainingDefenderHealth - ) - ] - ), - - DBQuery1 = - sh_db_query:update_indexed - ( - bm_battle:get_characters_field(), - CharacterIX, - [ - sh_db_query:set_field - ( - bm_character:get_current_health_field(), - RemainingAttackerHealth - ) - ] - ), - - S0Update = - bm_character_turn_update:add_to_timeline - ( - TimelineItem, - DBQuery0, - Update - ), - - S1Update = - bm_character_turn_update:add_to_db - ( - DBQuery1, - S0Update - ), - - S2Update = bm_character_turn_update:set_data(S1Data, S1Update), - - S3Update = - bm_victory:handle_character_lost_health - ( - CharacterIX, - RemainingAttackerHealth, - S2Update - ), - - S4Update = - bm_victory:handle_character_lost_health - ( - TargetIX, - RemainingDefenderHealth, - S3Update - ), - - S4Update. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle -( - bm_battle_action:type(), - bm_character_turn_update:type() -) --> bm_character_turn_update:type(). -handle (BattleAction, Update) -> - case bm_battle_action:get_category(BattleAction) of - move -> handle_move(BattleAction, Update); - switch_weapon -> handle_switch_weapon(Update); - attack -> handle_attack(BattleAction, Update) - end. diff --git a/src/battlemap/game-logic/bm_victory.erl b/src/battlemap/game-logic/bm_victory.erl deleted file mode 100644 index 327920a..0000000 --- a/src/battlemap/game-logic/bm_victory.erl +++ /dev/null @@ -1,194 +0,0 @@ --module(bm_victory). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - handle_character_lost_health/3 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --spec mark_players_characters_as_defeated - ( - non_neg_integer(), - array:array(bm_character:type()) - ) -> {array:array(bm_character:type()), list(non_neg_integer())}. -mark_players_characters_as_defeated (PlayerIX, Characters) -> - sh_array_util:mapiff - ( - fun (Character) -> - (bm_character:get_player_index(Character) == PlayerIX) - end, - fun (Character) -> - bm_character:set_is_defeated(true, Character) - end, - Characters - ). - --spec add_db_query_to_mark_character_as_defeated - ( - non_neg_integer(), - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -add_db_query_to_mark_character_as_defeated (IX, Update) -> - 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_is_defeated_field(), - true - ) - ] - ), - Update - ). - --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} = - mark_players_characters_as_defeated(PlayerIX, Characters), - - S1Update = - lists:foldl - ( - fun add_db_query_to_mark_character_as_defeated/2, - 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_player:get_is_active_field(), - false - ) - ] - ), - - S3Update = - bm_character_turn_update:add_to_timeline - ( - bm_turn_result:new_player_lost(PlayerIX), - DBQuery, - S2Update - ), - - S3Update. - - --spec actually_handle_character_lost_health - ( - non_neg_integer(), - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -actually_handle_character_lost_health (CharIX, 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, - 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, - Characters - ), - - case StillHasAliveChar of - true -> Update; - _ -> handle_player_defeat(CharacterPlayerIX, Update) - end - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle_character_lost_health - ( - non_neg_integer(), - integer(), - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -handle_character_lost_health (_, Health, Update) when (Health > 0) -> Update; -handle_character_lost_health (CharIX, _Health, Update) -> - Data = bm_character_turn_update:get_data(Update), - S1Data = bm_character_turn_data:clean_battle(Data), - S1Update = bm_character_turn_update:set_data(S1Data, Update), - - S2Update = actually_handle_character_lost_health(CharIX, S1Update), - - S2Data = bm_character_turn_update:get_data(S2Update), - S3Data = bm_character_turn_data:refresh_character(S2Data), - S3Update = bm_character_turn_update:set_data(S3Data, S2Update), - - S3Update. diff --git a/src/battlemap/io/bm_security.erl b/src/battlemap/io/bm_security.erl deleted file mode 100644 index 787082a..0000000 --- a/src/battlemap/io/bm_security.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(bm_security). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - assert_identity/2, - lock_queries/1, - unlock_queries/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec assert_identity (any(), any()) -> 'unimplemented'. -assert_identity (_PlayerID, _SessionToken) -> unimplemented. - --spec lock_queries (any()) -> 'unimplemented'. -lock_queries (_PlayerID) -> unimplemented. - --spec unlock_queries (any()) -> 'unimplemented'. -unlock_queries (_PlayerID) -> unimplemented. diff --git a/src/battlemap/query/bm_character_turn.erl b/src/battlemap/query/bm_character_turn.erl deleted file mode 100644 index 7a7476c..0000000 --- a/src/battlemap/query/bm_character_turn.erl +++ /dev/null @@ -1,282 +0,0 @@ --module(bm_character_turn). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../../include/yaws_api.hrl"). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([out/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%-spec send_to_database (list(database_diff:type()), character_turn_request:type()) -> 'ok'. - - -%%%% REQUEST DECODING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec decode_request (binary()) -> bm_character_turn_request:type(). -decode_request (BinaryRequest) -> - JSONMap = jiffy:decode(BinaryRequest, [return_maps]), - - bm_character_turn_request:decode(JSONMap). - -%%%% USER AUTHENTICATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec authenticate_user (bm_character_turn_request:type()) -> 'ok'. -authenticate_user (Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - SessionToken = bm_character_turn_request:get_session_token(Request), - - bm_security:assert_identity(PlayerID, SessionToken), - bm_security:lock_queries(PlayerID), - - ok. - -%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec fetch_data - ( - bm_character_turn_request:type() - ) - -> bm_character_turn_data:type(). -fetch_data (Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - BattleID = bm_character_turn_request:get_battle_id(Request), - CharacterIX = bm_character_turn_request:get_character_ix(Request), - Battle = sh_timed_cache:fetch(battle_db, PlayerID, BattleID), - - bm_character_turn_data:new(Battle, CharacterIX). - -%%%% ASSERTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec assert_user_is_current_player - ( - bm_character_turn_data:type(), - bm_character_turn_request:type() - ) -> 'ok'. -assert_user_is_current_player (Data, Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - Battle = bm_character_turn_data:get_battle(Data), - CurrentPlayerTurn = bm_battle:get_current_player_turn(Battle), - CurrentPlayerIX = bm_player_turn:get_player_ix(CurrentPlayerTurn), - CurrentPlayer = bm_battle:get_player(CurrentPlayerIX, Battle), - - true = (PlayerID == bm_player:get_id(CurrentPlayer)), - - ok. - --spec assert_user_owns_played_character - ( - bm_character_turn_data:type(), - bm_character_turn_request:type() - ) -> 'ok'. -assert_user_owns_played_character (Data, Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - Battle = bm_character_turn_data:get_battle(Data), - Players = bm_battle:get_players(Battle), - Character = bm_character_turn_data:get_character(Data), - CharacterPlayerIX = bm_character:get_player_index(Character), - CharacterPlayer = array:get(CharacterPlayerIX, Players), - CharacterPlayerID = bm_player:get_id(CharacterPlayer), - - true = (PlayerID == CharacterPlayerID), - - ok. - --spec assert_character_can_be_played (bm_character_turn_data:type()) -> 'ok'. -assert_character_can_be_played (Data) -> - Character = bm_character_turn_data:get_character(Data), - - true = bm_character:get_is_active(Character), - - ok. - --spec assert_user_permissions - ( - bm_character_turn_data:type(), - bm_character_turn_request:type() - ) -> 'ok'. -assert_user_permissions (Data, Request) -> - assert_user_is_current_player(Data, Request), - assert_user_owns_played_character(Data, Request), - assert_character_can_be_played(Data), - - ok. - -%%%% QUERY LOGIC HANDLING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec finalize_character - ( - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -finalize_character (Update) -> - Data = bm_character_turn_update:get_data(Update), - Character = bm_character_turn_data:get_character(Data), - - DisabledCharacter = bm_character:set_is_active(false, Character), - UpdatedData = bm_character_turn_data:set_character(DisabledCharacter, Data), - FinalizedData = bm_character_turn_data:clean_battle(UpdatedData), - - DBQuery = - sh_db_query:update_indexed - ( - bm_battle:get_characters_field(), - bm_character_turn_data:get_character_ix(Data), - [ sh_db_query:set_field(bm_character:get_is_active_field(), false) ] - ), - - S0Update = bm_character_turn_update:set_data(FinalizedData, Update), - S1Update = bm_character_turn_update:add_to_db(DBQuery, S0Update), - - S1Update. - --spec handle_actions - ( - bm_character_turn_data:type(), - bm_character_turn_request:type() - ) - -> bm_character_turn_update:type(). -handle_actions (Data, Request) -> - Actions = bm_character_turn_request:get_actions(Request), - - EmptyUpdate = bm_character_turn_update:new(Data), - PostActionsUpdate = - lists:foldl(fun bm_turn_actions:handle/2, EmptyUpdate, Actions), - - finalize_character(PostActionsUpdate). - --spec update_timeline - ( - bm_character_turn_update:type() - ) - -> bm_character_turn_update:type(). -update_timeline (Update) -> - NewTimelineElements = bm_character_turn_update:get_timeline(Update), - Data = bm_character_turn_update:get_data(Update), - Battle = bm_character_turn_data:get_battle(Data), - PlayerTurn = bm_battle:get_current_player_turn(Battle), - PlayerIX = bm_player_turn:get_player_ix(PlayerTurn), - Player = bm_battle:get_player(PlayerIX, Battle), - - UpdatedPlayer = bm_player:add_to_timeline(NewTimelineElements, Player), - UpdatedBattle = bm_battle:set_player(PlayerIX, UpdatedPlayer, Battle), - UpdatedData = bm_character_turn_data:set_battle(UpdatedBattle, Data), - - DBQuery = - sh_db_query:update_indexed - ( - bm_battle:get_players_field(), - PlayerIX, - [ - sh_db_query:add_to_field - ( - bm_player:get_timeline_field(), - NewTimelineElements, - true % We add those to the start of the list - ) - ] - ), - - S0Update = bm_character_turn_update:set_data(UpdatedData, Update), - S1Update = bm_character_turn_update:add_to_db(DBQuery, S0Update), - - S1Update. - - --spec update_data - ( - bm_character_turn_data:type(), - bm_character_turn_request:type() - ) - -> bm_character_turn_update:type(). -update_data (Data, Request) -> - PostActionsUpdate = handle_actions(Data, Request), - PostCharacterTurnUpdate = update_timeline(PostActionsUpdate), - - bm_next_turn:update_if_needed(PostCharacterTurnUpdate). - -%%%% DATABASE UPDATES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec send_to_database - ( - bm_character_turn_update:type(), - bm_character_turn_request:type() - ) - -> 'ok'. -send_to_database (Update, Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - BattleID = bm_character_turn_request:get_battle_id(Request), - Ops = bm_character_turn_update:get_db(Update), - Query = sh_db_query:new(battle_db, BattleID, {user, PlayerID}, Ops), - - sh_database:commit(Query), - - ok. - --spec send_to_cache - ( - bm_character_turn_update:type(), - bm_character_turn_request:type() - ) - -> 'ok'. -send_to_cache (Update, Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - BattleID = bm_character_turn_request:get_battle_id(Request), - Data = bm_character_turn_update:get_data(Update), - Battle = bm_character_turn_data:get_battle(Data), - - sh_timed_cache:update(battle_db, PlayerID, BattleID, Battle), - - ok. - --spec commit_update - ( - bm_character_turn_update:type(), - bm_character_turn_request:type() - ) - -> 'ok'. -commit_update (Update, Request) -> - send_to_database(Update, Request), - send_to_cache(Update, Request), - - ok. - -%%%% USER DISCONNECTION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec disconnect_user (bm_character_turn_request:type()) -> 'ok'. -disconnect_user (Request) -> - PlayerID = bm_character_turn_request:get_player_id(Request), - - bm_security:unlock_queries(PlayerID), - - ok. - -%%%% REPLY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_reply (bm_character_turn_update:type()) -> binary(). -generate_reply (Update) -> - NewTimelineItems = bm_character_turn_update:get_timeline(Update), - - TurnResultReply = bm_turn_results:generate(NewTimelineItems), - - jiffy:encode([TurnResultReply]). - -%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle (binary()) -> binary(). -handle (EncodedRequest) -> - Request = decode_request(EncodedRequest), - authenticate_user(Request), - Data = fetch_data(Request), - assert_user_permissions(Data, Request), - Update = update_data(Data, Request), - commit_update(Update, Request), - disconnect_user(Request), - generate_reply(Update). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -out(A) -> - { - content, - "application/json; charset=UTF-8", - handle(A#arg.clidata) - }. diff --git a/src/battlemap/query/bm_load_state.erl b/src/battlemap/query/bm_load_state.erl deleted file mode 100644 index 505ec3b..0000000 --- a/src/battlemap/query/bm_load_state.erl +++ /dev/null @@ -1,159 +0,0 @@ --module(bm_load_state). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../../include/yaws_api.hrl"). - --record -( - input, - { - player_id :: bm_player:id(), - session_token :: binary(), - battle_id :: binary() - } -). - --record -( - query_state, - { - battle :: bm_battle:type() - } -). - --type input() :: #input{}. --type query_state() :: #query_state{}. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([out/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec parse_input (binary()) -> input(). -parse_input (Req) -> - JSONReqMap = jiffy:decode(Req, [return_maps]), - PlayerID = maps:get(<<"pid">>, JSONReqMap), - SessionToken = maps:get(<<"stk">>, JSONReqMap), - BattleID = maps:get(<<"bmi">>, JSONReqMap), - - #input - { - player_id = PlayerID, - session_token = SessionToken, - battle_id = BattleID - }. - --spec fetch_data (input()) -> query_state(). -fetch_data (Input) -> - PlayerID = Input#input.player_id, - BattleID = Input#input.battle_id, - - Battle = sh_timed_cache:fetch(battle_db, PlayerID, BattleID), - - #query_state - { - battle = Battle - }. - --spec generate_reply(query_state(), input()) -> binary(). -generate_reply (QueryState, Input) -> - PlayerID = Input#input.player_id, - Battle = QueryState#query_state.battle, - Players = bm_battle:get_players(Battle), - - PlayerIX = - sh_array_util:first - ( - fun (Player) -> - (bm_player:get_id(Player) == PlayerID) - end, - Players - ), - - true = (PlayerIX >= 0), - - SetTimeline = - bm_set_timeline:generate - ( - bm_battle:get_encoded_last_turns_effects(Battle) - ), - - SetMap = bm_set_map:generate(bm_battle:get_battlemap(Battle)), - - AddCharList = - array:sparse_to_list - ( - array:map - ( - fun (IX, Character) -> - bm_add_char:generate(IX, Character, PlayerIX) - end, - bm_battle:get_characters(Battle) - ) - ), - - AddWeaponList = - lists:map - ( - fun (WeaponID) -> - bm_add_weapon:generate(sh_weapon:from_id(WeaponID)) - end, - bm_battle:get_used_weapon_ids(Battle) - ), - - AddArmorList = - lists:map - ( - fun (ArmorID) -> - bm_add_armor:generate(sh_armor:from_id(ArmorID)) - end, - bm_battle:get_used_armor_ids(Battle) - ), - - AddTileList = - lists:map - ( - fun (TileID) -> - bm_add_tile:generate(bm_tile:from_id(TileID)) - end, - bm_battle:get_used_tile_ids(Battle) - ), - - OutputList = - ( - AddTileList - ++ [SetTimeline, SetMap | AddWeaponList] - ++ AddArmorList - ++ AddCharList - ), - Output = jiffy:encode(OutputList), - - Output. - --spec handle (binary()) -> binary(). -handle (Req) -> - Input = parse_input(Req), - bm_security:assert_identity - ( - Input#input.player_id, - Input#input.session_token - ), - bm_security:lock_queries(Input#input.player_id), - QueryState = fetch_data(Input), - bm_security:unlock_queries(Input#input.player_id), - generate_reply(QueryState, Input). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -out(A) -> - { - content, - "application/json; charset=UTF-8", - handle(A#arg.clidata) - }. diff --git a/src/battlemap/reply/bm_add_armor.erl b/src/battlemap/reply/bm_add_armor.erl deleted file mode 100644 index 4f098bd..0000000 --- a/src/battlemap/reply/bm_add_armor.erl +++ /dev/null @@ -1,34 +0,0 @@ --module(bm_add_armor). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec encode_category (sh_armor:category()) -> binary(). -encode_category (kinetic) -> <<"k">>; -encode_category (leather) -> <<"l">>; -encode_category (chain) -> <<"c">>; -encode_category (plate) -> <<"p">>. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (sh_armor:type()) -> {list(any())}. -generate (Armor) -> - { - [ - {<<"msg">>, <<"add_armor">>}, - {<<"id">>, sh_armor:get_id(Armor)}, - {<<"nam">>, sh_armor:get_name(Armor)}, - {<<"ct">>, encode_category(sh_armor:get_category(Armor))}, - {<<"cf">>, sh_armor:get_coefficient(Armor)} - ] - }. diff --git a/src/battlemap/reply/bm_add_char.erl b/src/battlemap/reply/bm_add_char.erl deleted file mode 100644 index 4dab700..0000000 --- a/src/battlemap/reply/bm_add_char.erl +++ /dev/null @@ -1,83 +0,0 @@ --module(bm_add_char). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/3]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec rank_to_string (bm_character:rank()) -> binary(). -rank_to_string (Rank) -> - case Rank of - optional -> <<"o">>; - target -> <<"t">>; - commander -> <<"c">> - end. - --spec attributes_as_json - ( - sh_attributes:type() - ) -> - {list({binary(), non_neg_integer()})}. -attributes_as_json (Attributes) -> - { - [ - {<<"con">>, sh_attributes:get_constitution(Attributes)}, - {<<"dex">>, sh_attributes:get_dexterity(Attributes)}, - {<<"int">>, sh_attributes:get_intelligence(Attributes)}, - {<<"min">>, sh_attributes:get_mind(Attributes)}, - {<<"spe">>, sh_attributes:get_speed(Attributes)}, - {<<"str">>, sh_attributes:get_strength(Attributes)} - ] - }. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate - ( - non_neg_integer(), - bm_character:type(), - non_neg_integer() - ) - -> {list(any())}. -generate (IX, Character, PlayerIX) -> - Attributes = bm_character:get_attributes(Character), - {ActiveWeapon, SecondaryWeapon} = bm_character:get_weapon_ids(Character), - CharacterPlayerIX = bm_character:get_player_index(Character), - Location = bm_character:get_location(Character), - - { - [ - {<<"msg">>, <<"add_char">>}, - {<<"ix">>, IX}, - {<<"nam">>, bm_character:get_name(Character)}, - {<<"rnk">>, rank_to_string(bm_character:get_rank(Character))}, - {<<"ico">>, bm_character:get_icon(Character)}, - {<<"prt">>, bm_character:get_portrait(Character)}, - { - <<"hea">>, - bm_character:get_current_health(Character) - }, - {<<"lc">>, bm_location:encode(Location)}, - {<<"pla">>, CharacterPlayerIX}, - { - <<"ena">>, - ( - bm_character:get_is_active(Character) - and (CharacterPlayerIX == PlayerIX) - ) - }, - {<<"dea">>, bm_character:get_is_defeated(Character)}, - {<<"att">>, attributes_as_json(Attributes)}, - {<<"awp">>, ActiveWeapon}, - {<<"swp">>, SecondaryWeapon}, - {<<"ar">>, bm_character:get_armor_id(Character)} - ] - }. diff --git a/src/battlemap/reply/bm_add_tile.erl b/src/battlemap/reply/bm_add_tile.erl deleted file mode 100644 index 1845ffc..0000000 --- a/src/battlemap/reply/bm_add_tile.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(bm_add_tile). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (bm_tile:type()) -> {list(any())}. -generate (Tile) -> - { - [ - {<<"msg">>, <<"add_tile">>}, - {<<"id">>, bm_tile:get_id(Tile)}, - {<<"nam">>, bm_tile:get_name(Tile)}, - {<<"ct">>, bm_tile:get_cost(Tile)}, - {<<"rmi">>, bm_tile:get_range_minimum(Tile)}, - {<<"rma">>, bm_tile:get_range_maximum(Tile)} - ] - }. diff --git a/src/battlemap/reply/bm_add_weapon.erl b/src/battlemap/reply/bm_add_weapon.erl deleted file mode 100644 index 3473265..0000000 --- a/src/battlemap/reply/bm_add_weapon.erl +++ /dev/null @@ -1,54 +0,0 @@ --module(bm_add_weapon). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec encode_range_type (sh_weapon:range_type()) -> binary(). -encode_range_type (melee) -> <<"m">>; -encode_range_type (ranged) -> <<"r">>. - --spec encode_range_modifier (sh_weapon:range_modifier()) -> binary(). -encode_range_modifier (long) -> <<"l">>; -encode_range_modifier (short) -> <<"s">>. - --spec encode_damage_type (sh_weapon:damage_type()) -> binary(). -encode_damage_type (slash) -> <<"s">>; -encode_damage_type (pierce) -> <<"p">>; -encode_damage_type (blunt) -> <<"b">>. - --spec encode_damage_modifier (sh_weapon:damage_modifier()) -> binary(). -encode_damage_modifier (heavy) -> <<"h">>; -encode_damage_modifier (light) -> <<"l">>. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (sh_weapon:type()) -> {list(any())}. -generate (Weapon) -> - { - [ - {<<"msg">>, <<"add_weapon">>}, - {<<"id">>, sh_weapon:get_id(Weapon)}, - {<<"nam">>, sh_weapon:get_name(Weapon)}, - {<<"rt">>, encode_range_type(sh_weapon:get_range_type(Weapon))}, - { - <<"rm">>, - encode_range_modifier(sh_weapon:get_range_modifier(Weapon)) - }, - {<<"dt">>, encode_damage_type(sh_weapon:get_damage_type(Weapon))}, - { - <<"dm">>, - encode_damage_modifier(sh_weapon:get_damage_modifier(Weapon)) - }, - {<<"cf">>, sh_weapon:get_coefficient(Weapon)} - ] - }. diff --git a/src/battlemap/reply/bm_set_map.erl b/src/battlemap/reply/bm_set_map.erl deleted file mode 100644 index 9989fa0..0000000 --- a/src/battlemap/reply/bm_set_map.erl +++ /dev/null @@ -1,31 +0,0 @@ --module(bm_set_map). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (bm_battlemap:type()) -> {list(any())}. -generate (Battlemap) -> - { - [ - {<<"msg">>, <<"set_map">>}, - {<<"w">>, bm_battlemap:get_width(Battlemap)}, - {<<"h">>, bm_battlemap:get_height(Battlemap)}, - { - <<"t">>, - array:sparse_to_list(bm_battlemap:get_tile_class_ids(Battlemap)) - } - ] - }. diff --git a/src/battlemap/reply/bm_set_timeline.erl b/src/battlemap/reply/bm_set_timeline.erl deleted file mode 100644 index cea3790..0000000 --- a/src/battlemap/reply/bm_set_timeline.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(bm_set_timeline). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (list(any())) -> {list(any())}. -generate (EncodedClientUpdate) -> - io:format("~nSending timeline:~n~p~n", [EncodedClientUpdate]), - { - [ - {<<"msg">>, <<"set_timeline">>}, - {<<"cnt">>, EncodedClientUpdate} - ] - }. diff --git a/src/battlemap/reply/bm_turn_results.erl b/src/battlemap/reply/bm_turn_results.erl deleted file mode 100644 index d47a693..0000000 --- a/src/battlemap/reply/bm_turn_results.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(bm_turn_results). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (list(any())) -> {list(any())}. -generate (EncodedClientUpdate) -> - io:format("~nSending turn results:~n~p~n", [EncodedClientUpdate]), - { - [ - {<<"msg">>, <<"turn_results">>}, - {<<"cnt">>, EncodedClientUpdate} - ] - }. diff --git a/src/battlemap/struct/bm_attack.erl b/src/battlemap/struct/bm_attack.erl deleted file mode 100644 index a1ce027..0000000 --- a/src/battlemap/struct/bm_attack.erl +++ /dev/null @@ -1,306 +0,0 @@ --module(bm_attack). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type order() :: ('first' | 'second' | 'counter'). --type precision() :: ('misses' | 'grazes' | 'hits'). - --record -( - attack, - { - order :: order(), - precision :: precision(), - is_critical :: boolean(), - is_parry :: boolean(), - damage :: non_neg_integer() - } -). - --opaque type() :: #attack{}. --type maybe_type() :: ('nothing' | type()). --opaque step() :: {order(), boolean()}. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([type/0, maybe_type/0, step/0]). - --export -( - [ - get_sequence/3, - get_description_of/3, - apply_to_healths/3 - ] -). - --export -( - [ - encode/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec roll_precision - ( - sh_statistics:type(), - sh_statistics:type() - ) - -> precision(). -roll_precision (AttackerStatistics, DefenderStatistics) -> - DefenderDodges = sh_statistics:get_dodges(DefenderStatistics), - AttackerAccuracy = sh_statistics:get_accuracy(AttackerStatistics), - MissChance = max(0, (DefenderDodges - AttackerAccuracy)), - case sh_roll:percentage() of - X when (X =< MissChance) -> misses; - X when (X =< (MissChance * 2)) -> grazes; - _ -> hits - end. - --spec roll_damage - ( - sh_statistics:type(), - sh_statistics:type() - ) - -> {non_neg_integer(), boolean()}. -roll_damage (AttackerStatistics, _DefenderStatistics) -> - {MinimumDamage, MaximumDamage} = - sh_statistics:get_damages(AttackerStatistics), - MaximumRoll = max(1, MaximumDamage - MinimumDamage), - BaseDamage = MinimumDamage + (rand:uniform(MaximumRoll) - 1), - CriticalHitChance = sh_statistics:get_critical_hits(AttackerStatistics), - case sh_roll:percentage() of - X when (X =< CriticalHitChance) -> {(BaseDamage * 2), true}; - _ -> {BaseDamage, false} - end. - --spec roll_parry (sh_statistics:type()) -> boolean(). -roll_parry (DefenderStatistics) -> - DefenderParryChance = sh_statistics:get_parries(DefenderStatistics), - (sh_roll:percentage() =< DefenderParryChance). - --spec effect_of_attack - ( - order(), - bm_character:type(), - bm_character:type(), - boolean() - ) - -> type(). -effect_of_attack (Order, Attacker, Defender, CanParry) -> - AttackerStatistics = bm_character:get_statistics(Attacker), - DefenderStatistics = bm_character:get_statistics(Defender), - - ParryIsSuccessful = (CanParry and roll_parry(DefenderStatistics)), - - {ActualAtkStatistics, ActualDefStatistics} = - case ParryIsSuccessful of - true -> {DefenderStatistics, AttackerStatistics}; - false -> {AttackerStatistics, DefenderStatistics} - end, - {ActualAttacker, ActualDefender} = - case ParryIsSuccessful of - true -> {Defender, Attacker}; - false -> {Attacker, Defender} - end, - - ActualDefArmor = sh_armor:from_id(bm_character:get_armor_id(ActualDefender)), - {ActualAtkWeaponID, _} = bm_character:get_weapon_ids(ActualAttacker), - ActualAtkWeaponDmgType = - sh_weapon:get_damage_type(sh_weapon:from_id(ActualAtkWeaponID)), - - Precision = roll_precision(ActualAtkStatistics, ActualDefStatistics), - {Damage, IsCritical} = roll_damage(ActualAtkStatistics, ActualDefStatistics), - S0Damage = - case Precision of - misses -> 0; - grazes -> trunc(Damage / 2); - hits -> Damage - end, - ArmorResistance = - sh_armor:get_resistance_to(ActualAtkWeaponDmgType, ActualDefArmor), - ActualDamage = max(0, (S0Damage - ArmorResistance)), - - #attack - { - order = Order, - precision = Precision, - is_critical = IsCritical, - is_parry = ParryIsSuccessful, - damage = ActualDamage - }. - --spec encode_order (order()) -> binary(). -encode_order (first) -> <<"f">>; -encode_order (counter) -> <<"c">>; -encode_order (second) -> <<"s">>. - --spec encode_precision (precision()) -> binary(). -encode_precision (hits) -> <<"h">>; -encode_precision (grazes) -> <<"g">>; -encode_precision (misses) -> <<"m">>. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --spec get_description_of - ( - step(), - bm_character:type(), - bm_character:type() - ) - -> maybe_type(). -get_description_of ({first, CanParry}, Attacker, Defender) -> - effect_of_attack(first, Attacker, Defender, CanParry); -get_description_of ({second, CanParry}, Attacker, Defender) -> - AttackerStatistics = bm_character:get_statistics(Attacker), - AttackerDoubleAttackChange = - sh_statistics:get_double_hits(AttackerStatistics), - - case sh_roll:percentage() of - X when (X =< AttackerDoubleAttackChange) -> - effect_of_attack (second, Attacker, Defender, CanParry); - - _ -> - nothing - end; -get_description_of ({counter, CanParry}, Attacker, Defender) -> - effect_of_attack(counter, Defender, Attacker, CanParry). - --spec apply_to_healths - ( - maybe_type(), - non_neg_integer(), - non_neg_integer() - ) - -> {maybe_type(), non_neg_integer(), non_neg_integer()}. -apply_to_healths -( - nothing, - AttackerHealth, - DefenderHealth -) -> - {nothing, AttackerHealth, DefenderHealth}; -apply_to_healths -( - _Attack, - AttackerHealth, - DefenderHealth -) -when -( - (AttackerHealth =< 0) - or (DefenderHealth =< 0) -) -> - {nothing, AttackerHealth, DefenderHealth}; -apply_to_healths -( - Attack, - AttackerHealth, - DefenderHealth -) -when -( - ( - (not Attack#attack.is_parry) - and ((Attack#attack.order == first) or (Attack#attack.order == second)) - ) - or - ( - Attack#attack.is_parry - and (Attack#attack.order == counter) - ) -) -> - Damage = Attack#attack.damage, - - { - Attack, - AttackerHealth, - (DefenderHealth - Damage) - }; -apply_to_healths -( - Attack, - AttackerHealth, - DefenderHealth -) -when -( - ( - (not Attack#attack.is_parry) - and (Attack#attack.order == counter) - ) - or - ( - Attack#attack.is_parry - and ((Attack#attack.order == first) or (Attack#attack.order == second)) - ) -) -> - Damage = Attack#attack.damage, - - { - Attack, - (AttackerHealth - Damage), - DefenderHealth - }. - --spec get_sequence - ( - non_neg_integer(), - sh_weapon:type(), - sh_weapon:type() - ) - -> list(step()). -get_sequence (AttackRange, AttackerWeapon, DefenderWeapon) -> - {AttackerDefenseRange, AttackerAttackRange} = - sh_weapon:get_ranges(AttackerWeapon), - {DefenderDefenseRange, DefenderAttackRange} = - sh_weapon:get_ranges(DefenderWeapon), - - AttackerCanAttack = (AttackRange =< AttackerAttackRange), - AttackerCanAttack = true, - AttackerCanDefend = - (AttackerCanAttack and (AttackRange > AttackerDefenseRange)), - AttackerCanParry = - (AttackerCanDefend and sh_weapon:can_parry(AttackerWeapon)), - - DefenderCanAttack = (AttackRange =< DefenderAttackRange), - DefenderCanDefend = - (DefenderCanAttack and (AttackRange > DefenderDefenseRange)), - DefenderCanParry = - (DefenderCanDefend and sh_weapon:can_parry(DefenderWeapon)), - - First = {first, DefenderCanParry}, - Second = {second, DefenderCanParry}, - Counter = {counter, AttackerCanParry}, - - if - (not DefenderCanDefend) -> - [First, Second]; - - true -> - [First, Counter, Second] - end. - --spec encode (type()) -> {list(any())}. -encode (Attack) -> - Order = Attack#attack.order, - Precision = Attack#attack.precision, - IsCritical = Attack#attack.is_critical, - IsParry = Attack#attack.is_parry, - Damage = Attack#attack.damage, - - { - [ - {<<"ord">>, encode_order(Order)}, - {<<"pre">>, encode_precision(Precision)}, - {<<"cri">>, IsCritical}, - {<<"par">>, IsParry}, - {<<"dmg">>, Damage} - ] - }. diff --git a/src/battlemap/struct/bm_battle.erl b/src/battlemap/struct/bm_battle.erl deleted file mode 100644 index 4c93460..0000000 --- a/src/battlemap/struct/bm_battle.erl +++ /dev/null @@ -1,216 +0,0 @@ --module(bm_battle). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - battle, - { - id :: id(), - used_armor_ids :: list(sh_armor:id()), - used_weapon_ids :: list(sh_weapon:id()), - used_tile_ids :: list(bm_tile:id()), - battlemap :: bm_battlemap:type(), - characters :: array:array(bm_character:type()), - players :: array:array(bm_player:type()), - current_player_turn :: bm_player_turn:type() - } -). - --opaque type() :: #battle{}. - --export_type([type/0, id/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_used_weapon_ids/1, - get_used_armor_ids/1, - get_used_tile_ids/1, - get_battlemap/1, - get_characters/1, - get_character/2, - get_players/1, - get_player/2, - get_current_player_turn/1, - get_encoded_last_turns_effects/1, - - set_battlemap/2, - set_characters/2, - set_character/3, - set_players/2, - set_player/3, - set_current_player_turn/2, - - get_characters_field/0, - get_players_field/0, - get_current_player_turn_field/0 - ] -). - --export -( - [ - new/7 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -get_all_timelines (Result, CurrentIndex, EndPoint, ArraySize, Players) -> - Player = array:get(CurrentIndex, Players), - Timeline = bm_player:get_timeline(Player), - NextIndex = ((CurrentIndex + 1) rem ArraySize), - NextResult = (Timeline ++ Result), - case CurrentIndex of - EndPoint -> - NextResult; - - _ -> - get_all_timelines(NextResult, NextIndex, EndPoint, ArraySize, Players) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_id (type()) -> id(). -get_id (Battle) -> Battle#battle.id. - --spec get_used_weapon_ids (type()) -> list(sh_weapon:id()). -get_used_weapon_ids (Battle) -> Battle#battle.used_weapon_ids. - --spec get_used_armor_ids (type()) -> list(sh_armor:id()). -get_used_armor_ids (Battle) -> Battle#battle.used_armor_ids. - --spec get_used_tile_ids (type()) -> list(bm_tile:id()). -get_used_tile_ids (Battle) -> Battle#battle.used_tile_ids. - --spec get_battlemap (type()) -> bm_battlemap:type(). -get_battlemap (Battle) -> Battle#battle.battlemap. - --spec get_characters (type()) -> array:array(bm_character:type()). -get_characters (Battle) -> Battle#battle.characters. - --spec get_character (non_neg_integer(), type()) -> bm_character:type(). -get_character (IX, Battle) -> - array:get(IX, Battle#battle.characters). - --spec get_players (type()) -> array:array(bm_player:type()). -get_players (Battle) -> - Battle#battle.players. - --spec get_player (non_neg_integer(), type()) -> bm_player:type(). -get_player (IX, Battle) -> - array:get(IX, Battle#battle.players). - --spec get_current_player_turn (type()) -> bm_player_turn:type(). -get_current_player_turn (Battle) -> - Battle#battle.current_player_turn. - --spec get_encoded_last_turns_effects (type()) -> list(any()). -get_encoded_last_turns_effects (Battle) -> - CurrentPlayerTurn = Battle#battle.current_player_turn, - Players = Battle#battle.players, - CurrentPlayerIX = bm_player_turn:get_player_ix(CurrentPlayerTurn), - - PlayersCount = array:size(Players), - StartingPoint = ((CurrentPlayerIX + 1) rem PlayersCount), - get_all_timelines([], StartingPoint, CurrentPlayerIX, PlayersCount, Players). - --spec set_battlemap (bm_battlemap:type(), type()) -> type(). -set_battlemap (Battlemap, Battle) -> - Battle#battle - { - battlemap = Battlemap - }. - --spec set_characters (array:array(bm_character:type()), type()) -> type(). -set_characters (Characters, Battle) -> - Battle#battle - { - characters = Characters - }. - --spec set_character (non_neg_integer(), bm_character:type(), type()) -> type(). -set_character (IX, Character, Battle) -> - Battle#battle - { - characters = - array:set - ( - IX, - Character, - Battle#battle.characters - ) - }. - --spec set_players (array:array(bm_player:type()), type()) -> type(). -set_players (Players, Battle) -> - Battle#battle - { - players = Players - }. - --spec set_player (non_neg_integer(), bm_player:type(), type()) -> type(). -set_player (IX, Player, Battle) -> - Battle#battle - { - players = - array:set - ( - IX, - Player, - Battle#battle.players - ) - }. - --spec set_current_player_turn (bm_player_turn:type(), type()) -> type(). -set_current_player_turn (PlayerTurn, Battle) -> - Battle#battle - { - current_player_turn = PlayerTurn - }. - --spec new - ( - id(), - list(bm_player:type()), - bm_battlemap:type(), - list(bm_character:type()), - list(sh_weapon:id()), - list(sh_armor:id()), - list(bm_tile:id()) - ) - -> type(). -new (ID, PlayersAsList, Battlemap, CharactersAsList, UWIDs, UAIDs, UTIDs) -> - #battle - { - id = ID, - used_weapon_ids = UWIDs, - used_armor_ids = UAIDs, - used_tile_ids = UTIDs, - battlemap = Battlemap, - characters = array:from_list(CharactersAsList), - players = array:from_list(PlayersAsList), - current_player_turn = bm_player_turn:new(0, 0) - }. - - --spec get_characters_field () -> non_neg_integer(). -get_characters_field () -> #battle.characters. - --spec get_players_field () -> non_neg_integer(). -get_players_field () -> #battle.players. - --spec get_current_player_turn_field () -> non_neg_integer(). -get_current_player_turn_field () -> #battle.current_player_turn. diff --git a/src/battlemap/struct/bm_battle_action.erl b/src/battlemap/struct/bm_battle_action.erl deleted file mode 100644 index 1bc0f3b..0000000 --- a/src/battlemap/struct/bm_battle_action.erl +++ /dev/null @@ -1,114 +0,0 @@ --module(bm_battle_action). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - move, - { - path :: list(bm_direction:enum()) - } -). - --record -( - switch_weapon, - { - } -). - --record -( - attack, - { - target_ix :: non_neg_integer() - } -). - --type category() :: ('move' | 'switch_weapon' | 'attack' | 'nothing'). --opaque type() :: (#move{} | #switch_weapon{} | #attack{}). - --export_type([category/0, type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - decode/1, - can_follow/2 - ] -). - --export -( - [ - get_path/1, - get_target_ix/1, - get_category/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec decode_mov_action (map()) -> type(). -decode_mov_action (JSONMap) -> - PathInBinary = maps:get(<<"p">>, JSONMap), - Path = lists:map(fun bm_direction:decode/1, PathInBinary), - - #move { path = Path }. - --spec decode_atk_action (map()) -> type(). -decode_atk_action (JSONMap) -> - TargetIX = maps:get(<<"tix">>, JSONMap), - - #attack { target_ix = TargetIX }. - --spec decode_swp_action (map()) -> type(). -decode_swp_action (_JSONMap) -> - #switch_weapon{}. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec decode (map()) -> type(). -decode (EncodedAction) -> - JSONActionMap = EncodedAction, %jiffy:decode(EncodedAction, [return_maps]), - ActionType = maps:get(<<"t">>, JSONActionMap), - case ActionType of - <<"mov">> -> decode_mov_action(JSONActionMap); - <<"atk">> -> decode_atk_action(JSONActionMap); - <<"swp">> -> decode_swp_action(JSONActionMap) - end. - --spec can_follow (category(), category()) -> boolean(). -can_follow (nothing, attack) -> true; -can_follow (nothing, switch_weapon) -> true; -can_follow (nothing, move) -> true; -can_follow (switch_weapon, attack) -> true; -can_follow (move, attack) -> true; -can_follow (_, _) -> false. - --spec get_path (type()) -> list(bm_direction:type()). -get_path (Action) when is_record(Action, move) -> - Action#move.path; -get_path (_) -> - []. - --spec get_target_ix (type()) -> non_neg_integer(). -get_target_ix (Action) when is_record(Action, attack) -> - Action#attack.target_ix; -get_target_ix (_) -> - []. - --spec get_category (type()) -> category(). -get_category (Action) when is_record(Action, attack) -> attack; -get_category (Action) when is_record(Action, move) -> move; -get_category (Action) when is_record(Action, switch_weapon) -> switch_weapon; -get_category (Action) -> - io:format("How'd you get there?~p~n", [Action]), - true = Action. - diff --git a/src/battlemap/struct/bm_battlemap.erl b/src/battlemap/struct/bm_battlemap.erl deleted file mode 100644 index 77d3041..0000000 --- a/src/battlemap/struct/bm_battlemap.erl +++ /dev/null @@ -1,100 +0,0 @@ --module(bm_battlemap). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - battlemap, - { - id :: id(), - width :: integer(), - height :: integer(), - tile_class_ids :: array:array(bm_tile:class_id()) - } -). - --opaque type() :: #battlemap{}. - --export_type([type/0, id/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_width/1, - get_height/1, - get_tile_class_ids/1, - get_tile_class_id/2 - ] -). - --export -( - [ - from_list/4 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec location_to_array_index - ( - non_neg_integer(), - bm_location:type() - ) - -> ('error' | non_neg_integer()). -location_to_array_index (ArrayWidth, {X, Y}) -> - if - (X < 0) -> error; - (Y < 0) -> error; - (X >= ArrayWidth) -> error; - true -> ((Y * ArrayWidth) + X) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_id (type()) -> id(). -get_id (Battlemap) -> Battlemap#battlemap.id. - --spec get_width (type()) -> integer(). -get_width (Battlemap) -> Battlemap#battlemap.width. - --spec get_height (type()) -> integer(). -get_height (Battlemap) -> Battlemap#battlemap.height. - --spec get_tile_class_ids (type()) -> array:array(bm_tile:class_id()). -get_tile_class_ids (Battlemap) -> Battlemap#battlemap.tile_class_ids. - --spec get_tile_class_id (bm_location:type(), type()) -> bm_tile:class_id(). -get_tile_class_id (Location, Battlemap) -> - TileIX = location_to_array_index(Battlemap#battlemap.width, Location), - array:get(TileIX, Battlemap#battlemap.tile_class_ids). - --spec from_list - ( - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - list(non_neg_integer()) - ) - -> type(). -from_list (ID, Width, Height, List) -> - TileClassIDs = lists:map(fun bm_tile:class_id_from_int/1, List), - - #battlemap - { - id = list_to_binary(integer_to_list(ID)), - width = Width, - height = Height, - tile_class_ids = array:from_list(TileClassIDs) - }. diff --git a/src/battlemap/struct/bm_character.erl b/src/battlemap/struct/bm_character.erl deleted file mode 100644 index b0e19ed..0000000 --- a/src/battlemap/struct/bm_character.erl +++ /dev/null @@ -1,290 +0,0 @@ --module(bm_character). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: non_neg_integer(). --type rank() :: ('optional' | 'target' | 'commander'). - --record -( - character, - { - id :: id(), - player_ix :: non_neg_integer(), - name :: binary(), - rank :: rank(), - icon :: binary(), - portrait :: binary(), - attributes :: sh_attributes:type(), - statistics :: sh_statistics:type(), - weapon_ids :: {sh_weapon:id(), sh_weapon:id()}, - armor_id :: sh_armor:id(), - location :: {non_neg_integer(), non_neg_integer()}, - current_health :: integer(), %% Negative integers let us reverse attacks. - is_active :: boolean(), - is_defeated :: boolean() - } -). - --opaque type() :: #character{}. - --export_type([type/0, rank/0, id/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_player_index/1, - get_name/1, - get_rank/1, - get_icon/1, - get_portrait/1, - get_attributes/1, - get_statistics/1, - get_weapon_ids/1, - get_armor_id/1, - get_location/1, - get_current_health/1, - get_is_alive/1, - get_is_active/1, - get_is_defeated/1, - - set_rank/2, - set_weapon_ids/2, - set_armor_id/2, - set_statistics/2, - set_location/2, - set_current_health/2, - set_is_active/2, - set_is_defeated/2, - - get_rank_field/0, - get_statistics_field/0, - get_weapons_field/0, - get_location_field/0, - get_current_health_field/0, - get_is_active_field/0, - get_is_defeated_field/0 - ] -). - --export -( - [ - random/5 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec find_random_location - ( - non_neg_integer(), - non_neg_integer(), - list({non_neg_integer(), non_neg_integer()}) - ) - -> {non_neg_integer(), non_neg_integer()}. -find_random_location (BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> - X = sh_roll:between(0, (BattlemapWidth - 1)), - Y = sh_roll:between(0, (BattlemapHeight - 1)), - - IsForbidden = lists:member({X, Y}, ForbiddenLocations), - - case IsForbidden of - true -> - find_random_location - ( - BattlemapWidth, - BattlemapHeight, - ForbiddenLocations - ); - - _ -> {X, Y} - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_id (type()) -> id(). -get_id (Char) -> Char#character.id. - --spec get_player_index (type()) -> non_neg_integer(). -get_player_index (Char) -> Char#character.player_ix. - --spec get_name (type()) -> binary(). -get_name (Char) -> Char#character.name. - --spec get_rank (type()) -> rank(). -get_rank (Char) -> Char#character.rank. - --spec get_icon (type()) -> binary(). -get_icon (Char) -> Char#character.icon. - --spec get_portrait (type()) -> binary(). -get_portrait (Char) -> Char#character.portrait. - --spec get_attributes (type()) -> sh_attributes:type(). -get_attributes (Char) -> Char#character.attributes. - --spec get_armor_id (type()) -> sh_armor:id(). -get_armor_id (Char) -> Char#character.armor_id. - --spec get_weapon_ids (type()) -> {sh_weapon:id(), sh_weapon:id()}. -get_weapon_ids (Char) -> Char#character.weapon_ids. - --spec get_statistics (type()) -> sh_statistics:type(). -get_statistics (Char) -> Char#character.statistics. - --spec get_location (type()) -> {non_neg_integer(), non_neg_integer()}. -get_location (Char) -> Char#character.location. - --spec get_current_health (type()) -> integer(). -get_current_health (Char) -> Char#character.current_health. - --spec get_is_alive (type()) -> boolean(). -get_is_alive (Char) -> - ( - (not Char#character.is_defeated) - and (Char#character.current_health > 0) - ). - --spec get_is_active (type()) -> boolean(). -get_is_active (Char) -> - ( - (not Char#character.is_defeated) - and Char#character.is_active - and get_is_alive(Char) - ). - --spec get_is_defeated (type()) -> boolean(). -get_is_defeated (Char) -> Char#character.is_defeated. - --spec set_rank (rank(), type()) -> type(). -set_rank (Rank, Char) -> - Char#character - { - rank = Rank - }. - --spec set_location - ( - {non_neg_integer(), non_neg_integer()}, - type() - ) - -> type(). -set_location (Location, Char) -> - Char#character - { - location = Location - }. - --spec set_current_health (integer(), type()) -> type(). -set_current_health (Health, Char) -> - Char#character - { - current_health = Health - }. - --spec set_is_active (boolean(), type()) -> type(). -set_is_active (Active, Char) -> - Char#character - { - is_active = Active - }. - --spec set_is_defeated (boolean(), type()) -> type(). -set_is_defeated (Defeated, Char) -> - Char#character - { - is_defeated = Defeated - }. - --spec set_armor_id (sh_armor:id(), type()) -> type(). -set_armor_id (ArmorID, Char) -> - Char#character - { - armor_id = ArmorID - }. - --spec set_weapon_ids ({sh_weapon:id(), sh_weapon:id()}, type()) -> type(). -set_weapon_ids (WeaponIDs, Char) -> - Char#character - { - weapon_ids = WeaponIDs - }. - --spec set_statistics - ( - sh_statistics:type(), - type() - ) - -> type(). -set_statistics (Stats, Char) -> - Char#character - { - statistics = Stats - }. - -%%%% Utils --spec random - ( - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - list({non_neg_integer(), non_neg_integer()}) - ) - -> type(). -random (ID, PlayerIX, BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> - Location = - find_random_location(BattlemapWidth, BattlemapHeight, ForbiddenLocations), - WeaponIDs = {sh_weapon:random_id(), sh_weapon:random_id()}, - ArmorID = sh_armor:random_id(), - Attributes = sh_attributes:random(), - Statistics = sh_statistics:new(Attributes, WeaponIDs, ArmorID), - IDAsListString = integer_to_list(ID), - IDAsBinaryString = list_to_binary(IDAsListString), - - #character - { - id = ID, - player_ix = PlayerIX, - name = list_to_binary("Char" ++ IDAsListString), - rank = - if - ((ID rem 8) == 0) -> commander; - ((ID rem 3) == 0) -> target; - true -> optional - end, - icon = IDAsBinaryString, - portrait = IDAsBinaryString, - attributes = Attributes, - weapon_ids = WeaponIDs, - armor_id = ArmorID, - statistics = Statistics, - location = Location, - current_health = sh_statistics:get_health(Statistics), - is_active = false, - is_defeated = false - }. - --spec get_rank_field() -> non_neg_integer(). -get_rank_field () -> #character.rank. --spec get_statistics_field() -> non_neg_integer(). -get_statistics_field () -> #character.statistics. --spec get_weapons_field() -> non_neg_integer(). -get_weapons_field () -> #character.weapon_ids. --spec get_location_field() -> non_neg_integer(). -get_location_field () -> #character.location. --spec get_current_health_field() -> non_neg_integer(). -get_current_health_field () -> #character.current_health. --spec get_is_active_field() -> non_neg_integer(). -get_is_active_field () -> #character.is_active. --spec get_is_defeated_field() -> non_neg_integer(). -get_is_defeated_field () -> #character.is_defeated. diff --git a/src/battlemap/struct/bm_character_turn_data.erl b/src/battlemap/struct/bm_character_turn_data.erl deleted file mode 100644 index 65b650c..0000000 --- a/src/battlemap/struct/bm_character_turn_data.erl +++ /dev/null @@ -1,115 +0,0 @@ --module(bm_character_turn_data). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - type, - { - dirty :: boolean(), - battle :: bm_battle:type(), - character :: bm_character:type(), - character_ix :: non_neg_integer() - } -). - --opaque type() :: #type{}. - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - new/2, - - get_battle_is_dirty/1, - get_battle/1, - get_character/1, - get_character_ix/1, - - set_battle/2, - set_character/2 - ] -). - --export -( - [ - clean_battle/1, - refresh_character/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (bm_battle:type(), non_neg_integer()) -> type(). -new (Battle, CharacterIX) -> - Character = bm_battle:get_character(CharacterIX, Battle), - - #type - { - dirty = false, - battle = Battle, - character = Character, - character_ix = CharacterIX - }. - --spec get_battle_is_dirty (type()) -> boolean(). -get_battle_is_dirty (Data) -> Data#type.dirty. - --spec get_battle (type()) -> bm_battle:type(). -get_battle (Data) -> Data#type.battle. - --spec get_character (type()) -> bm_character:type(). -get_character (Data) -> Data#type.character. - --spec get_character_ix (type()) -> non_neg_integer(). -get_character_ix (Data) -> Data#type.character_ix. - --spec set_battle (bm_battle:type(), type()) -> type(). -set_battle (Battle, Data) -> - Data#type{ battle = Battle }. - --spec set_character (bm_character:type(), type()) -> type(). -set_character (Character, Data) -> - Data#type - { - dirty = true, - character = Character - }. - --spec clean_battle (type()) -> type(). -clean_battle (Data) -> - Data#type - { - dirty = false, - battle = - bm_battle:set_character - ( - Data#type.character_ix, - Data#type.character, - Data#type.battle - ) - }. - --spec refresh_character (type()) -> type(). -refresh_character (Data) -> - Data#type - { - dirty = false, - character = - bm_battle:get_character - ( - Data#type.character_ix, - Data#type.battle - ) - }. diff --git a/src/battlemap/struct/bm_character_turn_request.erl b/src/battlemap/struct/bm_character_turn_request.erl deleted file mode 100644 index 51c87a3..0000000 --- a/src/battlemap/struct/bm_character_turn_request.erl +++ /dev/null @@ -1,84 +0,0 @@ --module(bm_character_turn_request). - --define(PLAYER_ID_FIELD, <<"pid">>). --define(SESSION_TOKEN_FIELD, <<"stk">>). --define(BATTLE_ID_FIELD, <<"bid">>). --define(CHAR_IX_FIELD, <<"cix">>). --define(ACTIONS_FIELD, <<"act">>). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - type, - { - player_id :: bm_player:id(), - session_token :: binary(), - battle_id :: binary(), - character_ix :: non_neg_integer(), - actions :: list(bm_battle_action:type()) - } -). - --opaque type() :: #type{}. - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - decode/1 - ] -). - --export -( - [ - get_player_id/1, - get_session_token/1, - get_battle_id/1, - get_character_ix/1, - get_actions/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec decode (map()) -> type(). -decode (Map) -> - CharacterIX = maps:get(?CHAR_IX_FIELD, Map), - EncodedActions = maps:get(?ACTIONS_FIELD, Map), - Actions = lists:map(fun bm_battle_action:decode/1, EncodedActions), - - #type - { - player_id = maps:get(?PLAYER_ID_FIELD, Map), - session_token = maps:get(?SESSION_TOKEN_FIELD, Map), - battle_id = maps:get(?BATTLE_ID_FIELD, Map), - character_ix = CharacterIX, - actions = Actions - }. - --spec get_player_id (type()) -> bm_player:id(). -get_player_id (Request) -> Request#type.player_id. - --spec get_session_token (type()) -> binary(). -get_session_token (Request) -> Request#type.session_token. - --spec get_battle_id (type()) -> binary(). -get_battle_id (Request) -> Request#type.battle_id. - --spec get_character_ix (type()) -> non_neg_integer(). -get_character_ix (Request) -> Request#type.character_ix. - --spec get_actions (type()) -> list(bm_battle_action:type()). -get_actions (Request) -> Request#type.actions. diff --git a/src/battlemap/struct/bm_character_turn_update.erl b/src/battlemap/struct/bm_character_turn_update.erl deleted file mode 100644 index 1ca5d94..0000000 --- a/src/battlemap/struct/bm_character_turn_update.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(bm_character_turn_update). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - type, - { - data :: bm_character_turn_data:type(), - timeline :: list(any()), - db :: list(sh_db_query:op()) - } -). - --opaque type() :: #type{}. - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - new/1, - - get_data/1, - get_timeline/1, - get_db/1, - - set_data/2, - add_to_timeline/3, - add_to_db/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (bm_character_turn_data:type()) -> type(). -new (Data) -> - #type - { - data = Data, - timeline = [], - db = [] - }. - --spec get_data (type()) -> bm_character_turn_data:type(). -get_data (Update) -> Update#type.data. - --spec get_timeline (type()) -> list(any()). -get_timeline (Update) -> Update#type.timeline. - --spec get_db (type()) -> list(sh_db_query:op()). -get_db (Update) -> Update#type.db. - --spec set_data (bm_character_turn_data:type(), type()) -> type(). -set_data (Data, Update) -> - Update#type{ data = Data}. - --spec add_to_timeline - ( - bm_turn_result:type(), - sh_db_query:op(), - type() - ) -> type(). -add_to_timeline (Item, DBUpdate, Update) -> - add_to_db - ( - DBUpdate, - Update#type - { - timeline = [bm_turn_result:encode(Item)|Update#type.timeline] - } - ). - --spec add_to_db (sh_db_query:op(), type()) -> type(). -add_to_db (Item, Update) -> - Update#type{ db = [Item|Update#type.db] }. diff --git a/src/battlemap/struct/bm_direction.erl b/src/battlemap/struct/bm_direction.erl deleted file mode 100644 index 2da3936..0000000 --- a/src/battlemap/struct/bm_direction.erl +++ /dev/null @@ -1,38 +0,0 @@ --module(bm_direction). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type enum() :: ('up' | 'down' | 'left' | 'right'). --type type() :: enum(). - --export_type([enum/0, type/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - decode/1, - encode/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec decode (binary()) -> enum(). -decode (<<"U">>) -> up; -decode (<<"D">>) -> down; -decode (<<"L">>) -> left; -decode (<<"R">>) -> right. - --spec encode (enum()) -> binary(). -encode (up) -> <<"U">>; -encode (down) -> <<"D">>; -encode (left) -> <<"L">>; -encode (right) -> <<"R">>. diff --git a/src/battlemap/struct/bm_location.erl b/src/battlemap/struct/bm_location.erl deleted file mode 100644 index 056d10c..0000000 --- a/src/battlemap/struct/bm_location.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(bm_location). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type type() :: ({non_neg_integer(), non_neg_integer()} | 'nowhere'). - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - decode/1, - encode/1, - get_nowhere/0 - ] -). - --export -( - [ - apply_direction/2, - dist/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec validate ({integer(), integer()}) -> type(). -validate ({X, Y}) -> - if - (X < 0) -> nowhere; - (Y < 0) -> nowhere; - true -> {X, Y} - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_nowhere () -> type(). -get_nowhere () -> nowhere. - --spec apply_direction (bm_direction:enum(), type()) -> type(). -apply_direction (left, {X, Y}) -> - validate({(X - 1), Y}); -apply_direction (right, {X, Y}) -> - validate({(X + 1), Y}); -apply_direction (up, {X, Y}) -> - validate({X, (Y - 1)}); -apply_direction (down, {X, Y}) -> - validate({X, (Y + 1)}); -apply_direction (_, nowhere) -> - error("Trying to move from 'nowhere'."), - nowhere. - --spec dist(type(), type()) -> non_neg_integer(). -dist ({OX, OY}, {DX, DY}) -> - (abs(DY - OY) + abs(DX - OX)); -dist (_, _) -> - error("Trying to measure distance to 'nowhere'"), - 999. - --spec encode (type()) -> {list(any())}. -encode ({X, Y}) -> - { - [ - {<<"x">>, X}, - {<<"y">>, Y} - ] - }; -encode (nowhere) -> - { - [ - {<<"x">>, -1}, - {<<"y">>, -1} - ] - }. - --spec decode (map()) -> type(). -decode (Map) -> - X = maps:get(<<"x">>, Map), - Y = maps:get(<<"y">>, Map), - - true = (is_integer(X) and is_integer(Y)), - - validate({X, Y}). diff --git a/src/battlemap/struct/bm_player.erl b/src/battlemap/struct/bm_player.erl deleted file mode 100644 index 6e5338d..0000000 --- a/src/battlemap/struct/bm_player.erl +++ /dev/null @@ -1,104 +0,0 @@ --module(bm_player). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - player, - { - ix :: non_neg_integer(), - id :: id(), - character_ix :: non_neg_integer(), - timeline :: list(any()), - is_active :: boolean() - } -). - --opaque type() :: #player{}. - --export_type([type/0, id/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - get_id/1, - get_index/1, - get_character_index/1, - get_timeline/1, - - get_is_active/1, - set_is_active/2, - - add_to_timeline/2, - reset_timeline/1, - - get_timeline_field/0, - get_is_active_field/0 - ] -). - --export -( - [ - new/3 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_id (type()) -> id(). -get_id (Player) -> Player#player.id. - --spec get_index (type()) -> non_neg_integer(). -get_index (Player) -> Player#player.ix. - --spec get_character_index (type()) -> non_neg_integer(). -get_character_index (Player) -> Player#player.character_ix. - --spec get_timeline (type()) -> list(any()). -get_timeline (Player) -> Player#player.timeline. - --spec get_is_active (type()) -> boolean(). -get_is_active (Player) -> Player#player.is_active. - --spec set_is_active (boolean(), type()) -> type(). -set_is_active (Val, Player) -> Player#player{ is_active = Val }. - --spec add_to_timeline (list(any()), type()) -> type(). -add_to_timeline (NewEvents, Player) -> - OldTimeline = Player#player.timeline, - - Player#player - { - timeline = (NewEvents ++ OldTimeline) - }. - --spec reset_timeline (type()) -> type(). -reset_timeline (Player) -> Player#player{ timeline = [] }. - --spec new (non_neg_integer(), non_neg_integer(), id()) -> type(). -new (IX, CharacterIX, ID) -> - #player - { - ix = IX, - character_ix = CharacterIX, - id = ID, - is_active = true, - timeline = [] - }. - --spec get_timeline_field () -> non_neg_integer(). -get_timeline_field () -> #player.timeline. - --spec get_is_active_field () -> non_neg_integer(). -get_is_active_field () -> #player.is_active. diff --git a/src/battlemap/struct/bm_player_turn.erl b/src/battlemap/struct/bm_player_turn.erl deleted file mode 100644 index c72112a..0000000 --- a/src/battlemap/struct/bm_player_turn.erl +++ /dev/null @@ -1,106 +0,0 @@ --module(bm_player_turn). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - player_turn, - { - number :: non_neg_integer(), - player_ix :: non_neg_integer() - } -). - --opaque type() :: #player_turn{}. - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - new/2, - next/2 - ] -). - -%%%% Accessors --export -( - [ - get_number/1, - get_player_ix/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --spec next_valid_player - ( - non_neg_integer(), - array:array(bm_player:type()), - non_neg_integer(), - non_neg_integer() - ) -> non_neg_integer(). -next_valid_player (StartingPoint, _Players, _PlayersCount, StartingPoint) -> - StartingPoint; -next_valid_player (CandidateIX, Players, PlayersCount, StartingPoint) -> - Candidate = array:get(CandidateIX, Players), - - case bm_player:get_is_active(Candidate) of - true -> CandidateIX; - _ -> - next_valid_player - ( - ((CandidateIX + 1) rem PlayersCount), - Players, - PlayersCount, - StartingPoint - ) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec new (non_neg_integer(), non_neg_integer()) -> type(). -new (Number, PlayerIX) -> - #player_turn - { - number = Number, - player_ix = PlayerIX - }. - --spec get_number (type()) -> non_neg_integer(). -get_number (PlayerTurn) -> PlayerTurn#player_turn.number. - --spec get_player_ix (type()) -> non_neg_integer(). -get_player_ix (PlayerTurn) -> PlayerTurn#player_turn.player_ix. - --spec next (array:array(bm_player:type()), type()) -> type(). -next (Players, CurrentPlayerTurn) -> - CurrentPlayerIX = CurrentPlayerTurn#player_turn.player_ix, - CurrentTurnNumber = CurrentPlayerTurn#player_turn.number, - PlayersCount = array:size(Players), - - NextPlayerIX = - next_valid_player - ( - ((CurrentPlayerIX + 1) rem PlayersCount), - Players, - PlayersCount, - CurrentPlayerIX - ), - - NextTurnNumber = - case (NextPlayerIX < CurrentPlayerIX) of - true -> (CurrentTurnNumber + 1); - _ -> CurrentTurnNumber - end, - - new(NextTurnNumber, NextPlayerIX). diff --git a/src/battlemap/struct/bm_tile.erl b/src/battlemap/struct/bm_tile.erl deleted file mode 100644 index cf00b7a..0000000 --- a/src/battlemap/struct/bm_tile.erl +++ /dev/null @@ -1,124 +0,0 @@ --module(bm_tile). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - tile, - { - id :: id(), - name :: binary(), - cost :: non_neg_integer(), - class_range_min :: non_neg_integer(), - class_range_max :: non_neg_integer() - } -). - --opaque id() :: non_neg_integer(). --opaque class_id() :: non_neg_integer(). --opaque type() :: #tile{}. - --export_type([type/0, class_id/0, id/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - get_id/1, - get_name/1, - get_cost/1, - get_range_minimum/1, - get_range_maximum/1, - from_id/1, - cost_when_oob/0 - ] -). - --export -( - [ - class_id_to_type_id/1, - class_id_from_int/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --spec class_id_to_type_id (class_id()) -> id(). -class_id_to_type_id (ClassID) -> - case ClassID of - 0 -> 0; - 1 -> 1; - 2 -> 2; - N when ((N >= 3) and (N =< 17)) -> 3 - end. - --spec from_id (id()) -> type(). -from_id (0) -> - #tile - { - id = 0, - name = <<"[Grassland] Grass">>, - cost = 6, - class_range_min = 0, - class_range_max = 0 - }; -from_id (1) -> - #tile - { - id = 1, - name = <<"[Grassland] Mushroom Infestation">>, - cost = 12, - class_range_min = 1, - class_range_max = 1 - }; -from_id (2) -> - #tile - { - id = 2, - name = <<"[Grassland] Tree Remains">>, - cost = 24, - class_range_min = 2, - class_range_max = 2 - }; -from_id (3) -> - #tile - { - id = 3, - name = <<"[Grassland] Clear Water">>, - cost = cost_when_occupied(), - class_range_min = 3, - class_range_max = 17 - }. - --spec cost_when_oob () -> non_neg_integer(). -cost_when_oob () -> 255. - --spec cost_when_occupied () -> non_neg_integer(). -cost_when_occupied () -> 201. - --spec get_id (type()) -> non_neg_integer(). -get_id (Tile) -> Tile#tile.id. - --spec get_cost (type()) -> non_neg_integer(). -get_cost (Tile) -> Tile#tile.cost. - --spec get_name (type()) -> binary(). -get_name (Tile) -> Tile#tile.name. - --spec get_range_minimum (type()) -> non_neg_integer(). -get_range_minimum (Tile) -> Tile#tile.class_range_min. - --spec get_range_maximum (type()) -> non_neg_integer(). -get_range_maximum (Tile) -> Tile#tile.class_range_max. - --spec class_id_from_int (non_neg_integer()) -> id(). -class_id_from_int (I) -> I. diff --git a/src/battlemap/struct/bm_turn_result.erl b/src/battlemap/struct/bm_turn_result.erl deleted file mode 100644 index 79fd7f3..0000000 --- a/src/battlemap/struct/bm_turn_result.erl +++ /dev/null @@ -1,215 +0,0 @@ --module(bm_turn_result). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% --record -( - switched_weapon, - { - character_ix :: bm_character:id() - } -). - --record -( - moved, - { - character_ix :: bm_character:id(), - path :: list(bm_direction:enum()), - new_location :: bm_location:type() - } -). - --record -( - attacked, - { - attacker_ix :: bm_character:id(), - defender_ix :: bm_character:id(), - sequence :: list(bm_attack:type()) - } -). - --record -( - player_won, - { - player_ix :: non_neg_integer() - } -). - --record -( - player_lost, - { - player_ix :: non_neg_integer() - } -). - --record -( - player_turn_started, - { - player_ix :: non_neg_integer() - } -). - --opaque type() :: ( - #switched_weapon{} - | #moved{} - | #attacked{} - | #player_won{} - | #player_lost{} - | #player_turn_started{} -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([type/0]). - --export -( - [ - new_player_won/1, - new_player_lost/1, - new_player_turn_started/1, - new_character_switched_weapons/1, - new_character_moved/3, - new_character_attacked/3 - ] -). - --export -( - [ - encode/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new_player_won (non_neg_integer()) -> type(). -new_player_won (PlayerIX) -> - #player_won { player_ix = PlayerIX }. - --spec new_player_lost (non_neg_integer()) -> type(). -new_player_lost (PlayerIX) -> - #player_lost { player_ix = PlayerIX }. - --spec new_player_turn_started (non_neg_integer()) -> type(). -new_player_turn_started (PlayerIX) -> - #player_turn_started { player_ix = PlayerIX }. - --spec new_character_switched_weapons (bm_character:id()) -> type(). -new_character_switched_weapons (CharacterIX) -> - #switched_weapon { character_ix = CharacterIX }. - --spec new_character_moved - ( - bm_character:id(), - list(bm_direction:enum()), - bm_location:type() - ) - -> type(). -new_character_moved (CharacterIX, Path, NewLocation) -> - #moved - { - character_ix = CharacterIX, - path = Path, - new_location = NewLocation - }. - --spec new_character_attacked - ( - bm_character:id(), - bm_character:id(), - list(bm_attack:type()) - ) - -> type(). -new_character_attacked (AttackerIX, DefenderIX, AttackSequence) -> - #attacked - { - attacker_ix = AttackerIX, - defender_ix = DefenderIX, - sequence = AttackSequence - }. - --spec encode (type()) -> {list(any())}. -encode (TurnResult) when is_record(TurnResult, switched_weapon) -> - CharacterIX = TurnResult#switched_weapon.character_ix, - - { - [ - {<<"t">>, <<"swp">>}, - {<<"ix">>, CharacterIX} - ] - }; -encode (TurnResult) when is_record(TurnResult, moved) -> - CharacterIX = TurnResult#moved.character_ix, - Path = TurnResult#moved.path, - NewLocation = TurnResult#moved.new_location, - - EncodedPath = lists:map(fun bm_direction:encode/1, Path), - EncodedNewLocation = bm_location:encode(NewLocation), - - { - [ - {<<"t">>, <<"mv">>}, - {<<"ix">>, CharacterIX}, - {<<"p">>, EncodedPath}, - {<<"nlc">>, EncodedNewLocation} - ] - }; -encode (TurnResult) when is_record(TurnResult, attacked) -> - AttackerIX = TurnResult#attacked.attacker_ix, - DefenderIX = TurnResult#attacked.defender_ix, - Sequence = TurnResult#attacked.sequence, - - EncodedSequence = lists:map(fun bm_attack:encode/1, Sequence), - - { - [ - {<<"t">>, <<"atk">>}, - {<<"aix">>, AttackerIX}, - {<<"dix">>, DefenderIX}, - {<<"seq">>, EncodedSequence} - ] - }; -encode (TurnResult) when is_record(TurnResult, player_won) -> - PlayerIX = TurnResult#player_won.player_ix, - - { - [ - {<<"t">>, <<"pwo">>}, - {<<"ix">>, PlayerIX} - ] - }; -encode (TurnResult) when is_record(TurnResult, player_lost) -> - PlayerIX = TurnResult#player_lost.player_ix, - - { - [ - {<<"t">>, <<"plo">>}, - {<<"ix">>, PlayerIX} - ] - }; -encode (TurnResult) when is_record(TurnResult, player_turn_started) -> - PlayerIX = TurnResult#player_turn_started.player_ix, - - { - [ - {<<"t">>, <<"pts">>}, - {<<"ix">>, PlayerIX} - ] - }; -encode (Other) -> - io:format("~n invalid encode param\"~p\"~n", [Other]), - true = Other. diff --git a/src/query/qry_handler.erl b/src/query/qry_handler.erl new file mode 100644 index 0000000..ecf3263 --- /dev/null +++ b/src/query/qry_handler.erl @@ -0,0 +1,23 @@ +-module(qry_handler). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([start/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec start (any()) -> 'ok'. +start (_YawsParams) -> + {ok, TimedCachesManagerPid} = sh_timed_caches_manager:start(), + ok = btl_handler:start(TimedCachesManagerPid), + ok. -- cgit v1.2.3-70-g09d2