From ee9c2ac044cc77b80f30420c8f0788cad4281084 Mon Sep 17 00:00:00 2001 From: nsensfel Date: Wed, 6 Jun 2018 15:54:18 +0200 Subject: Figuring out how to organize the src folder(s)... --- src/battlemap/Makefile | 72 ---- src/battlemap/bm_handler.erl | 23 ++ src/battlemap/game-logic/bm_movement.erl | 58 ++++ src/battlemap/game-logic/bm_next_turn.erl | 135 ++++++++ src/battlemap/game-logic/bm_roll.erl | 32 ++ src/battlemap/game-logic/bm_turn_actions.erl | 364 +++++++++++++++++++++ src/battlemap/io/bm_security.erl | 33 ++ src/battlemap/mk/debug.mk | 40 --- src/battlemap/mk/erlang.mk | 28 -- src/battlemap/mk/preprocessor.mk | 44 --- src/battlemap/mk/yaws.mk | 29 -- src/battlemap/module.conf | 9 - src/battlemap/query/bm_character_turn.erl | 250 ++++++++++++++ src/battlemap/query/bm_load_state.erl | 111 +++++++ src/battlemap/reply/add_char.erl | 78 +++++ src/battlemap/reply/set_map.erl | 28 ++ src/battlemap/reply/set_timeline.erl | 27 ++ src/battlemap/reply/turn_results.erl | 27 ++ src/battlemap/src/game-logic/movement.erl | 58 ---- src/battlemap/src/game-logic/next_turn.erl | 130 -------- src/battlemap/src/game-logic/roll.erl | 32 -- src/battlemap/src/game-logic/turn_actions.erl | 364 --------------------- src/battlemap/src/handler.erl | 23 -- src/battlemap/src/io/security.erl | 33 -- src/battlemap/src/io/timed_cache.erl | 130 -------- src/battlemap/src/io/timed_caches_manager.erl | 152 --------- src/battlemap/src/query/character_turn.erl | 255 --------------- src/battlemap/src/query/load_state.erl | 104 ------ src/battlemap/src/reply/add_char.erl | 78 ----- src/battlemap/src/reply/set_map.erl | 28 -- src/battlemap/src/reply/set_timeline.erl | 27 -- src/battlemap/src/reply/turn_results.erl | 27 -- src/battlemap/src/shim/database_shim.erl | 137 -------- src/battlemap/src/struct/attack.erl | 299 ----------------- src/battlemap/src/struct/attributes.erl | 108 ------ src/battlemap/src/struct/battle.erl | 197 ----------- src/battlemap/src/struct/battle_action.erl | 114 ------- src/battlemap/src/struct/battlemap.erl | 121 ------- src/battlemap/src/struct/character.erl | 239 -------------- src/battlemap/src/struct/character_turn_data.erl | 102 ------ .../src/struct/character_turn_request.erl | 84 ----- src/battlemap/src/struct/character_turn_update.erl | 73 ----- src/battlemap/src/struct/db_query.erl | 59 ---- src/battlemap/src/struct/direction.erl | 38 --- src/battlemap/src/struct/location.erl | 90 ----- src/battlemap/src/struct/player.erl | 72 ---- src/battlemap/src/struct/player_turn.erl | 73 ----- src/battlemap/src/struct/statistics.erl | 193 ----------- src/battlemap/src/struct/tile.erl | 47 --- src/battlemap/src/struct/turn_result.erl | 142 -------- src/battlemap/src/struct/weapon.erl | 361 -------------------- src/battlemap/src/util/array_util.erl | 105 ------ src/battlemap/struct/bm_attack.erl | 300 +++++++++++++++++ src/battlemap/struct/bm_battle.erl | 197 +++++++++++ src/battlemap/struct/bm_battle_action.erl | 114 +++++++ src/battlemap/struct/bm_battlemap.erl | 121 +++++++ src/battlemap/struct/bm_character.erl | 239 ++++++++++++++ src/battlemap/struct/bm_character_turn_data.erl | 102 ++++++ src/battlemap/struct/bm_character_turn_request.erl | 84 +++++ src/battlemap/struct/bm_character_turn_update.erl | 73 +++++ src/battlemap/struct/bm_direction.erl | 38 +++ src/battlemap/struct/bm_location.erl | 90 +++++ src/battlemap/struct/bm_player.erl | 72 ++++ src/battlemap/struct/bm_player_turn.erl | 73 +++++ src/battlemap/struct/bm_tile.erl | 47 +++ src/battlemap/struct/bm_turn_result.erl | 142 ++++++++ src/battlemap/struct/bm_weapon.erl | 360 ++++++++++++++++++++ src/battlemap/util/array_util.erl | 105 ++++++ src/db/Makefile | 71 ---- src/db/db_node.erl | 31 ++ src/db/include/db_item.hrl | 15 - src/db/include/db_query.hrl | 63 ---- src/db/include/db_user.hrl | 7 - src/db/logic/storage_access.erl | 54 +++ src/db/mk/debug.mk | 40 --- src/db/mk/erlang.mk | 28 -- src/db/mk/preprocessor.mk | 34 -- src/db/module.conf | 6 - src/db/src/db_node.erl | 31 -- src/db/src/logic/storage_access.erl | 54 --- src/db/src/struct/db_item.erl | 70 ---- src/db/src/struct/db_model.erl | 71 ---- src/db/src/struct/db_query.erl | 109 ------ src/db/src/struct/db_user.erl | 28 -- src/db/struct/db_model.erl | 71 ++++ src/db/struct/db_query.erl | 114 +++++++ src/shared/include/db_item.hrl | 15 + src/shared/include/db_query.hrl | 63 ++++ src/shared/include/db_user.hrl | 7 + src/shared/io/sh_database.erl | 137 ++++++++ src/shared/io/sh_timed_cache.erl | 130 ++++++++ src/shared/io/sh_timed_caches_manager.erl | 152 +++++++++ src/shared/struct/sh_attributes.erl | 108 ++++++ src/shared/struct/sh_db_item.erl | 70 ++++ src/shared/struct/sh_db_query.erl | 59 ++++ src/shared/struct/sh_db_user.erl | 28 ++ src/shared/struct/sh_statistics.erl | 193 +++++++++++ 97 files changed, 4555 insertions(+), 4944 deletions(-) delete mode 100644 src/battlemap/Makefile create mode 100644 src/battlemap/bm_handler.erl create mode 100644 src/battlemap/game-logic/bm_movement.erl create mode 100644 src/battlemap/game-logic/bm_next_turn.erl create mode 100644 src/battlemap/game-logic/bm_roll.erl create mode 100644 src/battlemap/game-logic/bm_turn_actions.erl create mode 100644 src/battlemap/io/bm_security.erl delete mode 100644 src/battlemap/mk/debug.mk delete mode 100644 src/battlemap/mk/erlang.mk delete mode 100644 src/battlemap/mk/preprocessor.mk delete mode 100644 src/battlemap/mk/yaws.mk delete mode 100644 src/battlemap/module.conf create mode 100644 src/battlemap/query/bm_character_turn.erl create mode 100644 src/battlemap/query/bm_load_state.erl create mode 100644 src/battlemap/reply/add_char.erl create mode 100644 src/battlemap/reply/set_map.erl create mode 100644 src/battlemap/reply/set_timeline.erl create mode 100644 src/battlemap/reply/turn_results.erl delete mode 100644 src/battlemap/src/game-logic/movement.erl delete mode 100644 src/battlemap/src/game-logic/next_turn.erl delete mode 100644 src/battlemap/src/game-logic/roll.erl delete mode 100644 src/battlemap/src/game-logic/turn_actions.erl delete mode 100644 src/battlemap/src/handler.erl delete mode 100644 src/battlemap/src/io/security.erl delete mode 100644 src/battlemap/src/io/timed_cache.erl delete mode 100644 src/battlemap/src/io/timed_caches_manager.erl delete mode 100644 src/battlemap/src/query/character_turn.erl delete mode 100644 src/battlemap/src/query/load_state.erl delete mode 100644 src/battlemap/src/reply/add_char.erl delete mode 100644 src/battlemap/src/reply/set_map.erl delete mode 100644 src/battlemap/src/reply/set_timeline.erl delete mode 100644 src/battlemap/src/reply/turn_results.erl delete mode 100644 src/battlemap/src/shim/database_shim.erl delete mode 100644 src/battlemap/src/struct/attack.erl delete mode 100644 src/battlemap/src/struct/attributes.erl delete mode 100644 src/battlemap/src/struct/battle.erl delete mode 100644 src/battlemap/src/struct/battle_action.erl delete mode 100644 src/battlemap/src/struct/battlemap.erl delete mode 100644 src/battlemap/src/struct/character.erl delete mode 100644 src/battlemap/src/struct/character_turn_data.erl delete mode 100644 src/battlemap/src/struct/character_turn_request.erl delete mode 100644 src/battlemap/src/struct/character_turn_update.erl delete mode 100644 src/battlemap/src/struct/db_query.erl delete mode 100644 src/battlemap/src/struct/direction.erl delete mode 100644 src/battlemap/src/struct/location.erl delete mode 100644 src/battlemap/src/struct/player.erl delete mode 100644 src/battlemap/src/struct/player_turn.erl delete mode 100644 src/battlemap/src/struct/statistics.erl delete mode 100644 src/battlemap/src/struct/tile.erl delete mode 100644 src/battlemap/src/struct/turn_result.erl delete mode 100644 src/battlemap/src/struct/weapon.erl delete mode 100644 src/battlemap/src/util/array_util.erl create mode 100644 src/battlemap/struct/bm_attack.erl create mode 100644 src/battlemap/struct/bm_battle.erl create mode 100644 src/battlemap/struct/bm_battle_action.erl create mode 100644 src/battlemap/struct/bm_battlemap.erl create mode 100644 src/battlemap/struct/bm_character.erl create mode 100644 src/battlemap/struct/bm_character_turn_data.erl create mode 100644 src/battlemap/struct/bm_character_turn_request.erl create mode 100644 src/battlemap/struct/bm_character_turn_update.erl create mode 100644 src/battlemap/struct/bm_direction.erl create mode 100644 src/battlemap/struct/bm_location.erl create mode 100644 src/battlemap/struct/bm_player.erl create mode 100644 src/battlemap/struct/bm_player_turn.erl create mode 100644 src/battlemap/struct/bm_tile.erl create mode 100644 src/battlemap/struct/bm_turn_result.erl create mode 100644 src/battlemap/struct/bm_weapon.erl create mode 100644 src/battlemap/util/array_util.erl delete mode 100644 src/db/Makefile create mode 100644 src/db/db_node.erl delete mode 100644 src/db/include/db_item.hrl delete mode 100644 src/db/include/db_query.hrl delete mode 100644 src/db/include/db_user.hrl create mode 100644 src/db/logic/storage_access.erl delete mode 100644 src/db/mk/debug.mk delete mode 100644 src/db/mk/erlang.mk delete mode 100644 src/db/mk/preprocessor.mk delete mode 100644 src/db/module.conf delete mode 100644 src/db/src/db_node.erl delete mode 100644 src/db/src/logic/storage_access.erl delete mode 100644 src/db/src/struct/db_item.erl delete mode 100644 src/db/src/struct/db_model.erl delete mode 100644 src/db/src/struct/db_query.erl delete mode 100644 src/db/src/struct/db_user.erl create mode 100644 src/db/struct/db_model.erl create mode 100644 src/db/struct/db_query.erl create mode 100644 src/shared/include/db_item.hrl create mode 100644 src/shared/include/db_query.hrl create mode 100644 src/shared/include/db_user.hrl create mode 100644 src/shared/io/sh_database.erl create mode 100644 src/shared/io/sh_timed_cache.erl create mode 100644 src/shared/io/sh_timed_caches_manager.erl create mode 100644 src/shared/struct/sh_attributes.erl create mode 100644 src/shared/struct/sh_db_item.erl create mode 100644 src/shared/struct/sh_db_query.erl create mode 100644 src/shared/struct/sh_db_user.erl create mode 100644 src/shared/struct/sh_statistics.erl (limited to 'src') diff --git a/src/battlemap/Makefile b/src/battlemap/Makefile deleted file mode 100644 index 9b0c9f4..0000000 --- a/src/battlemap/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -YAWS_CONF ?= ${CURDIR}/yaws.conf -YAWS_API_HEADER ?= /my/src/yaws/include/yaws_api.hrl - -MODULE_NAME ?= $ $(shell basename ${CURDIR}) -MODULE_PORT ?= 8001 - -DIALYZER_PLT_FILE ?= tacticians-server.plt - -## Main Directories -SRC_DIR ?= ${CURDIR}/src -CONF_DIR ?= ${CURDIR}/conf - -#### Optional Dirs -BIN_DIR ?= ${CURDIR}/ebin -INCLUDE_DIR ?= ${CURDIR}/include -WWW_DIR ?= ${CURDIR}/www -LOG_DIR ?= ${CURDIR}/log - -## Binaries -YAWS ?= yaws -ERLC ?= erlc -ERLC_OPTS ?= -DIALYZER ?= dialyzer - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -OPTIONAL_DIRS = $(BIN_DIR) $(INCLUDE_DIR) $(WWW_DIR) $(LOG_DIR) -REQUIRED_HEADERS = $(INCLUDE_DIR)/yaws_api.hrl - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ -YAWS_API_HEADER ?= /my/src/yaws/include/yaws_api.hrl -DIALYZER_PLT_FILE ?= tacticians-server.plt - -## Main Directories -SRC_DIR ?= src -CONF_DIR ?= conf - -################################################################################ -## INCLUDES #################################################################### -################################################################################ -main_target: all - -include ${CURDIR}/mk/debug.mk -include ${CURDIR}/mk/erlang.mk -include ${CURDIR}/mk/preprocessor.mk -include ${CURDIR}/mk/yaws.mk - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -all: build - -debug: debug_run - -build: $(REQUIRED_HEADERS) $(PREPROCESSOR_RESULT) $(ERLANG_RESULT) - -run: yaws_run - -clean: - rm -rf $(PREPROCESSOR_RESULT) $(ERLANG_RESULT) - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -$(OPTIONAL_DIRS): %: - mkdir -p $@ diff --git a/src/battlemap/bm_handler.erl b/src/battlemap/bm_handler.erl new file mode 100644 index 0000000..09659e9 --- /dev/null +++ b/src/battlemap/bm_handler.erl @@ -0,0 +1,23 @@ +-module(bm_handler). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([start/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +start (_YawsParams) -> + {ok, Pid} = sh_timed_caches_manager:start(), + bm_database_shim:generate_db(), + sh_timed_caches_manager:new_cache(Pid, battle_db, none), + ok. diff --git a/src/battlemap/game-logic/bm_movement.erl b/src/battlemap/game-logic/bm_movement.erl new file mode 100644 index 0000000..ed4c38c --- /dev/null +++ b/src/battlemap/game-logic/bm_movement.erl @@ -0,0 +1,58 @@ +-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), + NextTile = bm_battlemap:get_tile_id(NextLocation, Battlemap), + 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 new file mode 100644 index 0000000..3628111 --- /dev/null +++ b/src/battlemap/game-logic/bm_next_turn.erl @@ -0,0 +1,135 @@ +-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(). +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(array:size(Players), CurrentPlayerTurn), + + bm_battle:set_current_player_turn(NextPlayerTurn, Battle). + +-spec reset_next_player_timeline + ( + bm_battle:type() + ) + -> {bm_battle:type(), bm_player:type()}. +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), + + {UpdatedBattle, UpdatedNextPlayer}. + + +-spec activate_next_players_characters + ( + bm_battle:type(), + bm_player:type() + ) + -> {bm_battle:type(), list(non_neg_integer())}. +activate_next_players_characters (Battle, NextPlayer) -> + NextPlayerID = bm_player:get_id(NextPlayer), + Characters = bm_battle:get_characters(Battle), + + {UpdatedCharacters, ModifiedIXs} = + array_util:mapiff + ( + fun (Character) -> + (bm_character:get_owner_id(Character) == NextPlayerID) + end, + fun (Character) -> + bm_character:set_is_active(true, Character) + end, + Characters + ), + + UpdatedBattle = bm_battle:set_characters(UpdatedCharacters, Battle), + + {UpdatedBattle, ModifiedIXs}. + +-spec add_activation_updates + ( + list(non_neg_integer()), + bm_character_turn_update:type() + ) + -> bm_character_turn_update:type(). +add_activation_updates ([], Update) -> + Update; +add_activation_updates ([IX|NextIXs], Update) -> + add_activation_updates + ( + NextIXs, + 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_active_field(), true)] + ), + Update + ) + ). + +-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 = set_player_turn_to_next(Battle), + {S1Battle, NextPlayer} = reset_next_player_timeline(S0Battle), + {S2Battle, ActivatedCharactersIX} = + activate_next_players_characters(S1Battle, NextPlayer), + + S0Update = add_activation_updates(ActivatedCharactersIX, Update), + + UpdatedData = bm_character_turn_data:set_battle(S2Battle, Data), + + bm_character_turn_update:set_data(UpdatedData, S0Update). + +-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), + + array_util:none(fun bm_character:get_is_active/1, Characters). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec update_if_needed + ( + bm_character_turn_update:type() + ) + -> 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_roll.erl b/src/battlemap/game-logic/bm_roll.erl new file mode 100644 index 0000000..be1cb9d --- /dev/null +++ b/src/battlemap/game-logic/bm_roll.erl @@ -0,0 +1,32 @@ +-module(bm_roll). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + percentage/0, + between/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec between (non_neg_integer(), non_neg_integer()) -> non_neg_integer(). +between (Min, Max) -> + Diff = (Max - Min), + (Min + (rand:uniform(Diff + 1) - 1)). + +-spec percentage () -> 0..100. +percentage () -> + between(0, 100). diff --git a/src/battlemap/game-logic/bm_turn_actions.erl b/src/battlemap/game-logic/bm_turn_actions.erl new file mode 100644 index 0000000..9664283 --- /dev/null +++ b/src/battlemap/game-logic/bm_turn_actions.erl @@ -0,0 +1,364 @@ +-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), + {PrimaryWeaponID, SecondaryWeaponID} = bm_character:get_weapon_ids(Character), + + UpdatedWeaponIDs = {SecondaryWeaponID, PrimaryWeaponID}, + UpdatedCharacterStatistics = + bm_statistics:new(CharacterAttributes, UpdatedWeaponIDs), + UpdatedCharacter = + bm_character:set_statistics + ( + UpdatedCharacterStatistics, + bm_character:set_weapon_ids(UpdatedWeaponIDs, Character) + ), + + DBQuery = + sh_db_query:update_indexed + ( + bm_battle:get_characters_field(), + CharacterIX, + [ + sh_db_query:set_field + ( + bm_character:get_weapons_field(), + UpdatedWeaponIDs + ) + ] + ), + + UpdatedData = bm_character_turn_data:set_character(UpdatedCharacter, Data), + + S0Update = bm_character_turn_update:set_data(UpdatedData, Update), + S1Update = + bm_character_turn_update:add_to_timeline + ( + bm_turn_result:new_character_switched_weapons(CharacterIX), + S0Update + ), + + bm_character_turn_update:add_to_db(DBQuery, S1Update). + +%%%% 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 = + bm_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), + + S0Update = + bm_character_turn_update:add_to_timeline + ( + bm_turn_result:new_character_moved(CharacterIX, Path, NewLocation), + Update + ), + + S1Update = + bm_character_turn_update:add_to_db + ( + 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:set_data(UpdatedData, S1Update). + +-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 +) -> + CharacterStatistics = bm_character:get_statistics(Character), + TargetCharacterStatistics = bm_character:get_statistics(TargetCharacter), + + AttackPlannedEffects = + lists:map + ( + fun (AttackStep) -> + bm_attack:get_description_of + ( + AttackStep, + CharacterStatistics, + TargetCharacterStatistics + ) + 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(attack:step()). +get_attack_sequence (Character, TargetCharacter) -> + Range = + 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 = bm_weapon:from_id(AttackingWeaponID), + DefendingWeapon = bm_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), + + 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 + ), + + + S0Update = + bm_character_turn_update:add_to_timeline + ( + bm_turn_result:new_character_attacked + ( + CharacterIX, + TargetIX, + AttackEffects + ), + Update + ), + S1Update = bm_character_turn_update:set_data(S1Data, S0Update), + + DBQuery = + sh_db_query:update_indexed + ( + bm_battle:get_characters_field(), + TargetIX, + [ + sh_db_query:set_field + ( + bm_character:get_current_health_field(), + RemainingDefenderHealth + ) + ] + ), + + bm_character_turn_update:add_to_db(DBQuery, S1Update). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 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/io/bm_security.erl b/src/battlemap/io/bm_security.erl new file mode 100644 index 0000000..787082a --- /dev/null +++ b/src/battlemap/io/bm_security.erl @@ -0,0 +1,33 @@ +-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/mk/debug.mk b/src/battlemap/mk/debug.mk deleted file mode 100644 index 7e88422..0000000 --- a/src/battlemap/mk/debug.mk +++ /dev/null @@ -1,40 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -DIALYZER_PLT_FILE ?= tacticians-server.plt -DIALYZER ?= dialyzer - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -SRC_FILES ?= $(wildcard $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -DEBUG_RESULT = $(DIALYZER_PLT_FILE) - -debug_rebuild: - $(MAKE) clean - $(MAKE) ERLC_OPTS=+debug_info - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -ifeq ($(wildcard $(DIALYZER_PLT_FILE)),) -debug_run: - $(DIALYZER) --build_plt --apps erts kernel stdlib jiffy --output_plt \ - $(DIALYZER_PLT_FILE) - $(MAKE) debug_rebuild - $(DIALYZER) --add_to_plt --plt $(DIALYZER_PLT_FILE) -r $(BIN_DIR) -else -debug_run: - $(MAKE) debug_rebuild - $(DIALYZER) --check_plt --plt $(DIALYZER_PLT_FILE) - $(DIALYZER) --get_warnings $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl \ - --src --plt $(DIALYZER_PLT_FILE) -endif diff --git a/src/battlemap/mk/erlang.mk b/src/battlemap/mk/erlang.mk deleted file mode 100644 index 9150f63..0000000 --- a/src/battlemap/mk/erlang.mk +++ /dev/null @@ -1,28 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -ERLC ?= erlc -ERLC_OPTS ?= - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -SRC_FILES ?= $(wildcard $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl) -BIN_FILES = \ - $(patsubst %.erl,$(BIN_DIR)/%.beam,$(notdir $(SRC_FILES))) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -ERLANG_RESULT = $(BIN_DIR) $(BIN_FILES) - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -.SECONDEXPANSION: -$(BIN_FILES): $(BIN_DIR)/%.beam : $$(wildcard $(SRC_DIR)/*/%.erl $(SRC_DIR)/%.erl) - $(ERLC) $(ERLC_OPTS) -o $(BIN_DIR) $< diff --git a/src/battlemap/mk/preprocessor.mk b/src/battlemap/mk/preprocessor.mk deleted file mode 100644 index d27de1b..0000000 --- a/src/battlemap/mk/preprocessor.mk +++ /dev/null @@ -1,44 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -CONFIG_FILE ?= ${CURDIR}/module.conf -YAWS_CONFIG_TEMPLATE ?= - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -PREPROCESSOR_FILES = $(shell find ${CURDIR} -name "*.m4") -PREPROCESSED_FILES = $(patsubst %.m4,%,$(PREPROCESSOR_FILES)) - -MAKEFILE_TO_M4 = \ - --define=__MAKEFILE_MODULE_NAME=$(MODULE_NAME) \ - --define=__MAKEFILE_MODULE_PORT=$(MODULE_PORT) \ - --define=__MAKEFILE_BIN_DIR=$(BIN_DIR) \ - --define=__MAKEFILE_INCLUDE_DIR=$(INCLUDE_DIR) \ - --define=__MAKEFILE_LOG_DIR=$(LOG_DIR) \ - --define=__MAKEFILE_WWW_DIR=$(WWW_DIR) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ -ifeq ($(wildcard $(CONFIG_FILE)),) -$(error "Missing CONFIG_FILE ($(CONFIG_FILE)).") -endif - -ifeq ($(wildcard $(YAWS_CONFIG_TEMPLATE)),) -$(error "Missing YAWS_CONFIG_TEMPLATE ($(YAWS_CONFIG_TEMPLATE)).") -endif - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -PREPROCESSOR_RESULT = $(PREPROCESSED_FILES) yaws.conf - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -$(PREPROCESSED_FILES): %: $(CONFIG_FILE) %.m4 - m4 -P $^ > $@ - -yaws.conf: $(CONFIG_FILE) $(YAWS_CONFIG_TEMPLATE) - m4 -P $(MAKEFILE_TO_M4) $^ > $@ diff --git a/src/battlemap/mk/yaws.mk b/src/battlemap/mk/yaws.mk deleted file mode 100644 index a68edf2..0000000 --- a/src/battlemap/mk/yaws.mk +++ /dev/null @@ -1,29 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -YAWS_CONF ?= ${CURDIR}/yaws.conf -YAWS_API_HEADER ?= /my/src/yaws/include/yaws_api.hrl - -YAWS ?= yaws -YAWS_OPTS ?= -name battlemap_node -erlarg "-connect_all false" - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ -YAWS_API_HEADER ?= /my/src/yaws/include/yaws_api.hrl - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -yaws_run: build $(WWW_DIR) $(LOG_DIR) - $(YAWS) --conf $(YAWS_CONF) $(YAWS_OPTS) - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -$(INCLUDE_DIR)/yaws_api.hrl: $(YAWS_API_HEADER) $(INCLUDE_DIR) - cp $< $@ diff --git a/src/battlemap/module.conf b/src/battlemap/module.conf deleted file mode 100644 index 8c2a2b6..0000000 --- a/src/battlemap/module.conf +++ /dev/null @@ -1,9 +0,0 @@ -m4_define(`__MODULE_NAME', `__MAKEFILE_MODULE_NAME')m4_dnl -m4_define(`__MODULE_PORT', `__MAKEFILE_MODULE_PORT')m4_dnl -m4_dnl -m4_define(`__MODULE_BIN_DIR', `__MAKEFILE_BIN_DIR')m4_dnl -m4_define(`__MODULE_INCLUDE_DIR', `__MAKEFILE_INCLUDE_DIR')m4_dnl -m4_define(`__MODULE_LOG_DIR', `__MAKEFILE_LOG_DIR')m4_dnl -m4_define(`__MODULE_WWW_DIR', `__MAKEFILE_WWW_DIR')m4_dnl -m4_dnl -m4_define(`__MODULE_APP_MODS', `character_turn load_state')m4_dnl diff --git a/src/battlemap/query/bm_character_turn.erl b/src/battlemap/query/bm_character_turn.erl new file mode 100644 index 0000000..26b8dce --- /dev/null +++ b/src/battlemap/query/bm_character_turn.erl @@ -0,0 +1,250 @@ +-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), + Character = bm_character_turn_data:get_character(Data), + CharacterOwnerID = bm_character:get_owner_id(Character), + + true = (PlayerID == CharacterOwnerID), + + 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), + + bm_character_turn_update:set_data(FinalizedData, Update). + +-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), + + bm_character_turn_update:set_data(UpdatedData, Update). + +-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), + + % TODO: send queries to an actual DB... + + 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 new file mode 100644 index 0000000..b580b9f --- /dev/null +++ b/src/battlemap/query/bm_load_state.erl @@ -0,0 +1,111 @@ +-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 = 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, + + jiffy:encode + ( + [ + bm_set_timeline:generate + ( + bm_battle:get_encoded_last_turns_effects(Battle) + ), + bm_set_map:generate(bm_battle:get_battlemap(Battle)) + | + array:sparse_to_list + ( + array:map + ( + fun (IX, Character) -> + bm_add_char:generate(IX, Character, PlayerID) + end, + bm_battle:get_characters(Battle) + ) + ) + ] + ). + +-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/add_char.erl b/src/battlemap/reply/add_char.erl new file mode 100644 index 0000000..86b1e9c --- /dev/null +++ b/src/battlemap/reply/add_char.erl @@ -0,0 +1,78 @@ +-module(add_char). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/3]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec attributes_as_json + ( + attributes:type() + ) -> + {list({binary(), non_neg_integer()})}. +attributes_as_json (Attributes) -> + { + [ + {<<"con">>, attributes:get_constitution(Attributes)}, + {<<"dex">>, attributes:get_dexterity(Attributes)}, + {<<"int">>, attributes:get_intelligence(Attributes)}, + {<<"min">>, attributes:get_mind(Attributes)}, + {<<"spe">>, attributes:get_speed(Attributes)}, + {<<"str">>, attributes:get_strength(Attributes)} + ] + }. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate + ( + non_neg_integer(), + character:type(), + player:id() + ) + -> {list(any())}. +generate (IX, Character, PlayerID) -> + IsAlive = character:get_is_alive(Character), + Attributes = character:get_attributes(Character), + {ActiveWeapon, SecondaryWeapon} = character:get_weapon_ids(Character), + OwnerID = character:get_owner_id(Character), + Location = + case IsAlive of + true -> character:get_location(Character); + _ -> location:get_nowhere() + end, + + { + [ + {<<"msg">>, <<"add_char">>}, + {<<"ix">>, IX}, + {<<"nam">>, character:get_name(Character)}, + {<<"ico">>, character:get_icon(Character)}, + {<<"prt">>, character:get_portrait(Character)}, + { + <<"hea">>, + character:get_current_health(Character) + }, + {<<"lc">>, location:encode(Location)}, + {<<"pla">>, OwnerID}, + { + <<"ena">>, + ( + character:get_is_active(Character) + and + (OwnerID == PlayerID) + ) + }, + {<<"att">>, attributes_as_json(Attributes)}, + {<<"awp">>, ActiveWeapon}, + {<<"swp">>, SecondaryWeapon} + ] + }. diff --git a/src/battlemap/reply/set_map.erl b/src/battlemap/reply/set_map.erl new file mode 100644 index 0000000..8518ac5 --- /dev/null +++ b/src/battlemap/reply/set_map.erl @@ -0,0 +1,28 @@ +-module(set_map). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([generate/1]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate (battlemap:type()) -> {list(any())}. +generate (Battlemap) -> + { + [ + {<<"msg">>, <<"set_map">>}, + {<<"w">>, battlemap:get_width(Battlemap)}, + {<<"h">>, battlemap:get_height(Battlemap)}, + {<<"t">>, array:sparse_to_list(battlemap:get_tile_ids(Battlemap))} + ] + }. diff --git a/src/battlemap/reply/set_timeline.erl b/src/battlemap/reply/set_timeline.erl new file mode 100644 index 0000000..bfe621a --- /dev/null +++ b/src/battlemap/reply/set_timeline.erl @@ -0,0 +1,27 @@ +-module(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/turn_results.erl b/src/battlemap/reply/turn_results.erl new file mode 100644 index 0000000..0f3ff25 --- /dev/null +++ b/src/battlemap/reply/turn_results.erl @@ -0,0 +1,27 @@ +-module(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/src/game-logic/movement.erl b/src/battlemap/src/game-logic/movement.erl deleted file mode 100644 index 467f87b..0000000 --- a/src/battlemap/src/game-logic/movement.erl +++ /dev/null @@ -1,58 +0,0 @@ --module(movement). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([cross/4]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec cross - ( - battlemap:type(), - list(location:type()), - list(direction:enum()), - non_neg_integer(), - location:type() - ) - -> {location:type(), non_neg_integer()}. -cross (_Battlemap, _ForbiddenLocations, [], Cost, Location) -> - {Location, Cost}; -cross (Battlemap, ForbiddenLocations, [Step|NextSteps], Cost, Location) -> - NextLocation = location:apply_direction(Step, Location), - NextTile = battlemap:get_tile_id(NextLocation, Battlemap), - NextCost = (Cost + 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 - ( - battlemap:type(), - list(location:type()), - list(direction:enum()), - location:type() - ) - -> {location:type(), non_neg_integer()}. -cross (Battlemap, ForbiddenLocations, Path, Location) -> - cross(Battlemap, ForbiddenLocations, Path, 0, Location). diff --git a/src/battlemap/src/game-logic/next_turn.erl b/src/battlemap/src/game-logic/next_turn.erl deleted file mode 100644 index 8e7ca8a..0000000 --- a/src/battlemap/src/game-logic/next_turn.erl +++ /dev/null @@ -1,130 +0,0 @@ --module(next_turn). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - update_if_needed/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec set_player_turn_to_next (battle:type()) -> battle:type(). -set_player_turn_to_next (Battle) -> - Players = battle:get_players(Battle), - CurrentPlayerTurn = battle:get_current_player_turn(Battle), - - NextPlayerTurn = player_turn:next(array:size(Players), CurrentPlayerTurn), - - battle:set_current_player_turn(NextPlayerTurn, Battle). - --spec reset_next_player_timeline - ( - battle:type() - ) - -> {battle:type(), player:type()}. -reset_next_player_timeline (Battle) -> - NextPlayerTurn = battle:get_current_player_turn(Battle), - NextPlayerIX = player_turn:get_player_ix(NextPlayerTurn), - NextPlayer = battle:get_player(NextPlayerIX, Battle), - - UpdatedNextPlayer = player:reset_timeline(NextPlayer), - UpdatedBattle = battle:set_player(NextPlayerIX, UpdatedNextPlayer, Battle), - - {UpdatedBattle, UpdatedNextPlayer}. - - --spec activate_next_players_characters - ( - battle:type(), - player:type() - ) - -> {battle:type(), list(non_neg_integer())}. -activate_next_players_characters (Battle, NextPlayer) -> - NextPlayerID = player:get_id(NextPlayer), - Characters = battle:get_characters(Battle), - - {UpdatedCharacters, ModifiedIXs} = - array_util:mapiff - ( - fun (Character) -> - (character:get_owner_id(Character) == NextPlayerID) - end, - fun (Character) -> - character:set_is_active(true, Character) - end, - Characters - ), - - UpdatedBattle = battle:set_characters(UpdatedCharacters, Battle), - - {UpdatedBattle, ModifiedIXs}. - --spec add_activation_updates - ( - list(non_neg_integer()), - character_turn_update:type() - ) - -> character_turn_update:type(). -add_activation_updates ([], Update) -> - Update; -add_activation_updates ([IX|NextIXs], Update) -> - add_activation_updates - ( - NextIXs, - character_turn_update:add_to_db - ( - db_query:update_indexed - ( - battle:get_characters_field(), - IX, - [db_query:set_field(character:get_active_field(), true)] - ), - Update - ) - ). - --spec update (character_turn_update:type()) -> character_turn_update:type(). -update (Update) -> - Data = character_turn_update:get_data(Update), - Battle = character_turn_data:get_battle(Data), - - S0Battle = set_player_turn_to_next(Battle), - {S1Battle, NextPlayer} = reset_next_player_timeline(S0Battle), - {S2Battle, ActivatedCharactersIX} = - activate_next_players_characters(S1Battle, NextPlayer), - - S0Update = add_activation_updates(ActivatedCharactersIX, Update), - - UpdatedData = character_turn_data:set_battle(S2Battle, Data), - - character_turn_update:set_data(UpdatedData, S0Update). - --spec requires_update (character_turn_update:type()) -> boolean(). -requires_update (Update) -> - Data = character_turn_update:get_data(Update), - Battle = character_turn_data:get_battle(Data), - Characters = battle:get_characters(Battle), - - array_util:none(fun character:get_is_active/1, Characters). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec update_if_needed - ( - character_turn_update:type() - ) - -> character_turn_update:type(). -update_if_needed (Update) -> - case requires_update(Update) of - true -> update(Update); - _ -> Update - end. diff --git a/src/battlemap/src/game-logic/roll.erl b/src/battlemap/src/game-logic/roll.erl deleted file mode 100644 index 074054b..0000000 --- a/src/battlemap/src/game-logic/roll.erl +++ /dev/null @@ -1,32 +0,0 @@ --module(roll). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - percentage/0, - between/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec between (non_neg_integer(), non_neg_integer()) -> non_neg_integer(). -between (Min, Max) -> - Diff = (Max - Min), - (Min + (rand:uniform(Diff + 1) - 1)). - --spec percentage () -> 0..100. -percentage () -> - between(0, 100). diff --git a/src/battlemap/src/game-logic/turn_actions.erl b/src/battlemap/src/game-logic/turn_actions.erl deleted file mode 100644 index e6aac9e..0000000 --- a/src/battlemap/src/game-logic/turn_actions.erl +++ /dev/null @@ -1,364 +0,0 @@ --module(turn_actions). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - handle/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%% SWITCHING WEAPON %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle_switch_weapon - ( - character_turn_update:type() - ) - -> character_turn_update:type(). -handle_switch_weapon (Update) -> - Data = character_turn_update:get_data(Update), - Character = character_turn_data:get_character(Data), - CharacterIX = character_turn_data:get_character_ix(Data), - CharacterAttributes = character:get_attributes(Character), - {PrimaryWeaponID, SecondaryWeaponID} = character:get_weapon_ids(Character), - - UpdatedWeaponIDs = {SecondaryWeaponID, PrimaryWeaponID}, - UpdatedCharacterStatistics = - statistics:new(CharacterAttributes, UpdatedWeaponIDs), - UpdatedCharacter = - character:set_statistics - ( - UpdatedCharacterStatistics, - character:set_weapon_ids(UpdatedWeaponIDs, Character) - ), - - DBQuery = - db_query:update_indexed - ( - battle:get_characters_field(), - CharacterIX, - [ - db_query:set_field - ( - character:get_weapons_field(), - UpdatedWeaponIDs - ) - ] - ), - - UpdatedData = character_turn_data:set_character(UpdatedCharacter, Data), - - S0Update = character_turn_update:set_data(UpdatedData, Update), - S1Update = - character_turn_update:add_to_timeline - ( - turn_result:new_character_switched_weapons(CharacterIX), - S0Update - ), - - character_turn_update:add_to_db(DBQuery, S1Update). - -%%%% MOVING %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_path_cost_and_destination - ( - character_turn_data:type(), - list(direction:type()) - ) - -> {non_neg_integer(), location:type()}. -get_path_cost_and_destination (Data, Path) -> - Character = character_turn_data:get_character(Data), - CharacterIX = character_turn_data:get_character_ix(Data), - Battle = character_turn_data:get_battle(Data), - Battlemap = battle:get_battlemap(Battle), - - ForbiddenLocations = - array:foldl - ( - fun (IX, Char, Prev) -> - IsAlive = character:get_is_alive(Char), - if - (IX == CharacterIX) -> Prev; - (not IsAlive) -> Prev; - true -> [character:get_location(Char)|Prev] - end - end, - [], - battle:get_characters(Battle) - ), - - {NewLocation, Cost} = - movement:cross - ( - Battlemap, - ForbiddenLocations, - Path, - character:get_location(Character) - ), - - {Cost, NewLocation}. - --spec assert_character_can_move - ( - character_turn_data:type(), - non_neg_integer() - ) - -> 'ok'. -assert_character_can_move (Data, Cost) -> - Character = character_turn_data:get_character(Data), - CharacterStatistics = character:get_statistics(Character), - CharacterMovementPoints = - statistics:get_movement_points(CharacterStatistics), - - true = (Cost =< CharacterMovementPoints), - - ok. - --spec commit_move - ( - character_turn_update:type(), - list(direction:type()), - location:type() - ) - -> character_turn_update:type(). -commit_move (Update, Path, NewLocation) -> - Data = character_turn_update:get_data(Update), - Character = character_turn_data:get_character(Data), - CharacterIX = character_turn_data:get_character_ix(Data), - - UpdatedCharacter = character:set_location(NewLocation, Character), - - UpdatedData = character_turn_data:set_character(UpdatedCharacter, Data), - - S0Update = - character_turn_update:add_to_timeline - ( - turn_result:new_character_moved(CharacterIX, Path, NewLocation), - Update - ), - - S1Update = - character_turn_update:add_to_db - ( - db_query:update_indexed - ( - battle:get_characters_field(), - CharacterIX, - [ - db_query:set_field - ( - character:get_location_field(), - NewLocation - ) - ] - ), - S0Update - ), - - character_turn_update:set_data(UpdatedData, S1Update). - --spec handle_move - ( - battle_action:type(), - character_turn_update:type() - ) - -> character_turn_update:type(). -handle_move (BattleAction, Update) -> - Data = character_turn_update:get_data(Update), - Path = 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 - ( - character:type(), - character:type(), - list(attack:step()) - ) - -> {list(attack:type()), non_neg_integer(), non_neg_integer()}. -handle_attack_sequence -( - Character, - TargetCharacter, - AttackSequence -) -> - CharacterStatistics = character:get_statistics(Character), - TargetCharacterStatistics = character:get_statistics(TargetCharacter), - - AttackPlannedEffects = - lists:map - ( - fun (AttackStep) -> - attack:get_description_of - ( - AttackStep, - CharacterStatistics, - TargetCharacterStatistics - ) - end, - AttackSequence - ), - - lists:foldl - ( - fun - ( - AttackEffectCandidate, - {AttackValidEffects, AttackerHealth, DefenderHealth} - ) -> - {AttackResult, NewAttackerHealth, NewDefenderHealth} = - attack:apply_to_healths - ( - AttackEffectCandidate, - AttackerHealth, - DefenderHealth - ), - case AttackResult of - nothing -> {AttackValidEffects, AttackerHealth, DefenderHealth}; - _ -> - { - (AttackValidEffects ++ [AttackResult]), - NewAttackerHealth, - NewDefenderHealth - } - end - end, - { - [], - character:get_current_health(Character), - character:get_current_health(TargetCharacter) - }, - AttackPlannedEffects - ). - --spec get_attack_sequence - ( - character:type(), - character:type() - ) - -> list(attack:step()). -get_attack_sequence (Character, TargetCharacter) -> - Range = - location:dist - ( - character:get_location(Character), - character:get_location(TargetCharacter) - ), - - {AttackingWeaponID, _} = character:get_weapon_ids(Character), - {DefendingWeaponID, _} = character:get_weapon_ids(TargetCharacter), - - AttackingWeapon = weapon:from_id(AttackingWeaponID), - DefendingWeapon = weapon:from_id(DefendingWeaponID), - - attack:get_sequence(Range, AttackingWeapon, DefendingWeapon). - - --spec handle_attack - ( - battle_action:type(), - character_turn_update:type() - ) - -> character_turn_update:type(). -handle_attack (BattleAction, Update) -> - Data = character_turn_update:get_data(Update), - Battle = character_turn_data:get_battle(Data), - Character = character_turn_data:get_character(Data), - CharacterIX = character_turn_data:get_character_ix(Data), - TargetIX = battle_action:get_target_ix(BattleAction), - TargetCharacter = battle:get_character(TargetIX, Battle), - - AttackSequence = get_attack_sequence(Character, TargetCharacter), - - {AttackEffects, RemainingAttackerHealth, RemainingDefenderHealth} = - handle_attack_sequence - ( - Character, - TargetCharacter, - AttackSequence - ), - - UpdatedCharacter = - character:set_current_health - ( - RemainingAttackerHealth, - Character - ), - - UpdatedBattle = - battle:set_character - ( - TargetIX, - character:set_current_health - ( - RemainingDefenderHealth, - TargetCharacter - ), - Battle - ), - - - S0Data = character_turn_data:set_battle(UpdatedBattle, Data), - S1Data = - character_turn_data:set_character - ( - UpdatedCharacter, - S0Data - ), - - - S0Update = - character_turn_update:add_to_timeline - ( - turn_result:new_character_attacked - ( - CharacterIX, - TargetIX, - AttackEffects - ), - Update - ), - S1Update = character_turn_update:set_data(S1Data, S0Update), - - DBQuery = - db_query:update_indexed - ( - battle:get_characters_field(), - TargetIX, - [ - db_query:set_field - ( - character:get_current_health_field(), - RemainingDefenderHealth - ) - ] - ), - - character_turn_update:add_to_db(DBQuery, S1Update). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec handle -( - battle_action:type(), - character_turn_update:type() -) --> character_turn_update:type(). -handle (BattleAction, Update) -> - case 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/src/handler.erl b/src/battlemap/src/handler.erl deleted file mode 100644 index 1b79b69..0000000 --- a/src/battlemap/src/handler.erl +++ /dev/null @@ -1,23 +0,0 @@ --module(handler). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([start/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -start (_YawsParams) -> - {ok, Pid} = timed_caches_manager:start(), - database_shim:generate_db(), - timed_caches_manager:new_cache(Pid, battle_db, none), - ok. diff --git a/src/battlemap/src/io/security.erl b/src/battlemap/src/io/security.erl deleted file mode 100644 index 60f6661..0000000 --- a/src/battlemap/src/io/security.erl +++ /dev/null @@ -1,33 +0,0 @@ --module(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/src/io/timed_cache.erl b/src/battlemap/src/io/timed_cache.erl deleted file mode 100644 index 52b98d6..0000000 --- a/src/battlemap/src/io/timed_cache.erl +++ /dev/null @@ -1,130 +0,0 @@ --module(timed_cache). --behavior(gen_server). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% 'gen_server' Exports --export -( - [ - init/1, - handle_cast/2, - handle_call/3, %% No reply will ever be given. - terminate/2, - code_change/3, - format_status/2, - handle_info/2 - ] -). - -%%%% Actual Interface --export -( - [ - fetch/3, - update/4, - invalidate/3 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec add_to_cache (atom(), any(), any()) -> any(). -add_to_cache (DB, Owner, ObjectID) -> - {ok, TimerPID} = gen_server:start(?MODULE, {DB, {Owner, ObjectID}}, []), - {ok, Data} = database_shim:fetch(DB, ObjectID), - ets:insert(DB, {{Owner, ObjectID}, TimerPID, Data}), - Data. - --spec add_update_to_cache (atom(), any(), any(), any()) -> 'ok'. -add_update_to_cache (DB, Owner, ObjectID, Data) -> - {ok, TimerPID} = gen_server:start(?MODULE, {DB, {Owner, ObjectID}}, []), - ets:insert(DB, {{Owner, ObjectID}, TimerPID, Data}), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% 'gen_server' functions -init ({DB, ObjectID}) -> - io:format("~nCache entry added: ~p.~n", [{DB, ObjectID}]), - {ok, {DB, ObjectID}, timed_caches_manager:get_timeout()}. - -handle_call (invalidate, _, State) -> - {stop, normal, State}; -handle_call (ping, _, State) -> - {noreply, State, timed_caches_manager:get_timeout()}. - -handle_cast (invalidate, State) -> - {stop, normal, State}; -handle_cast (ping, State) -> - {noreply, State, timed_caches_manager:get_timeout()}. - -terminate (_, {DB, ObjectID}) -> - io:format - ( - "~nCache entry timed out or was invalidated: ~p.~n", - [{DB, ObjectID}] - ), - ets:delete(DB, ObjectID). - -code_change (_, State, _) -> - {ok, State}. - -format_status (_, [_, State]) -> - [{data, [{"State", State}]}]. - -handle_info(timeout, State) -> - {stop, normal, State}; -handle_info(_, {DB, ObjectID}) -> - {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout()}. - -%%%% Interface Functions --spec fetch (atom(), any(), any()) -> any(). -fetch (DB, Owner, ObjectID) -> - io:format("~nfetch from cache: ~p.~n", [{DB, {Owner, ObjectID}}]), - case ets:lookup(DB, {Owner, ObjectID}) of - [] -> add_to_cache(DB, Owner, ObjectID); - - [{_, TimerPID, Data}] -> - gen_server:cast(TimerPID, ping), - Data - end. - --spec update (atom(), any(), any(), any()) -> 'ok'. -update (DB, Owner, ObjectID, Data) -> - io:format("~nUpdating cache: ~p.~n", [{DB, {Owner, ObjectID}}]), - case ets:lookup(DB, {Owner, ObjectID}) of - [] -> ok; - - [{_OwnerID, TimerPID, _Data}] -> - gen_server:stop(TimerPID) - end, - add_update_to_cache(DB, Owner, ObjectID, Data). - --spec invalidate (atom(), any(), any()) -> 'ok'. -invalidate (DB, Owner, ObjectID) -> - case ets:lookup(DB, {Owner, ObjectID}) of - [] -> - io:format - ( - "~nInvalidation request on non-stored entry: ~p.~n", - [{DB, Owner, ObjectID}] - ), - ok; - - [{_, TimerPID, _}] -> - io:format - ( - "~nInvalidation request on stored entry: ~p.~n", - [{DB, Owner, ObjectID}] - ), - gen_server:stop(TimerPID), - ok - end. diff --git a/src/battlemap/src/io/timed_caches_manager.erl b/src/battlemap/src/io/timed_caches_manager.erl deleted file mode 100644 index 5901964..0000000 --- a/src/battlemap/src/io/timed_caches_manager.erl +++ /dev/null @@ -1,152 +0,0 @@ --module(timed_caches_manager). --behavior(gen_server). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% 'gen_server' Exports --export( - [ - init/1, - handle_cast/2, - handle_call/3, - terminate/2, - code_change/3, - format_status/2, - handle_info/2 - ] -). - -%%%% Actual Interface --export( - [ - start/0, - new_cache/3, - delete_cache/2, - get_timeout/0 - ] -) -. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -remove_cache (DB) -> - ets:delete(DB). - -add_cache (DB, none) -> - io:format("~nTimed Caches Manager added a new cache. ~n"), - ets:new( - DB, - [ - set, - public, - named_table, - {keypos, 1}, - {read_concurrency, true}, - {heir, none} - ] - ); -add_cache (DB, Heir) -> - io:format("~nTimed Caches Manager added a new cache. ~n"), - ets:new( - DB, - [ - set, - public, - named_table, - {keypos, 1}, - {read_concurrency, true}, - {heir, Heir, DB} - ] - ). - -inherit_cache (CacheList, DB, Heir) -> - case lists:member(DB, CacheList) of - true -> - ets:setopts(DB, {heir, Heir, DB}), - CacheList; - - false -> - [DB|CacheList] - end. - -remove_cache (CacheList, DB) -> - case lists:member(DB, CacheList) of - true -> - remove_cache(DB), - lists:delete(DB, CacheList); - false -> - CacheList - end. - -add_cache (CacheList, DB, Heir) -> - case lists:member(DB, CacheList) of - true when (Heir =:= none) -> - CacheList; - - true -> - ets:setopts(DB, {heir, Heir, DB}), - CacheList; - - false -> - add_cache(DB, Heir), - [DB|CacheList] - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% 'gen_server' functions -init (CacheList) -> - io:format("~nStarting Timed Caches Manager..."), - {ok, CacheList}. - -handle_call ({remove, CacheName}, _Caller, State) -> - {noreply, remove_cache(State, CacheName)}; -handle_call ({add, CacheName, Heir}, _Caller, State)-> - {noreply, add_cache(State, CacheName, Heir)}; -handle_call ({inherit, CacheName, Heir}, _Caller, State)-> - {noreply, inherit_cache(State, CacheName, Heir)}; -handle_call (terminate, _, State) -> - {stop, normal, State}. - -handle_cast ({remove, CacheName}, State) -> - {noreply, remove_cache(State, CacheName)}; -handle_cast ({add, CacheName, Heir}, State)-> - {noreply, add_cache(State, CacheName, Heir)}; -handle_cast ({inherit, CacheName, Heir}, State)-> - {noreply, inherit_cache(State, CacheName, Heir)}; -handle_cast (terminate, State) -> - {stop, normal, State}. - -terminate (_Reason, []) -> - ok; -terminate (Reason, [CacheName|OtherCaches]) -> - remove_cache(CacheName), - terminate(Reason, OtherCaches). - -code_change (_, State, _) -> - {ok, State}. - -format_status (_, [_, State]) -> - [{data, [{"State", State}]}]. - -handle_info(_, State) -> - {noreply, State}. - -%%%% Interface Functions -start () -> - gen_server:start(timed_caches_manager, [], []). - -new_cache (ManagerPid, DB, Heir) -> - gen_server:cast(ManagerPid, {add, DB, Heir}). - -delete_cache (ManagerPid, DB) -> - gen_server:cast(ManagerPid, {remove, DB}). - -get_timeout () -> - 120000. % 2min. diff --git a/src/battlemap/src/query/character_turn.erl b/src/battlemap/src/query/character_turn.erl deleted file mode 100644 index a10cda7..0000000 --- a/src/battlemap/src/query/character_turn.erl +++ /dev/null @@ -1,255 +0,0 @@ --module(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()) -> character_turn_request:type(). -decode_request (BinaryRequest) -> - JSONMap = jiffy:decode(BinaryRequest, [return_maps]), - - character_turn_request:decode(JSONMap). - -%%%% USER AUTHENTICATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec authenticate_user (character_turn_request:type()) -> 'ok'. -authenticate_user (Request) -> - PlayerID = character_turn_request:get_player_id(Request), - SessionToken = character_turn_request:get_session_token(Request), - - security:assert_identity(PlayerID, SessionToken), - security:lock_queries(PlayerID), - - ok. - -%%%% MAIN LOGIC %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec fetch_data (character_turn_request:type()) -> character_turn_data:type(). -fetch_data (Request) -> - PlayerID = character_turn_request:get_player_id(Request), - BattleID = character_turn_request:get_battle_id(Request), - CharacterIX = - character_turn_request:get_character_ix(Request), - - Battle = timed_cache:fetch(battle_db, PlayerID, BattleID), - - character_turn_data:new(Battle, CharacterIX). - -%%%% ASSERTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec assert_user_is_current_player - ( - character_turn_data:type(), - character_turn_request:type() - ) -> 'ok'. -assert_user_is_current_player (Data, Request) -> - PlayerID = character_turn_request:get_player_id(Request), - Battle = character_turn_data:get_battle(Data), - CurrentPlayerTurn = battle:get_current_player_turn(Battle), - CurrentPlayerIX = player_turn:get_player_ix(CurrentPlayerTurn), - CurrentPlayer = battle:get_player(CurrentPlayerIX, Battle), - - true = (PlayerID == player:get_id(CurrentPlayer)), - - ok. - --spec assert_user_owns_played_character - ( - character_turn_data:type(), - character_turn_request:type() - ) -> 'ok'. -assert_user_owns_played_character (Data, Request) -> - PlayerID = character_turn_request:get_player_id(Request), - Character = character_turn_data:get_character(Data), - CharacterOwnerID = character:get_owner_id(Character), - - true = (PlayerID == CharacterOwnerID), - - ok. - --spec assert_character_can_be_played (character_turn_data:type()) -> 'ok'. -assert_character_can_be_played (Data) -> - Character = character_turn_data:get_character(Data), - - true = character:get_is_active(Character), - - ok. - --spec assert_user_permissions - ( - character_turn_data:type(), - 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 - ( - character_turn_update:type() - ) - -> character_turn_update:type(). -finalize_character (Update) -> - Data = character_turn_update:get_data(Update), - Character = character_turn_data:get_character(Data), - - DisabledCharacter = - character:set_is_active(false, Character), - - UpdatedData = - character_turn_data:set_character - ( - DisabledCharacter, - Data - ), - FinalizedData = character_turn_data:clean_battle(UpdatedData), - - character_turn_update:set_data(FinalizedData, Update). - --spec handle_actions - ( - character_turn_data:type(), - character_turn_request:type() - ) - -> character_turn_update:type(). -handle_actions (Data, Request) -> - Actions = character_turn_request:get_actions(Request), - - EmptyUpdate = character_turn_update:new(Data), - PostActionsUpdate = - lists:foldl(fun turn_actions:handle/2, EmptyUpdate, Actions), - - finalize_character(PostActionsUpdate). - --spec update_timeline - ( - character_turn_update:type() - ) - -> character_turn_update:type(). -update_timeline (Update) -> - NewTimelineElements = character_turn_update:get_timeline(Update), - Data = character_turn_update:get_data(Update), - Battle = character_turn_data:get_battle(Data), - PlayerTurn = battle:get_current_player_turn(Battle), - PlayerIX = player_turn:get_player_ix(PlayerTurn), - Player = battle:get_player(PlayerIX, Battle), - - UpdatedPlayer = player:add_to_timeline(NewTimelineElements, Player), - UpdatedBattle = battle:set_player(PlayerIX, UpdatedPlayer, Battle), - UpdatedData = character_turn_data:set_battle(UpdatedBattle, Data), - - character_turn_update:set_data(UpdatedData, Update). - --spec update_data - ( - character_turn_data:type(), - character_turn_request:type() - ) - -> character_turn_update:type(). -update_data (Data, Request) -> - PostActionsUpdate = handle_actions(Data, Request), - PostCharacterTurnUpdate = update_timeline(PostActionsUpdate), - - next_turn:update_if_needed(PostCharacterTurnUpdate). - -%%%% DATABASE UPDATES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec send_to_database - ( - character_turn_update:type(), - character_turn_request:type() - ) - -> 'ok'. -send_to_database (Update, Request) -> - PlayerID = character_turn_request:get_player_id(Request), - BattleID = character_turn_request:get_battle_id(Request), - Ops = character_turn_update:get_db(Update), - Query = db_query:new(battle_db, BattleID, {user, PlayerID}, Ops), - - % TODO: send queries to an actual DB... - - database_shim:commit(Query), - - ok. - --spec send_to_cache - ( - character_turn_update:type(), - character_turn_request:type() - ) - -> 'ok'. -send_to_cache (Update, Request) -> - PlayerID = character_turn_request:get_player_id(Request), - BattleID = character_turn_request:get_battle_id(Request), - Data = character_turn_update:get_data(Update), - Battle = character_turn_data:get_battle(Data), - - timed_cache:update(battle_db, PlayerID, BattleID, Battle), - - ok. - --spec commit_update - ( - character_turn_update:type(), - 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 (character_turn_request:type()) -> 'ok'. -disconnect_user (Request) -> - PlayerID = character_turn_request:get_player_id(Request), - - security:unlock_queries(PlayerID), - - ok. - -%%%% REPLY GENERATION %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_reply (character_turn_update:type()) -> binary(). -generate_reply (Update) -> - NewTimelineItems = character_turn_update:get_timeline(Update), - - TurnResultReply = 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/src/query/load_state.erl b/src/battlemap/src/query/load_state.erl deleted file mode 100644 index f905892..0000000 --- a/src/battlemap/src/query/load_state.erl +++ /dev/null @@ -1,104 +0,0 @@ --module(load_state). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../include/yaws_api.hrl"). - --record -( - input, - { - player_id :: player:id(), - session_token :: binary(), - battle_id :: binary() - } -). - --record -( - query_state, - { - battle :: 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 = 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, - - jiffy:encode - ( - [ - set_timeline:generate(battle:get_encoded_last_turns_effects(Battle)), - set_map:generate(battle:get_battlemap(Battle)) - | - array:sparse_to_list - ( - array:map - ( - fun (IX, Character) -> - add_char:generate(IX, Character, PlayerID) - end, - battle:get_characters(Battle) - ) - ) - ] - ). - --spec handle (binary()) -> binary(). -handle (Req) -> - Input = parse_input(Req), - security:assert_identity(Input#input.player_id, Input#input.session_token), - security:lock_queries(Input#input.player_id), - QueryState = fetch_data(Input), - 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/src/reply/add_char.erl b/src/battlemap/src/reply/add_char.erl deleted file mode 100644 index 86b1e9c..0000000 --- a/src/battlemap/src/reply/add_char.erl +++ /dev/null @@ -1,78 +0,0 @@ --module(add_char). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/3]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec attributes_as_json - ( - attributes:type() - ) -> - {list({binary(), non_neg_integer()})}. -attributes_as_json (Attributes) -> - { - [ - {<<"con">>, attributes:get_constitution(Attributes)}, - {<<"dex">>, attributes:get_dexterity(Attributes)}, - {<<"int">>, attributes:get_intelligence(Attributes)}, - {<<"min">>, attributes:get_mind(Attributes)}, - {<<"spe">>, attributes:get_speed(Attributes)}, - {<<"str">>, attributes:get_strength(Attributes)} - ] - }. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate - ( - non_neg_integer(), - character:type(), - player:id() - ) - -> {list(any())}. -generate (IX, Character, PlayerID) -> - IsAlive = character:get_is_alive(Character), - Attributes = character:get_attributes(Character), - {ActiveWeapon, SecondaryWeapon} = character:get_weapon_ids(Character), - OwnerID = character:get_owner_id(Character), - Location = - case IsAlive of - true -> character:get_location(Character); - _ -> location:get_nowhere() - end, - - { - [ - {<<"msg">>, <<"add_char">>}, - {<<"ix">>, IX}, - {<<"nam">>, character:get_name(Character)}, - {<<"ico">>, character:get_icon(Character)}, - {<<"prt">>, character:get_portrait(Character)}, - { - <<"hea">>, - character:get_current_health(Character) - }, - {<<"lc">>, location:encode(Location)}, - {<<"pla">>, OwnerID}, - { - <<"ena">>, - ( - character:get_is_active(Character) - and - (OwnerID == PlayerID) - ) - }, - {<<"att">>, attributes_as_json(Attributes)}, - {<<"awp">>, ActiveWeapon}, - {<<"swp">>, SecondaryWeapon} - ] - }. diff --git a/src/battlemap/src/reply/set_map.erl b/src/battlemap/src/reply/set_map.erl deleted file mode 100644 index 8518ac5..0000000 --- a/src/battlemap/src/reply/set_map.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(set_map). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([generate/1]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate (battlemap:type()) -> {list(any())}. -generate (Battlemap) -> - { - [ - {<<"msg">>, <<"set_map">>}, - {<<"w">>, battlemap:get_width(Battlemap)}, - {<<"h">>, battlemap:get_height(Battlemap)}, - {<<"t">>, array:sparse_to_list(battlemap:get_tile_ids(Battlemap))} - ] - }. diff --git a/src/battlemap/src/reply/set_timeline.erl b/src/battlemap/src/reply/set_timeline.erl deleted file mode 100644 index bfe621a..0000000 --- a/src/battlemap/src/reply/set_timeline.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(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/src/reply/turn_results.erl b/src/battlemap/src/reply/turn_results.erl deleted file mode 100644 index 0f3ff25..0000000 --- a/src/battlemap/src/reply/turn_results.erl +++ /dev/null @@ -1,27 +0,0 @@ --module(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/src/shim/database_shim.erl b/src/battlemap/src/shim/database_shim.erl deleted file mode 100644 index c64105d..0000000 --- a/src/battlemap/src/shim/database_shim.erl +++ /dev/null @@ -1,137 +0,0 @@ --module(database_shim). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - generate_db/0, - fetch/2, - commit/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -get_db_node () -> - list_to_atom("db_node@" ++ net_adm:localhost()). - --spec generate_random_characters - ( - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - non_neg_integer(), - battlemap:type(), - list(location:type()), - list(character:type()) - ) - -> list(character:type()). -generate_random_characters -( - 0, - 0, - _CharactersPerPlayer, - _TotalCharacterCount, - _Battlemap, - _ForbiddenLocations, - Result -) -> - Result; -generate_random_characters -( - MaxPlayerID, - 0, - CharactersPerPlayer, - TotalCharacterCount, - Battlemap, - ForbiddenLocations, - Result -) -> - generate_random_characters - ( - (MaxPlayerID - 1), - CharactersPerPlayer, - CharactersPerPlayer, - TotalCharacterCount, - Battlemap, - ForbiddenLocations, - Result - ); -generate_random_characters -( - MaxPlayerID, - PlayerCharacterCount, - CharactersPerPlayer, - TotalCharacterCount, - Battlemap, - ForbiddenLocations, - Result -) -> - NewCharacter = - character:random - ( - TotalCharacterCount, - list_to_binary(integer_to_list(MaxPlayerID)), - battlemap:get_width(Battlemap), - battlemap:get_height(Battlemap), - ForbiddenLocations - ), - Character = - case MaxPlayerID of - 0 -> character:set_is_active(true, NewCharacter); - _ -> NewCharacter - end, - - generate_random_characters - ( - MaxPlayerID, - (PlayerCharacterCount - 1), - CharactersPerPlayer, - (TotalCharacterCount + 1), - Battlemap, - [character:get_location(Character)|ForbiddenLocations], - [Character|Result] - ). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_db () -> 'ok'. -generate_db () -> - BattlemapWidth = roll:between(16, 64), - BattlemapHeight = roll:between(16, 64), - Battlemap = battlemap:random(0, BattlemapWidth, BattlemapHeight), - Characters = generate_random_characters(1, 8, 8, 0, Battlemap, [], []), - PlayersAsList = [player:new(<<"0">>), player:new(<<"1">>)], - Battle = battle:new(<<"0">>, PlayersAsList, Battlemap, Characters), - - {atomic, ok} = - rpc:call - ( - get_db_node(), - storage_access, - insert, - [battle_db, <<"0">>, any, Battle] - ), - - ok. - --spec fetch (atom(), any()) -> ({'ok', any()} | 'not_found'). -fetch (DB, ObjectID) -> - {atomic, Reply} = - rpc:call(get_db_node(), storage_access, read, [DB, ObjectID]), - io:format("~ndb_shim:fetch(~p) -> ~p.~n", [{DB, ObjectID}, Reply]), - Reply. - --spec commit (db_query:type()) -> 'ok'. -commit (Query) -> - {atomic, ok} = rpc:call(get_db_node(), storage_access, query, [Query]), - io:format("~ndb_shim:commit(~p) -> ok.~n", [Query]), - ok. diff --git a/src/battlemap/src/struct/attack.erl b/src/battlemap/src/struct/attack.erl deleted file mode 100644 index fed6a56..0000000 --- a/src/battlemap/src/struct/attack.erl +++ /dev/null @@ -1,299 +0,0 @@ --module(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 - ( - statistics:type(), - statistics:type() - ) - -> precision(). -roll_precision (AttackerStatistics, DefenderStatistics) -> - DefenderDodges = statistics:get_dodges(DefenderStatistics), - AttackerAccuracy = statistics:get_accuracy(AttackerStatistics), - MissChance = max(0, (DefenderDodges - AttackerAccuracy)), - case roll:percentage() of - X when (X =< MissChance) -> misses; - X when (X =< (MissChance * 2)) -> grazes; - _ -> hits - end. - --spec roll_damage - ( - statistics:type(), - statistics:type() - ) - -> {non_neg_integer(), boolean()}. -roll_damage (AttackerStatistics, _DefenderStatistics) -> - {MinimumDamage, MaximumDamage} = statistics:get_damages(AttackerStatistics), - MaximumRoll = max(1, MaximumDamage - MinimumDamage), - BaseDamage = MinimumDamage + (rand:uniform(MaximumRoll) - 1), - CriticalHitChance = statistics:get_critical_hits(AttackerStatistics), - case roll:percentage() of - X when (X =< CriticalHitChance) -> {(BaseDamage * 2), true}; - _ -> {BaseDamage, false} - end. - --spec roll_parry (statistics:type()) -> boolean(). -roll_parry (DefenderStatistics) -> - DefenderParryChance = statistics:get_parries(DefenderStatistics), - (roll:percentage() =< DefenderParryChance). - --spec effect_of_attack - ( - order(), - statistics:type(), - statistics:type(), - boolean() - ) - -> type(). -effect_of_attack (Order, AttackerStatistics, DefenderStatistics, CanParry) -> - ParryIsSuccessful = (CanParry and roll_parry(DefenderStatistics)), - {ActualAtkStatistics, ActualDefStatistics} = - case ParryIsSuccessful of - true -> {DefenderStatistics, AttackerStatistics}; - false -> {AttackerStatistics, DefenderStatistics} - end, - - Precision = roll_precision(ActualAtkStatistics, ActualDefStatistics), - {Damage, IsCritical} = roll_damage(ActualAtkStatistics, ActualDefStatistics), - ActualDamage = - case Precision of - misses -> 0; - grazes -> trunc(Damage / 2); - hits -> Damage - end, - - #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(), - statistics:type(), - statistics:type() - ) - -> maybe_type(). -get_description_of -( - {first, CanParry}, - AttackerStatistics, - DefenderStatistics -) -> - effect_of_attack(first, AttackerStatistics, DefenderStatistics, CanParry); -get_description_of -( - {second, CanParry}, - AttackerStatistics, - DefenderStatistics -) -> - AttackerDoubleAttackChange = statistics:get_double_hits(AttackerStatistics), - - case roll:percentage() of - X when (X =< AttackerDoubleAttackChange) -> - effect_of_attack - ( - second, - AttackerStatistics, - DefenderStatistics, - CanParry - ); - - _ -> - nothing - end; -get_description_of -( - {counter, CanParry}, - AttackerStatistics, - DefenderStatistics -) -> - effect_of_attack(counter, DefenderStatistics, AttackerStatistics, 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 -( - (Attack#attack.order == first) - or (Attack#attack.order == second) - or ((Attack#attack.order == counter) and Attack#attack.is_parry) -) -> - Damage = Attack#attack.damage, - - case AttackerHealth of - 0 -> - {nothing, AttackerHealth, DefenderHealth}; - - _ -> - { - Attack, - AttackerHealth, - max(0, (DefenderHealth - Damage)) - } - end; -apply_to_healths -( - Attack, - AttackerHealth, - DefenderHealth -) -when -( - (Attack#attack.order == counter) - or - ( - (Attack#attack.is_parry) - and ((Attack#attack.order == first) or (Attack#attack.order == second)) - ) -) -> - Damage = Attack#attack.damage, - - case DefenderHealth of - 0 -> - {nothing, AttackerHealth, DefenderHealth}; - - _ -> - { - Attack, - max(0, (AttackerHealth - Damage)), - DefenderHealth - } - end. - --spec get_sequence - ( - non_neg_integer(), - weapon:type(), - weapon:type() - ) - -> list(step()). -get_sequence (AttackRange, AttackerWeapon, DefenderWeapon) -> - {AttackerDefenseRange, AttackerAttackRange} = - weapon:get_ranges(AttackerWeapon), - {DefenderDefenseRange, DefenderAttackRange} = - weapon:get_ranges(DefenderWeapon), - - AttackerCanAttack = (AttackRange =< AttackerAttackRange), - AttackerCanAttack = true, - AttackerCanDefend = - (AttackerCanAttack and (AttackRange > AttackerDefenseRange)), - AttackerCanParry = - (AttackerCanDefend and weapon:can_parry(AttackerWeapon)), - - DefenderCanAttack = (AttackRange =< DefenderAttackRange), - DefenderCanDefend = - (DefenderCanAttack and (AttackRange > DefenderDefenseRange)), - DefenderCanParry = - (DefenderCanDefend and 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())}. -% This shouldn't be a possibility. Types in this module are a mess... -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/src/struct/attributes.erl b/src/battlemap/src/struct/attributes.erl deleted file mode 100644 index aca91d3..0000000 --- a/src/battlemap/src/struct/attributes.erl +++ /dev/null @@ -1,108 +0,0 @@ --module(attributes). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - attributes, - { - constitution :: integer(), - dexterity :: integer(), - intelligence :: integer(), - mind :: integer(), - speed :: integer(), - strength :: integer() - } -). - --opaque type() :: #attributes{}. - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_constitution/1, - get_dexterity/1, - get_intelligence/1, - get_mind/1, - get_speed/1, - get_strength/1, - - set_constitution/2, - set_dexterity/2, - set_intelligence/2, - set_mind/2, - set_speed/2, - set_strength/2 - ] -). - -%%%% Accessors --export -( - [ - random/0 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_constitution (type()) -> integer(). -get_constitution (Att) -> Att#attributes.constitution. - --spec get_dexterity (type()) -> integer(). -get_dexterity (Att) -> Att#attributes.dexterity. - --spec get_intelligence (type()) -> integer(). -get_intelligence (Att) -> Att#attributes.intelligence. - --spec get_mind (type()) -> integer(). -get_mind (Att) -> Att#attributes.mind. - --spec get_speed (type()) -> integer(). -get_speed (Att) -> Att#attributes.speed. - --spec get_strength (type()) -> integer(). -get_strength (Att) -> Att#attributes.strength. - --spec set_constitution (integer(), type()) -> type(). -set_constitution (Val, Att) -> Att#attributes{ constitution = Val }. - --spec set_dexterity (integer(), type()) -> type(). -set_dexterity (Val, Att) -> Att#attributes{ dexterity = Val }. - --spec set_intelligence (integer(), type()) -> type(). -set_intelligence (Val, Att) -> Att#attributes{ intelligence = Val }. - --spec set_mind (integer(), type()) -> type(). -set_mind (Val, Att) -> Att#attributes{ mind = Val }. - --spec set_speed (integer(), type()) -> type(). -set_speed (Val, Att) -> Att#attributes{ speed = Val }. - --spec set_strength (integer(), type()) -> type(). -set_strength (Val, Att) -> Att#attributes{ strength = Val }. - --spec random () -> type(). -random () -> - #attributes - { - constitution = roll:percentage(), - dexterity = roll:percentage(), - intelligence = roll:percentage(), - mind = roll:percentage(), - speed = roll:percentage(), - strength = roll:percentage() - }. diff --git a/src/battlemap/src/struct/battle.erl b/src/battlemap/src/struct/battle.erl deleted file mode 100644 index 6a76975..0000000 --- a/src/battlemap/src/struct/battle.erl +++ /dev/null @@ -1,197 +0,0 @@ --module(battle). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - battle, - { - id :: id(), - battlemap :: battlemap:type(), - characters :: array:array(character:type()), - players :: array:array(player:type()), - current_player_turn :: player_turn:type() - } -). - --opaque type() :: #battle{}. - --export_type([type/0, id/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/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/4 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -get_all_timelines (Result, CurrentIndex, EndPoint, ArraySize, Players) -> - Player = array:get(CurrentIndex, Players), - Timeline = 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_battlemap (type()) -> battlemap:type(). -get_battlemap (Battle) -> - Battle#battle.battlemap. - --spec get_characters (type()) -> array:array(character:type()). -get_characters (Battle) -> - Battle#battle.characters. - --spec get_character (non_neg_integer(), type()) -> character:type(). -get_character (IX, Battle) -> - array:get(IX, Battle#battle.characters). - --spec get_players (type()) -> array:array(player:type()). -get_players (Battle) -> - Battle#battle.players. - --spec get_player (non_neg_integer(), type()) -> player:type(). -get_player (IX, Battle) -> - array:get(IX, Battle#battle.players). - --spec get_current_player_turn (type()) -> 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 = 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 (battlemap:type(), type()) -> type(). -set_battlemap (Battlemap, Battle) -> - Battle#battle - { - battlemap = Battlemap - }. - --spec set_characters (array:array(character:type()), type()) -> type(). -set_characters (Characters, Battle) -> - Battle#battle - { - characters = Characters - }. - --spec set_character (non_neg_integer(), character:type(), type()) -> type(). -set_character (IX, Character, Battle) -> - Battle#battle - { - characters = - array:set - ( - IX, - Character, - Battle#battle.characters - ) - }. - --spec set_players (array:array(player:type()), type()) -> type(). -set_players (Players, Battle) -> - Battle#battle - { - players = Players - }. - --spec set_player (non_neg_integer(), player:type(), type()) -> type(). -set_player (IX, Player, Battle) -> - Battle#battle - { - players = - array:set - ( - IX, - Player, - Battle#battle.players - ) - }. - --spec set_current_player_turn (player_turn:type(), type()) -> type(). -set_current_player_turn (PlayerTurn, Battle) -> - Battle#battle - { - current_player_turn = PlayerTurn - }. - --spec new - ( - id(), - list(player:type()), - battlemap:type(), - list(character:type()) - ) - -> type(). -new (ID, PlayersAsList, Battlemap, CharactersAsList) -> - #battle - { - id = ID, - battlemap = Battlemap, - characters = array:from_list(CharactersAsList), - players = array:from_list(PlayersAsList), - current_player_turn = 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/src/struct/battle_action.erl b/src/battlemap/src/struct/battle_action.erl deleted file mode 100644 index 3cedfa7..0000000 --- a/src/battlemap/src/struct/battle_action.erl +++ /dev/null @@ -1,114 +0,0 @@ --module(battle_action). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - move, - { - path :: list(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 direction:decode/1, PathInBinary), - - #move { path = Path }. - --spec decode_atk_action (map()) -> type(). -decode_atk_action (JSONMap) -> - TargetIX = binary_to_integer(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(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/src/struct/battlemap.erl b/src/battlemap/src/struct/battlemap.erl deleted file mode 100644 index dc6bdc7..0000000 --- a/src/battlemap/src/struct/battlemap.erl +++ /dev/null @@ -1,121 +0,0 @@ --module(battlemap). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - battlemap, - { - id :: id(), - width :: integer(), - height :: integer(), - tile_ids :: array:array(tile:id()) - } -). - --opaque type() :: #battlemap{}. - --export_type([type/0, id/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_width/1, - get_height/1, - get_tile_ids/1, - get_tile_id/2 - ] -). - --export -( - [ - random/3 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec generate_random_tile_ids - ( - tile:id(), - list(tile:id()), - non_neg_integer(), - non_neg_integer(), - non_neg_integer() - ) - -> list(tile:id()). -generate_random_tile_ids (_PreviousTileID, Result, _X, 0, _Width) -> - Result; -generate_random_tile_ids (PreviousTileID, Result, 0, Y, Width) -> - generate_random_tile_ids(PreviousTileID, Result, Width, (Y - 1), Width); -generate_random_tile_ids (PreviousTileID, Result, X, Y, Width) -> - NewTile = - case roll:percentage() of - N when (N >= 10) -> PreviousTileID; - _ -> tile:random_id() - end, - generate_random_tile_ids(NewTile, [NewTile|Result], (X - 1), Y, Width). - --spec location_to_array_index - ( - non_neg_integer(), - 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_ids (type()) -> array:array(tile:id()). -get_tile_ids (Battlemap) -> Battlemap#battlemap.tile_ids. - --spec get_tile_id (location:type(), type()) -> tile:id(). -get_tile_id (Location, Battlemap) -> - TileIX = location_to_array_index(Battlemap#battlemap.width, Location), - array:get(TileIX, Battlemap#battlemap.tile_ids). - --spec random - ( - non_neg_integer(), - non_neg_integer(), - non_neg_integer() - ) - -> type(). -random (ID, Width, Height) -> - InitialTile = tile:random_id(), - TileIDs = generate_random_tile_ids(InitialTile, [], Width, Height, Width), - - #battlemap - { - id = list_to_binary(integer_to_list(ID)), - width = Width, - height = Height, - tile_ids = array:from_list(TileIDs) - }. diff --git a/src/battlemap/src/struct/character.erl b/src/battlemap/src/struct/character.erl deleted file mode 100644 index 2792da5..0000000 --- a/src/battlemap/src/struct/character.erl +++ /dev/null @@ -1,239 +0,0 @@ --module(character). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: non_neg_integer(). - --record -( - character, - { - id :: id(), - owner_id :: player:id(), - name :: binary(), - icon :: binary(), - portrait :: binary(), - attributes :: attributes:type(), - statistics :: statistics:type(), - weapon_ids :: {weapon:id(), weapon:id()}, - location :: {non_neg_integer(), non_neg_integer()}, - current_health :: non_neg_integer(), - active :: boolean() - } -). - --opaque type() :: #character{}. - --export_type([type/0, id/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_owner_id/1, - get_name/1, - get_icon/1, - get_portrait/1, - get_attributes/1, - get_statistics/1, - get_weapon_ids/1, - get_location/1, - get_current_health/1, - get_is_alive/1, - get_is_active/1, - - set_weapon_ids/2, - set_statistics/2, - set_location/2, - set_current_health/2, - set_is_active/2, - - get_statistics_field/0, - get_weapons_field/0, - get_location_field/0, - get_current_health_field/0, - get_active_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 = roll:between(0, (BattlemapWidth - 1)), - Y = 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_owner_id (type()) -> player:id(). -get_owner_id (Char) -> Char#character.owner_id. - --spec get_name (type()) -> binary(). -get_name (Char) -> Char#character.name. - --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()) -> attributes:type(). -get_attributes (Char) -> Char#character.attributes. - --spec get_weapon_ids (type()) -> {weapon:id(), weapon:id()}. -get_weapon_ids (Char) -> Char#character.weapon_ids. - --spec get_statistics (type()) -> statistics:type(). -get_statistics (Char) -> Char#character.statistics. - --spec get_location (type()) -> {non_neg_integer(), non_neg_integer()}. -get_location (Char) -> - true = get_is_alive(Char), - Char#character.location. - --spec get_current_health (type()) -> non_neg_integer(). -get_current_health (Char) -> Char#character.current_health. - --spec get_is_alive (type()) -> boolean(). -get_is_alive (Char) -> - (Char#character.current_health > 0). - --spec get_is_active (type()) -> boolean(). -get_is_active (Char) -> - ( - Char#character.active - and - get_is_alive(Char) - ). - --spec set_location - ( - {non_neg_integer(), non_neg_integer()}, - type() - ) - -> type(). -set_location (Location, Char) -> - Char#character - { - location = Location - }. - --spec set_current_health (non_neg_integer(), type()) -> type(). -set_current_health (Health, Char) -> - Char#character - { - current_health = max(0, Health) - }. - --spec set_is_active (boolean(), type()) -> type(). -set_is_active (Active, Char) -> - Char#character - { - active = Active - }. - --spec set_weapon_ids - ( - {weapon:id(), weapon:id()}, - type() - ) - -> type(). -set_weapon_ids (WeaponIDs, Char) -> - Char#character - { - weapon_ids = WeaponIDs - }. - --spec set_statistics - ( - statistics:type(), - type() - ) - -> type(). -set_statistics (Stats, Char) -> - Char#character - { - statistics = Stats - }. - -%%%% Utils --spec random - ( - non_neg_integer(), - player:id(), - non_neg_integer(), - non_neg_integer(), - list({non_neg_integer(), non_neg_integer()}) - ) - -> type(). -random (ID, OwnerID, BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> - Location = - find_random_location(BattlemapWidth, BattlemapHeight, ForbiddenLocations), - WeaponIDs = {weapon:random_id(), weapon:random_id()}, - Attributes = attributes:random(), - Statistics = statistics:new(Attributes, WeaponIDs), - IDAsListString = integer_to_list(ID), - IDAsBinaryString = list_to_binary(IDAsListString), - - #character - { - id = ID, - owner_id = OwnerID, - name = list_to_binary("Char" ++ IDAsListString), - icon = IDAsBinaryString, - portrait = IDAsBinaryString, - attributes = Attributes, - weapon_ids = WeaponIDs, - statistics = Statistics, - location = Location, - current_health = statistics:get_health(Statistics), - active = false - }. - --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_active_field() -> non_neg_integer(). -get_active_field () -> #character.active. diff --git a/src/battlemap/src/struct/character_turn_data.erl b/src/battlemap/src/struct/character_turn_data.erl deleted file mode 100644 index 6ea744b..0000000 --- a/src/battlemap/src/struct/character_turn_data.erl +++ /dev/null @@ -1,102 +0,0 @@ --module(character_turn_data). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - type, - { - dirty :: boolean(), - battle :: battle:type(), - character :: 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 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (battle:type(), non_neg_integer()) -> type(). -new (Battle, CharacterIX) -> - Character = 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()) -> battle:type(). -get_battle (Data) -> Data#type.battle. - --spec get_character (type()) -> 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 (battle:type(), type()) -> type(). -set_battle (Battle, Data) -> - Data#type{ battle = Battle }. - --spec set_character (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 = - battle:set_character - ( - Data#type.character_ix, - Data#type.character, - Data#type.battle - ) - }. - diff --git a/src/battlemap/src/struct/character_turn_request.erl b/src/battlemap/src/struct/character_turn_request.erl deleted file mode 100644 index ca8f44f..0000000 --- a/src/battlemap/src/struct/character_turn_request.erl +++ /dev/null @@ -1,84 +0,0 @@ --module(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 :: player:id(), - session_token :: binary(), - battle_id :: binary(), - character_ix :: non_neg_integer(), - actions :: list(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 = binary_to_integer(maps:get(?CHAR_IX_FIELD, Map)), - EncodedActions = maps:get(?ACTIONS_FIELD, Map), - Actions = lists:map(fun 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()) -> 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(battle_action:type()). -get_actions (Request) -> Request#type.actions. diff --git a/src/battlemap/src/struct/character_turn_update.erl b/src/battlemap/src/struct/character_turn_update.erl deleted file mode 100644 index 07cb562..0000000 --- a/src/battlemap/src/struct/character_turn_update.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(character_turn_update). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - type, - { - data :: character_turn_data:type(), - timeline :: list(any()), - db :: list(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/2, - add_to_db/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (character_turn_data:type()) -> type(). -new (Data) -> - #type - { - data = Data, - timeline = [], - db = [] - }. - --spec get_data (type()) -> 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(db_query:op()). -get_db (Update) -> Update#type.db. - --spec set_data (character_turn_data:type(), type()) -> type(). -set_data (Data, Update) -> - Update#type{ data = Data}. - --spec add_to_timeline (turn_result:type(), type()) -> type(). -add_to_timeline (Item, Update) -> - Update#type{ timeline = [turn_result:encode(Item)|Update#type.timeline] }. - --spec add_to_db (db_query:op(), type()) -> type(). -add_to_db (Item, Update) -> - Update#type{ db = [Item|Update#type.db] }. diff --git a/src/battlemap/src/struct/db_query.erl b/src/battlemap/src/struct/db_query.erl deleted file mode 100644 index 5d1e8d2..0000000 --- a/src/battlemap/src/struct/db_query.erl +++ /dev/null @@ -1,59 +0,0 @@ --module(db_query). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../../db/include/db_query.hrl"). - --opaque op() :: db_query_op(). --opaque type() :: db_query(). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([type/0, op/0]). - --export -( - [ - new/4, - set_field/2, - add_to_field/2, - update_indexed/3 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (atom(), any(), db_user:user(), list(op())) -> type(). -new (DBName, ObjectID, User, Ops) -> - #db_query - { - db = DBName, - id = ObjectID, - user = User, - ops = Ops - }. - --spec set_field (non_neg_integer(), any()) -> op(). -set_field (Field, Value) -> - #set_field { field = Field, value = Value }. - --spec add_to_field (non_neg_integer(), list(any())) -> op(). -add_to_field (Field, Values) -> - #add_to_field { field = Field, values = Values }. - --spec update_indexed - ( - non_neg_integer(), - non_neg_integer(), - list(op()) - ) - -> op(). -update_indexed (Field, IX, Updates) -> - #update_indexed { field = Field, ix = IX, ops = Updates}. diff --git a/src/battlemap/src/struct/direction.erl b/src/battlemap/src/struct/direction.erl deleted file mode 100644 index be43a13..0000000 --- a/src/battlemap/src/struct/direction.erl +++ /dev/null @@ -1,38 +0,0 @@ --module(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/src/struct/location.erl b/src/battlemap/src/struct/location.erl deleted file mode 100644 index e54584b..0000000 --- a/src/battlemap/src/struct/location.erl +++ /dev/null @@ -1,90 +0,0 @@ --module(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 (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/src/struct/player.erl b/src/battlemap/src/struct/player.erl deleted file mode 100644 index 4cd073e..0000000 --- a/src/battlemap/src/struct/player.erl +++ /dev/null @@ -1,72 +0,0 @@ --module(player). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type id() :: binary(). - --record -( - player, - { - id :: id(), - timeline :: list(any()) - } -). - --opaque type() :: #player{}. - --export_type([type/0, id/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - get_id/1, - get_timeline/1, - add_to_timeline/2, - reset_timeline/1 - ] -). - --export -( - [ - new/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_id (type()) -> id(). -get_id (Player) -> Player#player.id. - --spec get_timeline (type()) -> list(any()). -get_timeline (Player) -> Player#player.timeline. - --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 (id()) -> type(). -new (ID) -> - #player - { - id = ID, - timeline = [] - }. - diff --git a/src/battlemap/src/struct/player_turn.erl b/src/battlemap/src/struct/player_turn.erl deleted file mode 100644 index a558bfc..0000000 --- a/src/battlemap/src/struct/player_turn.erl +++ /dev/null @@ -1,73 +0,0 @@ --module(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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 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 (non_neg_integer(), type()) -> type(). -next (PlayersCount, CurrentPlayerTurn) -> - CurrentPlayerIX = CurrentPlayerTurn#player_turn.player_ix, - CurrentTurnNumber = CurrentPlayerTurn#player_turn.number, - - NextPlayerIX = ((CurrentPlayerIX + 1) rem PlayersCount), - NextTurnNumber = - case NextPlayerIX of - 0 -> (CurrentTurnNumber + 1); - _ -> CurrentTurnNumber - end, - - new(NextTurnNumber, NextPlayerIX). diff --git a/src/battlemap/src/struct/statistics.erl b/src/battlemap/src/struct/statistics.erl deleted file mode 100644 index 3406d9a..0000000 --- a/src/battlemap/src/struct/statistics.erl +++ /dev/null @@ -1,193 +0,0 @@ --module(statistics). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - statistics, - { - movement_points :: non_neg_integer(), - health :: non_neg_integer(), - dodges :: non_neg_integer(), - parries :: non_neg_integer(), - damage_min :: non_neg_integer(), - damage_max :: non_neg_integer(), - accuracy :: non_neg_integer(), - double_hits :: non_neg_integer(), - critical_hits :: non_neg_integer() - } -). - --opaque type() :: #statistics{}. - --export_type([type/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_movement_points/1, - get_health/1, - get_dodges/1, - get_parries/1, - get_damage_min/1, - get_damage_max/1, - get_accuracy/1, - get_double_hits/1, - get_critical_hits/1, - - get_damages/1 - ] -). - --export -( - [ - new/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec ceil (float()) -> integer(). -ceil (F) -> - I = trunc(F), - case (F > I) of - true -> (I + 1); - _ -> I - end. - --spec float_to_int (float()) -> integer(). -float_to_int (F) -> ceil(F). - --spec min_max (number(), number(), number()) -> number(). -min_max (Min, Max, V) -> min(Max, max(Min, V)). - --spec average (list(number())) -> number(). -%average ([]) -> 0; -average (L) -> lists:sum(L) / length(L). - -% V | 010 | 030 | 050 | 070 | 100 | -% F | 004 | 023 | 058 | 104 | 200 | --spec gentle_squared_growth (number()) -> non_neg_integer(). -gentle_squared_growth (V) -> float_to_int(math:pow(V, 1.8) / 20). - -% V | 010 | 030 | 050 | 070 | 100 | -% F | 001 | 005 | 018 | 041 | 100 | --spec sudden_squared_growth (number()) -> non_neg_integer(). -sudden_squared_growth (V) -> float_to_int(math:pow(V, 2.5) / 1000). - -% V | 010 | 030 | 050 | 070 | 100 | -% F | 002 | 006 | 016 | 049 | 256 | --spec sudden_exp_growth (number()) -> non_neg_integer(). -sudden_exp_growth (V) -> float_to_int(math:pow(4, V / 25)). - -% V | 010 | 030 | 050 | 070 | 100 | -% F | 040 | 066 | 079 | 088 | 099 | -% Seems too generous, values for attributes below 50 should dip faster and -% lower. -%-spec already_high_slow_growth (non_neg_integer()) -> non_neg_integer(). -%already_high_slow_growth (V) -> float_to_int(30 * math:log((V + 5)/4)). - --spec damage_base_modifier (non_neg_integer()) -> float(). -damage_base_modifier (Strength) -> ((math:pow(Strength, 1.8) / 2000.0) - 0.75). - --spec apply_damage_base_modifier - ( - float(), - non_neg_integer() - ) - -> non_neg_integer(). -apply_damage_base_modifier (Modifier, BaseValue) -> - max(0, float_to_int(BaseValue + (BaseValue * Modifier))). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_movement_points (type()) -> non_neg_integer(). -get_movement_points (Stats) -> Stats#statistics.movement_points. - --spec get_health (type()) -> non_neg_integer(). -get_health (Stats) -> Stats#statistics.health. - --spec get_dodges (type()) -> non_neg_integer(). -get_dodges (Stats) -> Stats#statistics.dodges. - --spec get_parries (type()) -> non_neg_integer(). -get_parries (Stats) -> Stats#statistics.parries. - --spec get_damage_min (type()) -> non_neg_integer(). -get_damage_min (Stats) -> Stats#statistics.damage_min. - --spec get_damage_max (type()) -> non_neg_integer(). -get_damage_max (Stats) -> Stats#statistics.damage_max. - --spec get_accuracy (type()) -> non_neg_integer(). -get_accuracy (Stats) -> Stats#statistics.accuracy. - --spec get_double_hits (type()) -> non_neg_integer(). -get_double_hits (Stats) -> Stats#statistics.double_hits. - --spec get_critical_hits (type()) -> non_neg_integer(). -get_critical_hits (Stats) -> Stats#statistics.critical_hits. - --spec get_damages (type()) -> {non_neg_integer(), non_neg_integer()}. -get_damages (Stats) -> - { - Stats#statistics.damage_min, - Stats#statistics.damage_max - }. - --spec new - ( - attributes:type(), - {weapon:id(), weapon:id()} - ) - -> type(). -new (BaseAttributes, WeaponIDs) -> - {ActiveWeaponID, _} = WeaponIDs, - ActiveWeapon = weapon:from_id(ActiveWeaponID), - {MinDamage, MaxDamage} = weapon:get_damages(ActiveWeapon), - Attributes = weapon:apply_to_attributes(BaseAttributes, ActiveWeapon), - Constitution = attributes:get_constitution(Attributes), - Dexterity = attributes:get_dexterity(Attributes), - Intelligence = attributes:get_intelligence(Attributes), - Mind = attributes:get_mind(Attributes), - Speed = attributes:get_speed(Attributes), - Strength = attributes:get_strength(Attributes), - DamageBaseModifier = damage_base_modifier(Strength), - - #statistics - { - movement_points = - gentle_squared_growth - ( - average([Mind, Constitution, Constitution, Speed, Speed, Speed]) - ), - health = - gentle_squared_growth(average([Mind, Constitution, Constitution])), - dodges = - min_max(0, 100, sudden_exp_growth(average([Dexterity, Mind, Speed]))), - parries = - min_max - ( - 0, - 75, - sudden_exp_growth - ( - average([Dexterity, Intelligence, Speed, Strength]) - ) - ), - damage_min = apply_damage_base_modifier(DamageBaseModifier, MinDamage), - damage_max = apply_damage_base_modifier(DamageBaseModifier, MaxDamage), - accuracy = min_max(0, 100, sudden_squared_growth(Dexterity)), - double_hits = - min_max(0, 100, sudden_squared_growth(average([Mind, Speed]))), - critical_hits = min_max(0, 100, sudden_squared_growth(Intelligence)) - }. diff --git a/src/battlemap/src/struct/tile.erl b/src/battlemap/src/struct/tile.erl deleted file mode 100644 index a2e04ee..0000000 --- a/src/battlemap/src/struct/tile.erl +++ /dev/null @@ -1,47 +0,0 @@ --module(tile). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --opaque id() :: non_neg_integer(). --opaque type() :: id(). - --export_type([type/0, id/0]). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - get_cost/1, - cost_when_oob/0 - ] -). - --export -( - [ - random_id/0 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec cost_when_oob () -> non_neg_integer(). -cost_when_oob () -> 255. - --spec get_cost (id()) -> non_neg_integer(). -get_cost (N) -> - if - (N =< 200) -> (N + 8); - true -> cost_when_oob() - end. - --spec random_id () -> id(). -random_id () -> - roll:between(0, 15). diff --git a/src/battlemap/src/struct/turn_result.erl b/src/battlemap/src/struct/turn_result.erl deleted file mode 100644 index 42a3a18..0000000 --- a/src/battlemap/src/struct/turn_result.erl +++ /dev/null @@ -1,142 +0,0 @@ --module(turn_result). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%% --record -( - switched_weapon, - { - character_ix :: character:id() - } -). - --record -( - moved, - { - character_ix :: character:id(), - path :: list(direction:enum()), - new_location :: location:type() - } -). - --record -( - attacked, - { - attacker_ix :: character:id(), - defender_ix :: character:id(), - sequence :: list(attack:type()) - } -). - --opaque type() :: (#switched_weapon{} | #moved{} | #attacked{}). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([type/0]). - --export -( - [ - new_character_switched_weapons/1, - new_character_moved/3, - new_character_attacked/3 - ] -). - --export -( - [ - encode/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new_character_switched_weapons (character:id()) -> type(). -new_character_switched_weapons (CharacterIX) -> - #switched_weapon { character_ix = CharacterIX }. - --spec new_character_moved - ( - character:id(), - list(direction:enum()), - location:type() - ) - -> type(). -new_character_moved (CharacterIX, Path, NewLocation) -> - #moved - { - character_ix = CharacterIX, - path = Path, - new_location = NewLocation - }. - --spec new_character_attacked - ( - character:id(), - character:id(), - list(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 direction:encode/1, Path), - EncodedNewLocation = 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 attack:encode/1, Sequence), - - { - [ - {<<"t">>, <<"atk">>}, - {<<"aix">>, AttackerIX}, - {<<"dix">>, DefenderIX}, - {<<"seq">>, EncodedSequence} - ] - }; -encode (Other) -> - io:format("~n invalid encode param\"~p\"~n", [Other]), - true = Other. diff --git a/src/battlemap/src/struct/weapon.erl b/src/battlemap/src/struct/weapon.erl deleted file mode 100644 index 7d3c874..0000000 --- a/src/battlemap/src/struct/weapon.erl +++ /dev/null @@ -1,361 +0,0 @@ --module(weapon). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --opaque id() :: non_neg_integer(). - --type range_type() :: 'ranged' | 'melee'. --type range_mod() :: 'long' | 'short'. --type damage_type() :: 'slash' | 'pierce' | 'blunt'. --type damage_mod() :: 'heavy' | 'light'. - --record -( - weapon, - { - id :: id(), - name :: binary(), - range_type :: range_type(), - range_mod :: range_mod(), - damage_type :: damage_type(), - damage_mod :: damage_mod() - } -). - --opaque type() :: #weapon{}. - --export_type([type/0, id/0]). --export_type -( - [ - range_type/0, - range_mod/0, - damage_type/0, - damage_mod/0 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_range_type/1, - get_ranges/1, - get_damages/1 - ] -). - --export -( - [ - random_id/0, - from_id/1, - can_parry/1, - apply_to_attributes/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec ranges_of_type - ( - range_type(), - range_mod() - ) - -> {non_neg_integer(), non_neg_integer()}. -ranges_of_type (ranged, long) -> {2, 6}; -ranges_of_type (ranged, short) -> {1, 4}; -ranges_of_type (melee, long) -> {0, 2}; -ranges_of_type (melee, short) -> {0, 1}. - --spec damages_of_type - ( - range_type(), - damage_mod() - ) - -> {non_neg_integer(), non_neg_integer()}. -damages_of_type (ranged, heavy) -> {10, 25}; -damages_of_type (ranged, light) -> {5, 20}; -damages_of_type (melee, heavy) -> {20, 35}; -damages_of_type (melee, light) -> {15, 30}. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_id (type()) -> id(). -get_id (Wp) -> Wp#weapon.id. - --spec get_range_type (type()) -> range_type(). -get_range_type (Wp) -> Wp#weapon.range_type. - --spec get_ranges (type()) -> {non_neg_integer(), non_neg_integer()}. -get_ranges (Wp) -> - ranges_of_type(Wp#weapon.range_type, Wp#weapon.range_mod). - --spec get_damages (type()) -> {non_neg_integer(), non_neg_integer()}. -get_damages (Wp) -> - damages_of_type(Wp#weapon.range_type, Wp#weapon.damage_mod). - --spec can_parry (type()) -> boolean(). -can_parry (Wp) -> (Wp#weapon.range_type == melee). - --spec from_id (id()) -> type(). -from_id (0) -> - #weapon{ - id = 0, - name = <<"None">>, - range_type = melee, - range_mod = short, - damage_type = blunt, - damage_mod = light - }; -from_id (1) -> - #weapon{ - id = 1, - name = <<"Dagger">>, - range_type = melee, - range_mod = short, - damage_type = slash, - damage_mod = light - }; -from_id (2) -> - #weapon{ - id = 2, - name = <<"Sword">>, - range_type = melee, - range_mod = short, - damage_type = slash, - damage_mod = heavy - }; -from_id (3) -> - #weapon{ - id = 3, - name = <<"Claymore">>, - range_type = melee, - range_mod = long, - damage_type = slash, - damage_mod = light - }; -from_id (4) -> - #weapon{ - id = 4, - name = <<"Bardiche">>, - range_type = melee, - range_mod = long, - damage_type = slash, - damage_mod = heavy - }; -from_id (5) -> - #weapon{ - id = 5, - name = <<"Stiletto">>, - range_type = melee, - range_mod = short, - damage_type = pierce, - damage_mod = light - }; -from_id (6) -> - #weapon{ - id = 6, - name = <<"Pickaxe">>, - range_type = melee, - range_mod = short, - damage_type = pierce, - damage_mod = heavy - }; -from_id (7) -> - #weapon{ - id = 7, - name = <<"Rapier">>, - range_type = melee, - range_mod = long, - damage_type = pierce, - damage_mod = light - }; -from_id (8) -> - #weapon{ - id = 8, - name = <<"Pike">>, - range_type = melee, - range_mod = long, - damage_type = pierce, - damage_mod = heavy - }; -from_id (9) -> - #weapon{ - id = 9, - name = <<"Club">>, - range_type = melee, - range_mod = short, - damage_type = blunt, - damage_mod = light - }; -from_id (10) -> - #weapon{ - id = 10, - name = <<"Mace">>, - range_type = melee, - range_mod = short, - damage_type = blunt, - damage_mod = heavy - }; -from_id (11) -> - #weapon{ - id = 11, - name = <<"Staff">>, - range_type = melee, - range_mod = long, - damage_type = blunt, - damage_mod = light - }; -from_id (12) -> - #weapon{ - id = 12, - name = <<"War Hammer">>, - range_type = melee, - range_mod = long, - damage_type = blunt, - damage_mod = heavy - }; -from_id (13) -> - #weapon{ - id = 13, - name = <<"Short Bow (Broadhead)">>, - range_type = ranged, - range_mod = short, - damage_type = slash, - damage_mod = light - }; -from_id (14) -> - #weapon{ - id = 14, - name = <<"Short Bow (Blunt)">>, - range_type = ranged, - range_mod = short, - damage_type = blunt, - damage_mod = light - }; -from_id (15) -> - #weapon{ - id = 15, - name = <<"Short Bow (Bodkin Point)">>, - range_type = ranged, - range_mod = short, - damage_type = pierce, - damage_mod = light - }; -from_id (16) -> - #weapon{ - id = 16, - name = <<"Long Bow (Broadhead)">>, - range_type = ranged, - range_mod = long, - damage_type = slash, - damage_mod = light - }; -from_id (17) -> - #weapon{ - id = 17, - name = <<"Long Bow (Blunt)">>, - range_type = ranged, - range_mod = long, - damage_type = blunt, - damage_mod = light - }; -from_id (18) -> - #weapon{ - id = 18, - name = <<"Long Bow (Bodkin Point)">>, - range_type = ranged, - range_mod = long, - damage_type = pierce, - damage_mod = light - }; -from_id (19) -> - #weapon{ - id = 19, - name = <<"Crossbow (Broadhead)">>, - range_type = ranged, - range_mod = short, - damage_type = slash, - damage_mod = heavy - }; -from_id (20) -> - #weapon{ - id = 20, - name = <<"Crossbow (Blunt)">>, - range_type = ranged, - range_mod = short, - damage_type = blunt, - damage_mod = heavy - }; -from_id (21) -> - #weapon{ - id = 21, - name = <<"Crossbow (Bodkin Point)">>, - range_type = ranged, - range_mod = short, - damage_type = pierce, - damage_mod = heavy - }; -from_id (22) -> - #weapon{ - id = 22, - name = <<"Arbalest (Broadhead)">>, - range_type = ranged, - range_mod = long, - damage_type = slash, - damage_mod = heavy - }; -from_id (23) -> - #weapon{ - id = 23, - name = <<"Arbalest (Blunt)">>, - range_type = ranged, - range_mod = long, - damage_type = blunt, - damage_mod = heavy - }; -from_id (24) -> - #weapon{ - id = 24, - name = <<"Arbalest (Bodkin Point)">>, - range_type = ranged, - range_mod = long, - damage_type = pierce, - damage_mod = heavy - }. - --spec random_id () -> id(). -random_id () -> roll:between(0, 24). - --spec apply_to_attributes - ( - attributes:type(), - weapon:type() - ) - -> attributes:type(). -apply_to_attributes (Attributes, Weapon) -> - Dexterity = attributes:get_dexterity(Attributes), - Speed = attributes:get_speed(Attributes), - RangeModifier = Weapon#weapon.range_mod, - DamageModifier = Weapon#weapon.damage_mod, - WithRangeModifier = - case RangeModifier of - long -> - attributes:set_dexterity(max(0, (Dexterity - 20)), Attributes); - _ -> Attributes - end, - case DamageModifier of - heavy -> - attributes:set_speed(max(0, (Speed - 20)), WithRangeModifier); - _ -> WithRangeModifier - end. - diff --git a/src/battlemap/src/util/array_util.erl b/src/battlemap/src/util/array_util.erl deleted file mode 100644 index 418d9ce..0000000 --- a/src/battlemap/src/util/array_util.erl +++ /dev/null @@ -1,105 +0,0 @@ --module(array_util). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - any/2, - none/2, - all/2, - - mapiff/3 - ] -). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec any_internals - ( - fun((any()) -> boolean()), - array:array(any()), - non_neg_integer() - ) - -> boolean(). -any_internals (_, _, 0) -> - false; -any_internals (Fun, Array, PrevIX) -> - IX = (PrevIX - 1), - case Fun(array:get(IX, Array)) of - true -> true; - _ -> any_internals(Fun, Array, IX) - end. - --spec all_internals - ( - fun((any()) -> boolean()), - array:array(any()), - non_neg_integer() - ) - -> boolean(). -all_internals (_, _, 0) -> - true; -all_internals (Fun, Array, PrevIX) -> - IX = (PrevIX - 1), - case Fun(array:get(IX, Array)) of - true -> any_internals(Fun, Array, IX); - _ -> false - end. - --spec mapiff_internals - ( - fun((any()) -> boolean()), - fun((any()) -> any()), - array:array(any()), - list(non_neg_integer()), - non_neg_integer() - ) - -> {array:array(any()), list(non_neg_integer())}. -mapiff_internals (_, _, Array, IXList, 0) -> - {Array, IXList}; -mapiff_internals (Cond, Map, Array, IXList, PrevIX) -> - IX = (PrevIX - 1), - Elem = array:get(IX, Array), - - case Cond(Elem) of - false -> mapiff_internals(Cond, Map, Array, IXList, IX); - _ -> - mapiff_internals - ( - Cond, - Map, - array:set(IX, Map(Elem), Array), - [IX|IXList], - IX - ) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec any (fun((any()) -> boolean()), array:array(any())) -> boolean(). -any (Fun, Array) -> - any_internals(Fun, Array, array:size(Array)). - --spec all (fun((any()) -> boolean()), array:array(any())) -> boolean(). -all (Fun, Array) -> - all_internals(Fun, Array, array:size(Array)). - --spec none (fun((any()) -> boolean()), array:array(any())) -> boolean(). -none (Fun, Array) -> - not any(Fun, Array). - --spec mapiff - ( - fun((any()) -> boolean()), - fun((any()) -> any()), - array:array(any()) - ) - -> {array:array(any()), list(non_neg_integer())}. -mapiff (Cond, Map, Array) -> - mapiff_internals(Cond, Map, Array, [], array:size(Array)). diff --git a/src/battlemap/struct/bm_attack.erl b/src/battlemap/struct/bm_attack.erl new file mode 100644 index 0000000..fe7d8b8 --- /dev/null +++ b/src/battlemap/struct/bm_attack.erl @@ -0,0 +1,300 @@ +-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 + ( + bm_statistics:type(), + bm_statistics:type() + ) + -> precision(). +roll_precision (AttackerStatistics, DefenderStatistics) -> + DefenderDodges = bm_statistics:get_dodges(DefenderStatistics), + AttackerAccuracy = bm_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 + ( + bm_statistics:type(), + bm_statistics:type() + ) + -> {non_neg_integer(), boolean()}. +roll_damage (AttackerStatistics, _DefenderStatistics) -> + {MinimumDamage, MaximumDamage} = + bm_statistics:get_damages(AttackerStatistics), + MaximumRoll = max(1, MaximumDamage - MinimumDamage), + BaseDamage = MinimumDamage + (rand:uniform(MaximumRoll) - 1), + CriticalHitChance = bm_statistics:get_critical_hits(AttackerStatistics), + case sh_roll:percentage() of + X when (X =< CriticalHitChance) -> {(BaseDamage * 2), true}; + _ -> {BaseDamage, false} + end. + +-spec roll_parry (bm_statistics:type()) -> boolean(). +roll_parry (DefenderStatistics) -> + DefenderParryChance = bm_statistics:get_parries(DefenderStatistics), + (sh_roll:percentage() =< DefenderParryChance). + +-spec effect_of_attack + ( + order(), + bm_statistics:type(), + bm_statistics:type(), + boolean() + ) + -> type(). +effect_of_attack (Order, AttackerStatistics, DefenderStatistics, CanParry) -> + ParryIsSuccessful = (CanParry and roll_parry(DefenderStatistics)), + {ActualAtkStatistics, ActualDefStatistics} = + case ParryIsSuccessful of + true -> {DefenderStatistics, AttackerStatistics}; + false -> {AttackerStatistics, DefenderStatistics} + end, + + Precision = roll_precision(ActualAtkStatistics, ActualDefStatistics), + {Damage, IsCritical} = roll_damage(ActualAtkStatistics, ActualDefStatistics), + ActualDamage = + case Precision of + misses -> 0; + grazes -> trunc(Damage / 2); + hits -> Damage + end, + + #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_statistics:type(), + bm_statistics:type() + ) + -> maybe_type(). +get_description_of +( + {first, CanParry}, + AttackerStatistics, + DefenderStatistics +) -> + effect_of_attack(first, AttackerStatistics, DefenderStatistics, CanParry); +get_description_of +( + {second, CanParry}, + AttackerStatistics, + DefenderStatistics +) -> + AttackerDoubleAttackChange = + bm_statistics:get_double_hits(AttackerStatistics), + + case sh_roll:percentage() of + X when (X =< AttackerDoubleAttackChange) -> + effect_of_attack + ( + second, + AttackerStatistics, + DefenderStatistics, + CanParry + ); + + _ -> + nothing + end; +get_description_of +( + {counter, CanParry}, + AttackerStatistics, + DefenderStatistics +) -> + effect_of_attack(counter, DefenderStatistics, AttackerStatistics, 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 +( + (Attack#attack.order == first) + or (Attack#attack.order == second) + or ((Attack#attack.order == counter) and Attack#attack.is_parry) +) -> + Damage = Attack#attack.damage, + + case AttackerHealth of + 0 -> + {nothing, AttackerHealth, DefenderHealth}; + + _ -> + { + Attack, + AttackerHealth, + max(0, (DefenderHealth - Damage)) + } + end; +apply_to_healths +( + Attack, + AttackerHealth, + DefenderHealth +) +when +( + (Attack#attack.order == counter) + or + ( + (Attack#attack.is_parry) + and ((Attack#attack.order == first) or (Attack#attack.order == second)) + ) +) -> + Damage = Attack#attack.damage, + + case DefenderHealth of + 0 -> + {nothing, AttackerHealth, DefenderHealth}; + + _ -> + { + Attack, + max(0, (AttackerHealth - Damage)), + DefenderHealth + } + end. + +-spec get_sequence + ( + non_neg_integer(), + bm_weapon:type(), + bm_weapon:type() + ) + -> list(step()). +get_sequence (AttackRange, AttackerWeapon, DefenderWeapon) -> + {AttackerDefenseRange, AttackerAttackRange} = + bm_weapon:get_ranges(AttackerWeapon), + {DefenderDefenseRange, DefenderAttackRange} = + bm_weapon:get_ranges(DefenderWeapon), + + AttackerCanAttack = (AttackRange =< AttackerAttackRange), + AttackerCanAttack = true, + AttackerCanDefend = + (AttackerCanAttack and (AttackRange > AttackerDefenseRange)), + AttackerCanParry = + (AttackerCanDefend and weapon:can_parry(AttackerWeapon)), + + DefenderCanAttack = (AttackRange =< DefenderAttackRange), + DefenderCanDefend = + (DefenderCanAttack and (AttackRange > DefenderDefenseRange)), + DefenderCanParry = + (DefenderCanDefend and 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 new file mode 100644 index 0000000..08c4943 --- /dev/null +++ b/src/battlemap/struct/bm_battle.erl @@ -0,0 +1,197 @@ +-module(bm_battle). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + battle, + { + id :: 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_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/4 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 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_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()) + ) + -> type(). +new (ID, PlayersAsList, Battlemap, CharactersAsList) -> + #battle + { + id = ID, + 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 new file mode 100644 index 0000000..abdc1c6 --- /dev/null +++ b/src/battlemap/struct/bm_battle_action.erl @@ -0,0 +1,114 @@ +-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 = binary_to_integer(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(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 new file mode 100644 index 0000000..c3eabb0 --- /dev/null +++ b/src/battlemap/struct/bm_battlemap.erl @@ -0,0 +1,121 @@ +-module(bm_battlemap). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + battlemap, + { + id :: id(), + width :: integer(), + height :: integer(), + tile_ids :: array:array(bm_tile:id()) + } +). + +-opaque type() :: #battlemap{}. + +-export_type([type/0, id/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_width/1, + get_height/1, + get_tile_ids/1, + get_tile_id/2 + ] +). + +-export +( + [ + random/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate_random_tile_ids + ( + bm_tile:id(), + list(bm_tile:id()), + non_neg_integer(), + non_neg_integer(), + non_neg_integer() + ) + -> list(bm_tile:id()). +generate_random_tile_ids (_PreviousTileID, Result, _X, 0, _Width) -> + Result; +generate_random_tile_ids (PreviousTileID, Result, 0, Y, Width) -> + generate_random_tile_ids(PreviousTileID, Result, Width, (Y - 1), Width); +generate_random_tile_ids (PreviousTileID, Result, X, Y, Width) -> + NewTile = + case sh_roll:percentage() of + N when (N >= 10) -> PreviousTileID; + _ -> bm_tile:random_id() + end, + generate_random_tile_ids(NewTile, [NewTile|Result], (X - 1), Y, Width). + +-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_ids (type()) -> array:array(bm_tile:id()). +get_tile_ids (Battlemap) -> Battlemap#battlemap.tile_ids. + +-spec get_tile_id (bm_location:type(), type()) -> bm_tile:id(). +get_tile_id (Location, Battlemap) -> + TileIX = location_to_array_index(Battlemap#battlemap.width, Location), + array:get(TileIX, Battlemap#battlemap.tile_ids). + +-spec random + ( + non_neg_integer(), + non_neg_integer(), + non_neg_integer() + ) + -> type(). +random (ID, Width, Height) -> + InitialTile = bm_tile:random_id(), + TileIDs = generate_random_tile_ids(InitialTile, [], Width, Height, Width), + + #battlemap + { + id = list_to_binary(integer_to_list(ID)), + width = Width, + height = Height, + tile_ids = array:from_list(TileIDs) + }. diff --git a/src/battlemap/struct/bm_character.erl b/src/battlemap/struct/bm_character.erl new file mode 100644 index 0000000..e797b74 --- /dev/null +++ b/src/battlemap/struct/bm_character.erl @@ -0,0 +1,239 @@ +-module(bm_character). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: non_neg_integer(). + +-record +( + character, + { + id :: id(), + owner_id :: bm_player:id(), + name :: binary(), + icon :: binary(), + portrait :: binary(), + attributes :: sh_attributes:type(), + statistics :: bm_statistics:type(), + weapon_ids :: {bm_weapon:id(), bm_weapon:id()}, + location :: {non_neg_integer(), non_neg_integer()}, + current_health :: non_neg_integer(), + active :: boolean() + } +). + +-opaque type() :: #character{}. + +-export_type([type/0, id/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_owner_id/1, + get_name/1, + get_icon/1, + get_portrait/1, + get_attributes/1, + get_statistics/1, + get_weapon_ids/1, + get_location/1, + get_current_health/1, + get_is_alive/1, + get_is_active/1, + + set_weapon_ids/2, + set_statistics/2, + set_location/2, + set_current_health/2, + set_is_active/2, + + get_statistics_field/0, + get_weapons_field/0, + get_location_field/0, + get_current_health_field/0, + get_active_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 = roll:between(0, (BattlemapWidth - 1)), + Y = 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_owner_id (type()) -> bm_player:id(). +get_owner_id (Char) -> Char#character.owner_id. + +-spec get_name (type()) -> binary(). +get_name (Char) -> Char#character.name. + +-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_weapon_ids (type()) -> {bm_weapon:id(), bm_weapon:id()}. +get_weapon_ids (Char) -> Char#character.weapon_ids. + +-spec get_statistics (type()) -> bm_statistics:type(). +get_statistics (Char) -> Char#character.statistics. + +-spec get_location (type()) -> {non_neg_integer(), non_neg_integer()}. +get_location (Char) -> + true = get_is_alive(Char), + Char#character.location. + +-spec get_current_health (type()) -> non_neg_integer(). +get_current_health (Char) -> Char#character.current_health. + +-spec get_is_alive (type()) -> boolean(). +get_is_alive (Char) -> + (Char#character.current_health > 0). + +-spec get_is_active (type()) -> boolean(). +get_is_active (Char) -> + ( + Char#character.active + and + get_is_alive(Char) + ). + +-spec set_location + ( + {non_neg_integer(), non_neg_integer()}, + type() + ) + -> type(). +set_location (Location, Char) -> + Char#character + { + location = Location + }. + +-spec set_current_health (non_neg_integer(), type()) -> type(). +set_current_health (Health, Char) -> + Char#character + { + current_health = max(0, Health) + }. + +-spec set_is_active (boolean(), type()) -> type(). +set_is_active (Active, Char) -> + Char#character + { + active = Active + }. + +-spec set_weapon_ids + ( + {bm_weapon:id(), bm_weapon:id()}, + type() + ) + -> type(). +set_weapon_ids (WeaponIDs, Char) -> + Char#character + { + weapon_ids = WeaponIDs + }. + +-spec set_statistics + ( + bm_statistics:type(), + type() + ) + -> type(). +set_statistics (Stats, Char) -> + Char#character + { + statistics = Stats + }. + +%%%% Utils +-spec random + ( + non_neg_integer(), + bm_player:id(), + non_neg_integer(), + non_neg_integer(), + list({non_neg_integer(), non_neg_integer()}) + ) + -> type(). +random (ID, OwnerID, BattlemapWidth, BattlemapHeight, ForbiddenLocations) -> + Location = + find_random_location(BattlemapWidth, BattlemapHeight, ForbiddenLocations), + WeaponIDs = {bm_weapon:random_id(), bm_weapon:random_id()}, + Attributes = sh_attributes:random(), + Statistics = bm_statistics:new(Attributes, WeaponIDs), + IDAsListString = integer_to_list(ID), + IDAsBinaryString = list_to_binary(IDAsListString), + + #character + { + id = ID, + owner_id = OwnerID, + name = list_to_binary("Char" ++ IDAsListString), + icon = IDAsBinaryString, + portrait = IDAsBinaryString, + attributes = Attributes, + weapon_ids = WeaponIDs, + statistics = Statistics, + location = Location, + current_health = bm_statistics:get_health(Statistics), + active = false + }. + +-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_active_field() -> non_neg_integer(). +get_active_field () -> #character.active. diff --git a/src/battlemap/struct/bm_character_turn_data.erl b/src/battlemap/struct/bm_character_turn_data.erl new file mode 100644 index 0000000..aaf7426 --- /dev/null +++ b/src/battlemap/struct/bm_character_turn_data.erl @@ -0,0 +1,102 @@ +-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 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 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 + ) + }. + diff --git a/src/battlemap/struct/bm_character_turn_request.erl b/src/battlemap/struct/bm_character_turn_request.erl new file mode 100644 index 0000000..d141d7e --- /dev/null +++ b/src/battlemap/struct/bm_character_turn_request.erl @@ -0,0 +1,84 @@ +-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 = binary_to_integer(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()) -> 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 new file mode 100644 index 0000000..078075c --- /dev/null +++ b/src/battlemap/struct/bm_character_turn_update.erl @@ -0,0 +1,73 @@ +-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/2, + 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(), type()) -> type(). +add_to_timeline (Item, Update) -> + 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 new file mode 100644 index 0000000..2da3936 --- /dev/null +++ b/src/battlemap/struct/bm_direction.erl @@ -0,0 +1,38 @@ +-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 new file mode 100644 index 0000000..056d10c --- /dev/null +++ b/src/battlemap/struct/bm_location.erl @@ -0,0 +1,90 @@ +-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 new file mode 100644 index 0000000..3f14a6f --- /dev/null +++ b/src/battlemap/struct/bm_player.erl @@ -0,0 +1,72 @@ +-module(bm_player). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type id() :: binary(). + +-record +( + player, + { + id :: id(), + timeline :: list(any()) + } +). + +-opaque type() :: #player{}. + +-export_type([type/0, id/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + get_id/1, + get_timeline/1, + add_to_timeline/2, + reset_timeline/1 + ] +). + +-export +( + [ + new/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_id (type()) -> id(). +get_id (Player) -> Player#player.id. + +-spec get_timeline (type()) -> list(any()). +get_timeline (Player) -> Player#player.timeline. + +-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 (id()) -> type(). +new (ID) -> + #player + { + id = ID, + timeline = [] + }. + diff --git a/src/battlemap/struct/bm_player_turn.erl b/src/battlemap/struct/bm_player_turn.erl new file mode 100644 index 0000000..5f2c074 --- /dev/null +++ b/src/battlemap/struct/bm_player_turn.erl @@ -0,0 +1,73 @@ +-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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 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 (non_neg_integer(), type()) -> type(). +next (PlayersCount, CurrentPlayerTurn) -> + CurrentPlayerIX = CurrentPlayerTurn#player_turn.player_ix, + CurrentTurnNumber = CurrentPlayerTurn#player_turn.number, + + NextPlayerIX = ((CurrentPlayerIX + 1) rem PlayersCount), + NextTurnNumber = + case NextPlayerIX of + 0 -> (CurrentTurnNumber + 1); + _ -> CurrentTurnNumber + end, + + new(NextTurnNumber, NextPlayerIX). diff --git a/src/battlemap/struct/bm_tile.erl b/src/battlemap/struct/bm_tile.erl new file mode 100644 index 0000000..c1dd448 --- /dev/null +++ b/src/battlemap/struct/bm_tile.erl @@ -0,0 +1,47 @@ +-module(bm_tile). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-opaque id() :: non_neg_integer(). +-opaque type() :: id(). + +-export_type([type/0, id/0]). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + get_cost/1, + cost_when_oob/0 + ] +). + +-export +( + [ + random_id/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec cost_when_oob () -> non_neg_integer(). +cost_when_oob () -> 255. + +-spec get_cost (id()) -> non_neg_integer(). +get_cost (N) -> + if + (N =< 200) -> (N + 8); + true -> cost_when_oob() + end. + +-spec random_id () -> id(). +random_id () -> + sh_roll:between(0, 15). diff --git a/src/battlemap/struct/bm_turn_result.erl b/src/battlemap/struct/bm_turn_result.erl new file mode 100644 index 0000000..c3440bd --- /dev/null +++ b/src/battlemap/struct/bm_turn_result.erl @@ -0,0 +1,142 @@ +-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()) + } +). + +-opaque type() :: (#switched_weapon{} | #moved{} | #attacked{}). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0]). + +-export +( + [ + new_character_switched_weapons/1, + new_character_moved/3, + new_character_attacked/3 + ] +). + +-export +( + [ + encode/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-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 (Other) -> + io:format("~n invalid encode param\"~p\"~n", [Other]), + true = Other. diff --git a/src/battlemap/struct/bm_weapon.erl b/src/battlemap/struct/bm_weapon.erl new file mode 100644 index 0000000..6c05799 --- /dev/null +++ b/src/battlemap/struct/bm_weapon.erl @@ -0,0 +1,360 @@ +-module(bm_weapon). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-opaque id() :: non_neg_integer(). + +-type range_type() :: 'ranged' | 'melee'. +-type range_mod() :: 'long' | 'short'. +-type damage_type() :: 'slash' | 'pierce' | 'blunt'. +-type damage_mod() :: 'heavy' | 'light'. + +-record +( + weapon, + { + id :: id(), + name :: binary(), + range_type :: range_type(), + range_mod :: range_mod(), + damage_type :: damage_type(), + damage_mod :: damage_mod() + } +). + +-opaque type() :: #weapon{}. + +-export_type([type/0, id/0]). +-export_type +( + [ + range_type/0, + range_mod/0, + damage_type/0, + damage_mod/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_range_type/1, + get_ranges/1, + get_damages/1 + ] +). + +-export +( + [ + random_id/0, + from_id/1, + can_parry/1, + apply_to_attributes/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec ranges_of_type + ( + range_type(), + range_mod() + ) + -> {non_neg_integer(), non_neg_integer()}. +ranges_of_type (ranged, long) -> {2, 6}; +ranges_of_type (ranged, short) -> {1, 4}; +ranges_of_type (melee, long) -> {0, 2}; +ranges_of_type (melee, short) -> {0, 1}. + +-spec damages_of_type + ( + range_type(), + damage_mod() + ) + -> {non_neg_integer(), non_neg_integer()}. +damages_of_type (ranged, heavy) -> {10, 25}; +damages_of_type (ranged, light) -> {5, 20}; +damages_of_type (melee, heavy) -> {20, 35}; +damages_of_type (melee, light) -> {15, 30}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Wp) -> Wp#weapon.id. + +-spec get_range_type (type()) -> range_type(). +get_range_type (Wp) -> Wp#weapon.range_type. + +-spec get_ranges (type()) -> {non_neg_integer(), non_neg_integer()}. +get_ranges (Wp) -> + ranges_of_type(Wp#weapon.range_type, Wp#weapon.range_mod). + +-spec get_damages (type()) -> {non_neg_integer(), non_neg_integer()}. +get_damages (Wp) -> + damages_of_type(Wp#weapon.range_type, Wp#weapon.damage_mod). + +-spec can_parry (type()) -> boolean(). +can_parry (Wp) -> (Wp#weapon.range_type == melee). + +-spec from_id (id()) -> type(). +from_id (0) -> + #weapon{ + id = 0, + name = <<"None">>, + range_type = melee, + range_mod = short, + damage_type = blunt, + damage_mod = light + }; +from_id (1) -> + #weapon{ + id = 1, + name = <<"Dagger">>, + range_type = melee, + range_mod = short, + damage_type = slash, + damage_mod = light + }; +from_id (2) -> + #weapon{ + id = 2, + name = <<"Sword">>, + range_type = melee, + range_mod = short, + damage_type = slash, + damage_mod = heavy + }; +from_id (3) -> + #weapon{ + id = 3, + name = <<"Claymore">>, + range_type = melee, + range_mod = long, + damage_type = slash, + damage_mod = light + }; +from_id (4) -> + #weapon{ + id = 4, + name = <<"Bardiche">>, + range_type = melee, + range_mod = long, + damage_type = slash, + damage_mod = heavy + }; +from_id (5) -> + #weapon{ + id = 5, + name = <<"Stiletto">>, + range_type = melee, + range_mod = short, + damage_type = pierce, + damage_mod = light + }; +from_id (6) -> + #weapon{ + id = 6, + name = <<"Pickaxe">>, + range_type = melee, + range_mod = short, + damage_type = pierce, + damage_mod = heavy + }; +from_id (7) -> + #weapon{ + id = 7, + name = <<"Rapier">>, + range_type = melee, + range_mod = long, + damage_type = pierce, + damage_mod = light + }; +from_id (8) -> + #weapon{ + id = 8, + name = <<"Pike">>, + range_type = melee, + range_mod = long, + damage_type = pierce, + damage_mod = heavy + }; +from_id (9) -> + #weapon{ + id = 9, + name = <<"Club">>, + range_type = melee, + range_mod = short, + damage_type = blunt, + damage_mod = light + }; +from_id (10) -> + #weapon{ + id = 10, + name = <<"Mace">>, + range_type = melee, + range_mod = short, + damage_type = blunt, + damage_mod = heavy + }; +from_id (11) -> + #weapon{ + id = 11, + name = <<"Staff">>, + range_type = melee, + range_mod = long, + damage_type = blunt, + damage_mod = light + }; +from_id (12) -> + #weapon{ + id = 12, + name = <<"War Hammer">>, + range_type = melee, + range_mod = long, + damage_type = blunt, + damage_mod = heavy + }; +from_id (13) -> + #weapon{ + id = 13, + name = <<"Short Bow (Broadhead)">>, + range_type = ranged, + range_mod = short, + damage_type = slash, + damage_mod = light + }; +from_id (14) -> + #weapon{ + id = 14, + name = <<"Short Bow (Blunt)">>, + range_type = ranged, + range_mod = short, + damage_type = blunt, + damage_mod = light + }; +from_id (15) -> + #weapon{ + id = 15, + name = <<"Short Bow (Bodkin Point)">>, + range_type = ranged, + range_mod = short, + damage_type = pierce, + damage_mod = light + }; +from_id (16) -> + #weapon{ + id = 16, + name = <<"Long Bow (Broadhead)">>, + range_type = ranged, + range_mod = long, + damage_type = slash, + damage_mod = light + }; +from_id (17) -> + #weapon{ + id = 17, + name = <<"Long Bow (Blunt)">>, + range_type = ranged, + range_mod = long, + damage_type = blunt, + damage_mod = light + }; +from_id (18) -> + #weapon{ + id = 18, + name = <<"Long Bow (Bodkin Point)">>, + range_type = ranged, + range_mod = long, + damage_type = pierce, + damage_mod = light + }; +from_id (19) -> + #weapon{ + id = 19, + name = <<"Crossbow (Broadhead)">>, + range_type = ranged, + range_mod = short, + damage_type = slash, + damage_mod = heavy + }; +from_id (20) -> + #weapon{ + id = 20, + name = <<"Crossbow (Blunt)">>, + range_type = ranged, + range_mod = short, + damage_type = blunt, + damage_mod = heavy + }; +from_id (21) -> + #weapon{ + id = 21, + name = <<"Crossbow (Bodkin Point)">>, + range_type = ranged, + range_mod = short, + damage_type = pierce, + damage_mod = heavy + }; +from_id (22) -> + #weapon{ + id = 22, + name = <<"Arbalest (Broadhead)">>, + range_type = ranged, + range_mod = long, + damage_type = slash, + damage_mod = heavy + }; +from_id (23) -> + #weapon{ + id = 23, + name = <<"Arbalest (Blunt)">>, + range_type = ranged, + range_mod = long, + damage_type = blunt, + damage_mod = heavy + }; +from_id (24) -> + #weapon{ + id = 24, + name = <<"Arbalest (Bodkin Point)">>, + range_type = ranged, + range_mod = long, + damage_type = pierce, + damage_mod = heavy + }. + +-spec random_id () -> id(). +random_id () -> sh_roll:between(0, 24). + +-spec apply_to_attributes + ( + sh_attributes:type(), + bm_weapon:type() + ) + -> attributes:type(). +apply_to_attributes (Attributes, Weapon) -> + Dexterity = sh_attributes:get_dexterity(Attributes), + Speed = sh_attributes:get_speed(Attributes), + RangeModifier = Weapon#weapon.range_mod, + DamageModifier = Weapon#weapon.damage_mod, + WithRangeModifier = + case RangeModifier of + long -> + sh_attributes:set_dexterity(max(0, (Dexterity - 20)), Attributes); + _ -> Attributes + end, + case DamageModifier of + heavy -> sh_attributes:set_speed(max(0, (Speed - 20)), WithRangeModifier); + _ -> WithRangeModifier + end. + diff --git a/src/battlemap/util/array_util.erl b/src/battlemap/util/array_util.erl new file mode 100644 index 0000000..418d9ce --- /dev/null +++ b/src/battlemap/util/array_util.erl @@ -0,0 +1,105 @@ +-module(array_util). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + any/2, + none/2, + all/2, + + mapiff/3 + ] +). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec any_internals + ( + fun((any()) -> boolean()), + array:array(any()), + non_neg_integer() + ) + -> boolean(). +any_internals (_, _, 0) -> + false; +any_internals (Fun, Array, PrevIX) -> + IX = (PrevIX - 1), + case Fun(array:get(IX, Array)) of + true -> true; + _ -> any_internals(Fun, Array, IX) + end. + +-spec all_internals + ( + fun((any()) -> boolean()), + array:array(any()), + non_neg_integer() + ) + -> boolean(). +all_internals (_, _, 0) -> + true; +all_internals (Fun, Array, PrevIX) -> + IX = (PrevIX - 1), + case Fun(array:get(IX, Array)) of + true -> any_internals(Fun, Array, IX); + _ -> false + end. + +-spec mapiff_internals + ( + fun((any()) -> boolean()), + fun((any()) -> any()), + array:array(any()), + list(non_neg_integer()), + non_neg_integer() + ) + -> {array:array(any()), list(non_neg_integer())}. +mapiff_internals (_, _, Array, IXList, 0) -> + {Array, IXList}; +mapiff_internals (Cond, Map, Array, IXList, PrevIX) -> + IX = (PrevIX - 1), + Elem = array:get(IX, Array), + + case Cond(Elem) of + false -> mapiff_internals(Cond, Map, Array, IXList, IX); + _ -> + mapiff_internals + ( + Cond, + Map, + array:set(IX, Map(Elem), Array), + [IX|IXList], + IX + ) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec any (fun((any()) -> boolean()), array:array(any())) -> boolean(). +any (Fun, Array) -> + any_internals(Fun, Array, array:size(Array)). + +-spec all (fun((any()) -> boolean()), array:array(any())) -> boolean(). +all (Fun, Array) -> + all_internals(Fun, Array, array:size(Array)). + +-spec none (fun((any()) -> boolean()), array:array(any())) -> boolean(). +none (Fun, Array) -> + not any(Fun, Array). + +-spec mapiff + ( + fun((any()) -> boolean()), + fun((any()) -> any()), + array:array(any()) + ) + -> {array:array(any()), list(non_neg_integer())}. +mapiff (Cond, Map, Array) -> + mapiff_internals(Cond, Map, Array, [], array:size(Array)). diff --git a/src/db/Makefile b/src/db/Makefile deleted file mode 100644 index 206a332..0000000 --- a/src/db/Makefile +++ /dev/null @@ -1,71 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -MODULE_NAME ?= $ $(shell basename ${CURDIR}) -MODULE_PORT ?= 8002 - -DIALYZER_PLT_FILE ?= tacticians-server.plt - -## Main Directories -SRC_DIR ?= ${CURDIR}/src -CONF_DIR ?= ${CURDIR}/conf - -#### Optional Dirs -BIN_DIR ?= ${CURDIR}/ebin -INCLUDE_DIR ?= ${CURDIR}/include - -## Binaries -ERLC ?= erlc -ERLC_OPTS ?= -ERL ?= erl -ERL_OPTS ?= \ - -connect_all false \ - -name db_node \ - -pa $(BIN_DIR) \ - -run db_node start - -DIALYZER ?= dialyzer - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -OPTIONAL_DIRS = $(BIN_DIR) $(INCLUDE_DIR) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ -DIALYZER_PLT_FILE ?= tacticians-server.plt - -## Main Directories -SRC_DIR ?= src -CONF_DIR ?= conf - -################################################################################ -## INCLUDES #################################################################### -################################################################################ -main_target: all - -include ${CURDIR}/mk/debug.mk -include ${CURDIR}/mk/erlang.mk -include ${CURDIR}/mk/preprocessor.mk - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -all: build - -debug: debug_run - -build: $(REQUIRED_HEADERS) $(PREPROCESSOR_RESULT) $(ERLANG_RESULT) - -run: - $(ERL) $(ERL_OPTS) - -clean: - rm -rf $(PREPROCESSOR_RESULT) $(ERLANG_RESULT) - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -$(OPTIONAL_DIRS): %: - mkdir -p $@ diff --git a/src/db/db_node.erl b/src/db/db_node.erl new file mode 100644 index 0000000..be295c6 --- /dev/null +++ b/src/db/db_node.erl @@ -0,0 +1,31 @@ +-module(db_node). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export([start/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec wait_for_stop () -> 'ok'. +wait_for_stop () -> + receive + stop -> ok; + {ping, Pid} -> Pid ! pong; + _ -> wait_for_stop() + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec start () -> 'ok'. +start () -> + DB = db_model:new(battle_db, "/tmp/battle_db.mnesia", []), + db_model:start(DB), + wait_for_stop(), + ok. diff --git a/src/db/include/db_item.hrl b/src/db/include/db_item.hrl deleted file mode 100644 index 86d5863..0000000 --- a/src/db/include/db_item.hrl +++ /dev/null @@ -1,15 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - db_item, - { - id :: any(), - perm :: db_user:permission(), - val :: any() - } -). - --type db_item() :: #db_item{}. - diff --git a/src/db/include/db_query.hrl b/src/db/include/db_query.hrl deleted file mode 100644 index 7e5a5b0..0000000 --- a/src/db/include/db_query.hrl +++ /dev/null @@ -1,63 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - set_field, - { - field :: non_neg_integer(), - value :: any() - } -). - --record -( - add_to_field, - { - field :: non_neg_integer(), - values :: list(any()), - head :: boolean() - } -). - --record -( - update_indexed, - { - field :: non_neg_integer(), - ix :: non_neg_integer(), - ops :: list(db_query_op()) - } -). - --record -( - set_perm, - { - perm :: db_user:permission() - } -). - --record -( - set_val, - { - val :: any() - } -). - --record -( - db_query, - { - db :: atom(), - id :: any(), - user :: db_user:user(), - ops :: list(db_query_master_op()) - } -). - --type db_query_op() :: (#set_field{} | #add_to_field{} | #update_indexed{}). --type db_query_master_op() :: (db_query_op() | #set_perm{} | #set_val{}). --type db_query() :: #db_query{}. - diff --git a/src/db/include/db_user.hrl b/src/db/include/db_user.hrl deleted file mode 100644 index c5b033e..0000000 --- a/src/db/include/db_user.hrl +++ /dev/null @@ -1,7 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type db_named_user() :: {'user', any()}. --type db_user() :: (db_named_user() | 'admin' | 'any'). --type db_permission() :: (list(db_named_user()) | 'any'). - diff --git a/src/db/logic/storage_access.erl b/src/db/logic/storage_access.erl new file mode 100644 index 0000000..437294f --- /dev/null +++ b/src/db/logic/storage_access.erl @@ -0,0 +1,54 @@ +-module(storage_access). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + read/2, + insert/4, + query/1 + ] +). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +get_value ([]) -> not_found; +get_value ([Regval]) -> {ok, db_item:get_value(Regval)}. + +read_transaction (DB, ID) -> + get_value(mnesia:read(DB, ID)). + +insert_transaction (DB, ID, Perm, Value) -> + StoredItem = db_item:new(ID, Perm, Value), + % FIXME: handle return value, mnesia:write -> (transaction abort | ok). + % FIXME: is this an atomic OP? Is the lock freed afterwards? + mnesia:write(DB, StoredItem, sticky_write), + ok. + +query_transaction (Query) -> + DB = db_query:get_database(Query), + ID = db_query:get_entry_id(Query), + [Item] = mnesia:read(DB, ID), + {ok, UpdatedItem} = db_query:apply_to(Query, Item), + % FIXME: handle return value, mnesia:write -> (transaction abort | ok). + % FIXME: is this an atomic OP? Is the lock freed afterwards? + mnesia:write(DB, UpdatedItem, sticky_write), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +read (DB, ID) -> + mnesia:transaction(fun read_transaction/2, [DB, ID]). + +insert (DB, ID, Perm, Value) -> + mnesia:transaction(fun insert_transaction/4, [DB, ID, Perm, Value]). + +query (Query) -> + mnesia:transaction(fun query_transaction/1, [Query]). diff --git a/src/db/mk/debug.mk b/src/db/mk/debug.mk deleted file mode 100644 index bd93669..0000000 --- a/src/db/mk/debug.mk +++ /dev/null @@ -1,40 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -DIALYZER_PLT_FILE ?= tacticians-server.plt -DIALYZER ?= dialyzer - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -SRC_FILES ?= $(wildcard $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -DEBUG_RESULT = $(DIALYZER_PLT_FILE) - -debug_rebuild: - $(MAKE) clean - $(MAKE) ERLC_OPTS=+debug_info - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -ifeq ($(wildcard $(DIALYZER_PLT_FILE)),) -debug_run: - $(DIALYZER) --build_plt --apps erts kernel stdlib --output_plt \ - $(DIALYZER_PLT_FILE) - $(MAKE) debug_rebuild - $(DIALYZER) --add_to_plt --plt $(DIALYZER_PLT_FILE) -r $(BIN_DIR) -else -debug_run: - $(MAKE) debug_rebuild - $(DIALYZER) --check_plt --plt $(DIALYZER_PLT_FILE) - $(DIALYZER) --get_warnings $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl \ - --src --plt $(DIALYZER_PLT_FILE) -endif diff --git a/src/db/mk/erlang.mk b/src/db/mk/erlang.mk deleted file mode 100644 index 9150f63..0000000 --- a/src/db/mk/erlang.mk +++ /dev/null @@ -1,28 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -ERLC ?= erlc -ERLC_OPTS ?= - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -SRC_FILES ?= $(wildcard $(SRC_DIR)/*.erl $(SRC_DIR)/*/*.erl) -BIN_FILES = \ - $(patsubst %.erl,$(BIN_DIR)/%.beam,$(notdir $(SRC_FILES))) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -ERLANG_RESULT = $(BIN_DIR) $(BIN_FILES) - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -.SECONDEXPANSION: -$(BIN_FILES): $(BIN_DIR)/%.beam : $$(wildcard $(SRC_DIR)/*/%.erl $(SRC_DIR)/%.erl) - $(ERLC) $(ERLC_OPTS) -o $(BIN_DIR) $< diff --git a/src/db/mk/preprocessor.mk b/src/db/mk/preprocessor.mk deleted file mode 100644 index 74f66ba..0000000 --- a/src/db/mk/preprocessor.mk +++ /dev/null @@ -1,34 +0,0 @@ -################################################################################ -## CONFIG ###################################################################### -################################################################################ -CONFIG_FILE ?= ${CURDIR}/module.conf - -################################################################################ -## MAKEFILE MAGIC ############################################################## -################################################################################ -PREPROCESSOR_FILES = $(shell find ${CURDIR} -name "*.m4") -PREPROCESSED_FILES = $(patsubst %.m4,%,$(PREPROCESSOR_FILES)) - -MAKEFILE_TO_M4 = \ - --define=__MAKEFILE_MODULE_NAME=$(MODULE_NAME) \ - --define=__MAKEFILE_MODULE_PORT=$(MODULE_PORT) \ - --define=__MAKEFILE_BIN_DIR=$(BIN_DIR) \ - --define=__MAKEFILE_INCLUDE_DIR=$(INCLUDE_DIR) - -################################################################################ -## SANITY CHECKS ############################################################### -################################################################################ -ifeq ($(wildcard $(CONFIG_FILE)),) -$(error "Missing CONFIG_FILE ($(CONFIG_FILE)).") -endif - -################################################################################ -## TARGET RULES ################################################################ -################################################################################ -PREPROCESSOR_RESULT = $(PREPROCESSED_FILES) - -################################################################################ -## INTERNAL RULES ############################################################## -################################################################################ -$(PREPROCESSED_FILES): %: $(CONFIG_FILE) %.m4 - m4 -P $^ > $@ diff --git a/src/db/module.conf b/src/db/module.conf deleted file mode 100644 index 08714a1..0000000 --- a/src/db/module.conf +++ /dev/null @@ -1,6 +0,0 @@ -m4_define(`__MODULE_NAME', `__MAKEFILE_MODULE_NAME')m4_dnl -m4_define(`__MODULE_PORT', `__MAKEFILE_MODULE_PORT')m4_dnl -m4_dnl -m4_define(`__MODULE_BIN_DIR', `__MAKEFILE_BIN_DIR')m4_dnl -m4_define(`__MODULE_INCLUDE_DIR', `__MAKEFILE_INCLUDE_DIR')m4_dnl -m4_dnl diff --git a/src/db/src/db_node.erl b/src/db/src/db_node.erl deleted file mode 100644 index be295c6..0000000 --- a/src/db/src/db_node.erl +++ /dev/null @@ -1,31 +0,0 @@ --module(db_node). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export([start/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec wait_for_stop () -> 'ok'. -wait_for_stop () -> - receive - stop -> ok; - {ping, Pid} -> Pid ! pong; - _ -> wait_for_stop() - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec start () -> 'ok'. -start () -> - DB = db_model:new(battle_db, "/tmp/battle_db.mnesia", []), - db_model:start(DB), - wait_for_stop(), - ok. diff --git a/src/db/src/logic/storage_access.erl b/src/db/src/logic/storage_access.erl deleted file mode 100644 index 437294f..0000000 --- a/src/db/src/logic/storage_access.erl +++ /dev/null @@ -1,54 +0,0 @@ --module(storage_access). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - read/2, - insert/4, - query/1 - ] -). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -get_value ([]) -> not_found; -get_value ([Regval]) -> {ok, db_item:get_value(Regval)}. - -read_transaction (DB, ID) -> - get_value(mnesia:read(DB, ID)). - -insert_transaction (DB, ID, Perm, Value) -> - StoredItem = db_item:new(ID, Perm, Value), - % FIXME: handle return value, mnesia:write -> (transaction abort | ok). - % FIXME: is this an atomic OP? Is the lock freed afterwards? - mnesia:write(DB, StoredItem, sticky_write), - ok. - -query_transaction (Query) -> - DB = db_query:get_database(Query), - ID = db_query:get_entry_id(Query), - [Item] = mnesia:read(DB, ID), - {ok, UpdatedItem} = db_query:apply_to(Query, Item), - % FIXME: handle return value, mnesia:write -> (transaction abort | ok). - % FIXME: is this an atomic OP? Is the lock freed afterwards? - mnesia:write(DB, UpdatedItem, sticky_write), - ok. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -read (DB, ID) -> - mnesia:transaction(fun read_transaction/2, [DB, ID]). - -insert (DB, ID, Perm, Value) -> - mnesia:transaction(fun insert_transaction/4, [DB, ID, Perm, Value]). - -query (Query) -> - mnesia:transaction(fun query_transaction/1, [Query]). diff --git a/src/db/src/struct/db_item.erl b/src/db/src/struct/db_item.erl deleted file mode 100644 index 0ce7630..0000000 --- a/src/db/src/struct/db_item.erl +++ /dev/null @@ -1,70 +0,0 @@ --module(db_item). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../include/db_item.hrl"). - --type type() :: db_item(). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([type/0]). - --export -( - [ - new/3, - - get_id/1, - get_permission/1, - get_value/1, - - set_permission/2, - set_value/2, - - get_id_field/0, - get_record_info/0, - get_record_name/0 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (any(), db_user:permission(), any()) -> type(). -new (ID, Permission, Value) -> - #db_item - { - id = ID, - perm = Permission, - val = Value - }. - --spec get_id (type()) -> any(). -get_id (#db_item { id = Result }) -> Result. - --spec get_permission (type()) -> db_user:permission(). -get_permission (#db_item { perm = Result }) -> Result. - --spec get_value (type()) -> any(). -get_value (#db_item { val = Result }) -> Result. - --spec set_permission (db_user:permission(), type()) -> type(). -set_permission (Perm, Item) -> Item#db_item{ perm = Perm }. - --spec set_value (any(), type()) -> type(). -set_value (Value, Item) -> Item#db_item{ val = Value }. - --spec get_id_field () -> non_neg_integer(). -get_id_field () -> #db_item.id. - -get_record_info () -> record_info(fields, db_item). - -get_record_name () -> db_item. - diff --git a/src/db/src/struct/db_model.erl b/src/db/src/struct/db_model.erl deleted file mode 100644 index 1b21629..0000000 --- a/src/db/src/struct/db_model.erl +++ /dev/null @@ -1,71 +0,0 @@ --module(db_model). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - --record -( - db_model, - { - name :: atom(), - store_file :: string(), - neighbors :: list(node()) - } -). - --type type() :: #db_model{}. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([type/0]). - --export -( - [ - new/3, - start/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec new (atom(), string(), list(node())) -> type(). -new (DBName, StorageFile, Neighbors) -> - #db_model - { - name = DBName, - store_file = StorageFile, - neighbors = Neighbors - }. - -start (Model) -> - DBName = Model#db_model.name, - StorageFile = Model#db_model.store_file, - Neighbors = Model#db_model.neighbors, - - ok = application:set_env(mnesia, dir, StorageFile), - case mnesia:create_schema([node()|Neighbors]) of - {error, {Name, {already_exists, Name}}} -> ok; - ok -> ok - end, - ok = mnesia:start(), - mnesia:create_table - ( - DBName, - [ - {record_name, db_item:get_record_name()}, - {attributes, db_item:get_record_info()}, - {disc_copies, [node()|Neighbors]}, - {disc_only_copies, []}, - {ram_copies, []}, - {type, ordered_set}, - {local_content, false} - ] - ). diff --git a/src/db/src/struct/db_query.erl b/src/db/src/struct/db_query.erl deleted file mode 100644 index f8ad310..0000000 --- a/src/db/src/struct/db_query.erl +++ /dev/null @@ -1,109 +0,0 @@ --module(db_query). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../include/db_query.hrl"). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - get_database/1, - get_entry_id/1 - ] -). --export([apply_to/2]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_user (db_query()) -> db_user:user(). -get_user (#db_query{ user = Result }) -> Result. - --spec apply_update_indexed (#update_indexed{}, any()) -> any(). -apply_update_indexed (Op, Elem) -> - FieldNumber = Op#update_indexed.field, - IX = Op#update_indexed.ix, - Ops = Op#update_indexed.ops, - - IndexedFieldValue = element(FieldNumber, Elem), - ArrayValue = array:get(IX, IndexedFieldValue), - UpdatedArrayValue = lists:foldl(fun apply_op_to/2, ArrayValue, Ops), - UpdatedIndexedFieldValue = - array:set(IX, UpdatedArrayValue, IndexedFieldValue), - - setelement(FieldNumber, Elem, UpdatedIndexedFieldValue). - --spec apply_add_to_field (#add_to_field{}, any()) -> any(). -apply_add_to_field (Op, Elem) -> - FieldNumber = Op#add_to_field.field, - NewValues = Op#add_to_field.values, - AddToHead = Op#add_to_field.head, - - CurrentValues = element(FieldNumber, Elem), - UpdatedValues = - case AddToHead of - true -> (NewValues ++ CurrentValues); - _ -> (CurrentValues ++ NewValues) - end, - - setelement(FieldNumber, Elem, UpdatedValues). - --spec apply_set_field (#set_field{}, any()) -> any(). -apply_set_field (Op, Elem) -> - FieldNumber = Op#set_field.field, - NewValue = Op#set_field.value, - - setelement(FieldNumber, Elem, NewValue). - --spec apply_op_to (db_query_op(), any()) -> any(). -apply_op_to (Op, Elem) when is_record(Op, set_field) -> - apply_set_field(Op, Elem); -apply_op_to (Op, Elem) when is_record(Op, add_to_field) -> - apply_add_to_field(Op, Elem); -apply_op_to (Op, Elem) when is_record(Op, update_indexed) -> - apply_update_indexed(Op, Elem). - --spec apply_master_op_to - ( - db_query_master_op(), - db_item:type() - ) - -> db_item:type(). -apply_master_op_to (MOp, Elem) when is_record(MOp, set_perm) -> - NewPerm = MOp#set_perm.perm, - - db_item:set_perm(NewPerm, Elem); -apply_master_op_to (MOp, Elem) when is_record(MOp, set_val) -> - NewVal = MOp#set_val.val, - - db_item:set_value(NewVal, Elem); -apply_master_op_to (MOp, Elem) -> - OldValue = db_item:get_value(Elem), - NewValue = apply_op_to(MOp, OldValue), - - db_item:set_value(NewValue, Elem). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_database (db_query()) -> atom(). -get_database (#db_query{ db = Result }) -> Result. - --spec get_entry_id (db_query()) -> any(). -get_entry_id (#db_query{ id = Result }) -> Result. - --spec apply_to - ( - db_query(), - db_item:type() - ) - -> ({'ok', db_item:type()} | 'error'). -apply_to (DBQuery, DBItem) -> - true = db_user:can_access(db_item:get_permission(DBItem), get_user(DBQuery)), - MOps = DBQuery#db_query.ops, - {ok, lists:foldl(fun apply_master_op_to/2, DBItem, MOps)}. - diff --git a/src/db/src/struct/db_user.erl b/src/db/src/struct/db_user.erl deleted file mode 100644 index 983013c..0000000 --- a/src/db/src/struct/db_user.erl +++ /dev/null @@ -1,28 +0,0 @@ --module(db_user). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../../include/db_user.hrl"). - --type user() :: db_user(). --type permission() :: db_permission(). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([user/0, permission/0]). - --export([can_access/2]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec can_access (permission(), user()) -> boolean(). -can_access (_, admin) -> true; -can_access (any, _) -> true; -can_access (List, {'user', User}) -> - lists:member(User, List). diff --git a/src/db/struct/db_model.erl b/src/db/struct/db_model.erl new file mode 100644 index 0000000..1b21629 --- /dev/null +++ b/src/db/struct/db_model.erl @@ -0,0 +1,71 @@ +-module(db_model). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +-record +( + db_model, + { + name :: atom(), + store_file :: string(), + neighbors :: list(node()) + } +). + +-type type() :: #db_model{}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0]). + +-export +( + [ + new/3, + start/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (atom(), string(), list(node())) -> type(). +new (DBName, StorageFile, Neighbors) -> + #db_model + { + name = DBName, + store_file = StorageFile, + neighbors = Neighbors + }. + +start (Model) -> + DBName = Model#db_model.name, + StorageFile = Model#db_model.store_file, + Neighbors = Model#db_model.neighbors, + + ok = application:set_env(mnesia, dir, StorageFile), + case mnesia:create_schema([node()|Neighbors]) of + {error, {Name, {already_exists, Name}}} -> ok; + ok -> ok + end, + ok = mnesia:start(), + mnesia:create_table + ( + DBName, + [ + {record_name, db_item:get_record_name()}, + {attributes, db_item:get_record_info()}, + {disc_copies, [node()|Neighbors]}, + {disc_only_copies, []}, + {ram_copies, []}, + {type, ordered_set}, + {local_content, false} + ] + ). diff --git a/src/db/struct/db_query.erl b/src/db/struct/db_query.erl new file mode 100644 index 0000000..9a86f98 --- /dev/null +++ b/src/db/struct/db_query.erl @@ -0,0 +1,114 @@ +-module(db_query). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../../shared/include/db_query.hrl"). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + get_database/1, + get_entry_id/1 + ] +). +-export([apply_to/2]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_user (db_query()) -> sh_db_user:user(). +get_user (#db_query{ user = Result }) -> Result. + +-spec apply_update_indexed (#update_indexed{}, any()) -> any(). +apply_update_indexed (Op, Elem) -> + FieldNumber = Op#update_indexed.field, + IX = Op#update_indexed.ix, + Ops = Op#update_indexed.ops, + + IndexedFieldValue = element(FieldNumber, Elem), + ArrayValue = array:get(IX, IndexedFieldValue), + UpdatedArrayValue = lists:foldl(fun apply_op_to/2, ArrayValue, Ops), + UpdatedIndexedFieldValue = + array:set(IX, UpdatedArrayValue, IndexedFieldValue), + + setelement(FieldNumber, Elem, UpdatedIndexedFieldValue). + +-spec apply_add_to_field (#add_to_field{}, any()) -> any(). +apply_add_to_field (Op, Elem) -> + FieldNumber = Op#add_to_field.field, + NewValues = Op#add_to_field.values, + AddToHead = Op#add_to_field.head, + + CurrentValues = element(FieldNumber, Elem), + UpdatedValues = + case AddToHead of + true -> (NewValues ++ CurrentValues); + _ -> (CurrentValues ++ NewValues) + end, + + setelement(FieldNumber, Elem, UpdatedValues). + +-spec apply_set_field (#set_field{}, any()) -> any(). +apply_set_field (Op, Elem) -> + FieldNumber = Op#set_field.field, + NewValue = Op#set_field.value, + + setelement(FieldNumber, Elem, NewValue). + +-spec apply_op_to (db_query_op(), any()) -> any(). +apply_op_to (Op, Elem) when is_record(Op, set_field) -> + apply_set_field(Op, Elem); +apply_op_to (Op, Elem) when is_record(Op, add_to_field) -> + apply_add_to_field(Op, Elem); +apply_op_to (Op, Elem) when is_record(Op, update_indexed) -> + apply_update_indexed(Op, Elem). + +-spec apply_master_op_to + ( + db_query_master_op(), + db_item:type() + ) + -> db_item:type(). +apply_master_op_to (MOp, Elem) when is_record(MOp, set_perm) -> + NewPerm = MOp#set_perm.perm, + + db_item:set_perm(NewPerm, Elem); +apply_master_op_to (MOp, Elem) when is_record(MOp, set_val) -> + NewVal = MOp#set_val.val, + + db_item:set_value(NewVal, Elem); +apply_master_op_to (MOp, Elem) -> + OldValue = sh_db_item:get_value(Elem), + NewValue = apply_op_to(MOp, OldValue), + + db_item:set_value(NewValue, Elem). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_database (db_query()) -> atom(). +get_database (#db_query{ db = Result }) -> Result. + +-spec get_entry_id (db_query()) -> any(). +get_entry_id (#db_query{ id = Result }) -> Result. + +-spec apply_to + ( + db_query(), + db_item:type() + ) + -> ({'ok', db_item:type()} | 'error'). +apply_to (DBQuery, DBItem) -> + true = + sh_db_user:can_access + ( + sh_db_item:get_permission(DBItem), + get_user(DBQuery) + ), + MOps = DBQuery#db_query.ops, + {ok, lists:foldl(fun apply_master_op_to/2, DBItem, MOps)}. + diff --git a/src/shared/include/db_item.hrl b/src/shared/include/db_item.hrl new file mode 100644 index 0000000..86d5863 --- /dev/null +++ b/src/shared/include/db_item.hrl @@ -0,0 +1,15 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + db_item, + { + id :: any(), + perm :: db_user:permission(), + val :: any() + } +). + +-type db_item() :: #db_item{}. + diff --git a/src/shared/include/db_query.hrl b/src/shared/include/db_query.hrl new file mode 100644 index 0000000..7e5a5b0 --- /dev/null +++ b/src/shared/include/db_query.hrl @@ -0,0 +1,63 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + set_field, + { + field :: non_neg_integer(), + value :: any() + } +). + +-record +( + add_to_field, + { + field :: non_neg_integer(), + values :: list(any()), + head :: boolean() + } +). + +-record +( + update_indexed, + { + field :: non_neg_integer(), + ix :: non_neg_integer(), + ops :: list(db_query_op()) + } +). + +-record +( + set_perm, + { + perm :: db_user:permission() + } +). + +-record +( + set_val, + { + val :: any() + } +). + +-record +( + db_query, + { + db :: atom(), + id :: any(), + user :: db_user:user(), + ops :: list(db_query_master_op()) + } +). + +-type db_query_op() :: (#set_field{} | #add_to_field{} | #update_indexed{}). +-type db_query_master_op() :: (db_query_op() | #set_perm{} | #set_val{}). +-type db_query() :: #db_query{}. + diff --git a/src/shared/include/db_user.hrl b/src/shared/include/db_user.hrl new file mode 100644 index 0000000..c5b033e --- /dev/null +++ b/src/shared/include/db_user.hrl @@ -0,0 +1,7 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type db_named_user() :: {'user', any()}. +-type db_user() :: (db_named_user() | 'admin' | 'any'). +-type db_permission() :: (list(db_named_user()) | 'any'). + diff --git a/src/shared/io/sh_database.erl b/src/shared/io/sh_database.erl new file mode 100644 index 0000000..a65b784 --- /dev/null +++ b/src/shared/io/sh_database.erl @@ -0,0 +1,137 @@ +-module(sh_database). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + generate_db/0, + fetch/2, + commit/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +get_db_node () -> + list_to_atom("db_node@" ++ net_adm:localhost()). + +-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 +( + MaxPlayerID, + 0, + CharactersPerPlayer, + TotalCharacterCount, + Battlemap, + ForbiddenLocations, + Result +) -> + generate_random_characters + ( + (MaxPlayerID - 1), + CharactersPerPlayer, + CharactersPerPlayer, + TotalCharacterCount, + Battlemap, + ForbiddenLocations, + Result + ); +generate_random_characters +( + MaxPlayerID, + PlayerCharacterCount, + CharactersPerPlayer, + TotalCharacterCount, + Battlemap, + ForbiddenLocations, + Result +) -> + NewCharacter = + bm_character:random + ( + TotalCharacterCount, + list_to_binary(integer_to_list(MaxPlayerID)), + bm_battlemap:get_width(Battlemap), + bm_battlemap:get_height(Battlemap), + ForbiddenLocations + ), + Character = + case MaxPlayerID of + 0 -> bm_character:set_is_active(true, NewCharacter); + _ -> NewCharacter + end, + + generate_random_characters + ( + MaxPlayerID, + (PlayerCharacterCount - 1), + CharactersPerPlayer, + (TotalCharacterCount + 1), + Battlemap, + [bm_character:get_location(Character)|ForbiddenLocations], + [Character|Result] + ). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec generate_db () -> 'ok'. +generate_db () -> + BattlemapWidth = sh_roll:between(16, 64), + BattlemapHeight = sh_roll:between(16, 64), + Battlemap = bm_battlemap:random(0, BattlemapWidth, BattlemapHeight), + Characters = generate_random_characters(1, 8, 8, 0, Battlemap, [], []), + PlayersAsList = [bm_player:new(<<"0">>), bm_player:new(<<"1">>)], + Battle = bm_battle:new(<<"0">>, PlayersAsList, Battlemap, Characters), + + {atomic, ok} = + rpc:call + ( + get_db_node(), + storage_access, + insert, + [battle_db, <<"0">>, any, Battle] + ), + + ok. + +-spec fetch (atom(), any()) -> ({'ok', any()} | 'not_found'). +fetch (DB, ObjectID) -> + {atomic, Reply} = + rpc:call(get_db_node(), storage_access, read, [DB, ObjectID]), + io:format("~ndb_shim:fetch(~p) -> ~p.~n", [{DB, ObjectID}, Reply]), + Reply. + +-spec commit (db_query:type()) -> 'ok'. +commit (Query) -> + {atomic, ok} = rpc:call(get_db_node(), storage_access, query, [Query]), + io:format("~ndb_shim:commit(~p) -> ok.~n", [Query]), + ok. diff --git a/src/shared/io/sh_timed_cache.erl b/src/shared/io/sh_timed_cache.erl new file mode 100644 index 0000000..1839992 --- /dev/null +++ b/src/shared/io/sh_timed_cache.erl @@ -0,0 +1,130 @@ +-module(sh_timed_cache). +-behavior(gen_server). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% 'gen_server' Exports +-export +( + [ + init/1, + handle_cast/2, + handle_call/3, %% No reply will ever be given. + terminate/2, + code_change/3, + format_status/2, + handle_info/2 + ] +). + +%%%% Actual Interface +-export +( + [ + fetch/3, + update/4, + invalidate/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec add_to_cache (atom(), any(), any()) -> any(). +add_to_cache (DB, Owner, ObjectID) -> + {ok, TimerPID} = sh_gen_server:start(?MODULE, {DB, {Owner, ObjectID}}, []), + {ok, Data} = sh_database:fetch(DB, ObjectID), + ets:insert(DB, {{Owner, ObjectID}, TimerPID, Data}), + Data. + +-spec add_update_to_cache (atom(), any(), any(), any()) -> 'ok'. +add_update_to_cache (DB, Owner, ObjectID, Data) -> + {ok, TimerPID} = gen_server:start(?MODULE, {DB, {Owner, ObjectID}}, []), + ets:insert(DB, {{Owner, ObjectID}, TimerPID, Data}), + ok. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% 'gen_server' functions +init ({DB, ObjectID}) -> + io:format("~nCache entry added: ~p.~n", [{DB, ObjectID}]), + {ok, {DB, ObjectID}, sh_timed_caches_manager:get_timeout()}. + +handle_call (invalidate, _, State) -> + {stop, normal, State}; +handle_call (ping, _, State) -> + {noreply, State, sh_timed_caches_manager:get_timeout()}. + +handle_cast (invalidate, State) -> + {stop, normal, State}; +handle_cast (ping, State) -> + {noreply, State, sh_timed_caches_manager:get_timeout()}. + +terminate (_, {DB, ObjectID}) -> + io:format + ( + "~nCache entry timed out or was invalidated: ~p.~n", + [{DB, ObjectID}] + ), + ets:delete(DB, ObjectID). + +code_change (_, State, _) -> + {ok, State}. + +format_status (_, [_, State]) -> + [{data, [{"State", State}]}]. + +handle_info(timeout, State) -> + {stop, normal, State}; +handle_info(_, {DB, ObjectID}) -> + {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout()}. + +%%%% Interface Functions +-spec fetch (atom(), any(), any()) -> any(). +fetch (DB, Owner, ObjectID) -> + io:format("~nfetch from cache: ~p.~n", [{DB, {Owner, ObjectID}}]), + case ets:lookup(DB, {Owner, ObjectID}) of + [] -> add_to_cache(DB, Owner, ObjectID); + + [{_, TimerPID, Data}] -> + gen_server:cast(TimerPID, ping), + Data + end. + +-spec update (atom(), any(), any(), any()) -> 'ok'. +update (DB, Owner, ObjectID, Data) -> + io:format("~nUpdating cache: ~p.~n", [{DB, {Owner, ObjectID}}]), + case ets:lookup(DB, {Owner, ObjectID}) of + [] -> ok; + + [{_OwnerID, TimerPID, _Data}] -> + gen_server:stop(TimerPID) + end, + add_update_to_cache(DB, Owner, ObjectID, Data). + +-spec invalidate (atom(), any(), any()) -> 'ok'. +invalidate (DB, Owner, ObjectID) -> + case ets:lookup(DB, {Owner, ObjectID}) of + [] -> + io:format + ( + "~nInvalidation request on non-stored entry: ~p.~n", + [{DB, Owner, ObjectID}] + ), + ok; + + [{_, TimerPID, _}] -> + io:format + ( + "~nInvalidation request on stored entry: ~p.~n", + [{DB, Owner, ObjectID}] + ), + gen_server:stop(TimerPID), + ok + end. diff --git a/src/shared/io/sh_timed_caches_manager.erl b/src/shared/io/sh_timed_caches_manager.erl new file mode 100644 index 0000000..7921552 --- /dev/null +++ b/src/shared/io/sh_timed_caches_manager.erl @@ -0,0 +1,152 @@ +-module(sh_timed_caches_manager). +-behavior(gen_server). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% 'gen_server' Exports +-export( + [ + init/1, + handle_cast/2, + handle_call/3, + terminate/2, + code_change/3, + format_status/2, + handle_info/2 + ] +). + +%%%% Actual Interface +-export( + [ + start/0, + new_cache/3, + delete_cache/2, + get_timeout/0 + ] +) +. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +remove_cache (DB) -> + ets:delete(DB). + +add_cache (DB, none) -> + io:format("~nTimed Caches Manager added a new cache. ~n"), + ets:new( + DB, + [ + set, + public, + named_table, + {keypos, 1}, + {read_concurrency, true}, + {heir, none} + ] + ); +add_cache (DB, Heir) -> + io:format("~nTimed Caches Manager added a new cache. ~n"), + ets:new( + DB, + [ + set, + public, + named_table, + {keypos, 1}, + {read_concurrency, true}, + {heir, Heir, DB} + ] + ). + +inherit_cache (CacheList, DB, Heir) -> + case lists:member(DB, CacheList) of + true -> + ets:setopts(DB, {heir, Heir, DB}), + CacheList; + + false -> + [DB|CacheList] + end. + +remove_cache (CacheList, DB) -> + case lists:member(DB, CacheList) of + true -> + remove_cache(DB), + lists:delete(DB, CacheList); + false -> + CacheList + end. + +add_cache (CacheList, DB, Heir) -> + case lists:member(DB, CacheList) of + true when (Heir =:= none) -> + CacheList; + + true -> + ets:setopts(DB, {heir, Heir, DB}), + CacheList; + + false -> + add_cache(DB, Heir), + [DB|CacheList] + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% 'gen_server' functions +init (CacheList) -> + io:format("~nStarting Timed Caches Manager..."), + {ok, CacheList}. + +handle_call ({remove, CacheName}, _Caller, State) -> + {noreply, remove_cache(State, CacheName)}; +handle_call ({add, CacheName, Heir}, _Caller, State)-> + {noreply, add_cache(State, CacheName, Heir)}; +handle_call ({inherit, CacheName, Heir}, _Caller, State)-> + {noreply, inherit_cache(State, CacheName, Heir)}; +handle_call (terminate, _, State) -> + {stop, normal, State}. + +handle_cast ({remove, CacheName}, State) -> + {noreply, remove_cache(State, CacheName)}; +handle_cast ({add, CacheName, Heir}, State)-> + {noreply, add_cache(State, CacheName, Heir)}; +handle_cast ({inherit, CacheName, Heir}, State)-> + {noreply, inherit_cache(State, CacheName, Heir)}; +handle_cast (terminate, State) -> + {stop, normal, State}. + +terminate (_Reason, []) -> + ok; +terminate (Reason, [CacheName|OtherCaches]) -> + remove_cache(CacheName), + terminate(Reason, OtherCaches). + +code_change (_, State, _) -> + {ok, State}. + +format_status (_, [_, State]) -> + [{data, [{"State", State}]}]. + +handle_info(_, State) -> + {noreply, State}. + +%%%% Interface Functions +start () -> + gen_server:start(timed_caches_manager, [], []). + +new_cache (ManagerPid, DB, Heir) -> + gen_server:cast(ManagerPid, {add, DB, Heir}). + +delete_cache (ManagerPid, DB) -> + gen_server:cast(ManagerPid, {remove, DB}). + +get_timeout () -> + 120000. % 2min. diff --git a/src/shared/struct/sh_attributes.erl b/src/shared/struct/sh_attributes.erl new file mode 100644 index 0000000..93dcfc6 --- /dev/null +++ b/src/shared/struct/sh_attributes.erl @@ -0,0 +1,108 @@ +-module(sh_attributes). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + attributes, + { + constitution :: integer(), + dexterity :: integer(), + intelligence :: integer(), + mind :: integer(), + speed :: integer(), + strength :: integer() + } +). + +-opaque type() :: #attributes{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_constitution/1, + get_dexterity/1, + get_intelligence/1, + get_mind/1, + get_speed/1, + get_strength/1, + + set_constitution/2, + set_dexterity/2, + set_intelligence/2, + set_mind/2, + set_speed/2, + set_strength/2 + ] +). + +%%%% Accessors +-export +( + [ + random/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_constitution (type()) -> integer(). +get_constitution (Att) -> Att#attributes.constitution. + +-spec get_dexterity (type()) -> integer(). +get_dexterity (Att) -> Att#attributes.dexterity. + +-spec get_intelligence (type()) -> integer(). +get_intelligence (Att) -> Att#attributes.intelligence. + +-spec get_mind (type()) -> integer(). +get_mind (Att) -> Att#attributes.mind. + +-spec get_speed (type()) -> integer(). +get_speed (Att) -> Att#attributes.speed. + +-spec get_strength (type()) -> integer(). +get_strength (Att) -> Att#attributes.strength. + +-spec set_constitution (integer(), type()) -> type(). +set_constitution (Val, Att) -> Att#attributes{ constitution = Val }. + +-spec set_dexterity (integer(), type()) -> type(). +set_dexterity (Val, Att) -> Att#attributes{ dexterity = Val }. + +-spec set_intelligence (integer(), type()) -> type(). +set_intelligence (Val, Att) -> Att#attributes{ intelligence = Val }. + +-spec set_mind (integer(), type()) -> type(). +set_mind (Val, Att) -> Att#attributes{ mind = Val }. + +-spec set_speed (integer(), type()) -> type(). +set_speed (Val, Att) -> Att#attributes{ speed = Val }. + +-spec set_strength (integer(), type()) -> type(). +set_strength (Val, Att) -> Att#attributes{ strength = Val }. + +-spec random () -> type(). +random () -> + #attributes + { + constitution = sh_roll:percentage(), + dexterity = sh_roll:percentage(), + intelligence = sh_roll:percentage(), + mind = sh_roll:percentage(), + speed = sh_roll:percentage(), + strength = sh_roll:percentage() + }. diff --git a/src/shared/struct/sh_db_item.erl b/src/shared/struct/sh_db_item.erl new file mode 100644 index 0000000..e499634 --- /dev/null +++ b/src/shared/struct/sh_db_item.erl @@ -0,0 +1,70 @@ +-module(sh_db_item). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../include/db_item.hrl"). + +-type type() :: db_item(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0]). + +-export +( + [ + new/3, + + get_id/1, + get_permission/1, + get_value/1, + + set_permission/2, + set_value/2, + + get_id_field/0, + get_record_info/0, + get_record_name/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (any(), db_user:permission(), any()) -> type(). +new (ID, Permission, Value) -> + #db_item + { + id = ID, + perm = Permission, + val = Value + }. + +-spec get_id (type()) -> any(). +get_id (#db_item { id = Result }) -> Result. + +-spec get_permission (type()) -> db_user:permission(). +get_permission (#db_item { perm = Result }) -> Result. + +-spec get_value (type()) -> any(). +get_value (#db_item { val = Result }) -> Result. + +-spec set_permission (db_user:permission(), type()) -> type(). +set_permission (Perm, Item) -> Item#db_item{ perm = Perm }. + +-spec set_value (any(), type()) -> type(). +set_value (Value, Item) -> Item#db_item{ val = Value }. + +-spec get_id_field () -> non_neg_integer(). +get_id_field () -> #db_item.id. + +get_record_info () -> record_info(fields, db_item). + +get_record_name () -> db_item. + diff --git a/src/shared/struct/sh_db_query.erl b/src/shared/struct/sh_db_query.erl new file mode 100644 index 0000000..998568e --- /dev/null +++ b/src/shared/struct/sh_db_query.erl @@ -0,0 +1,59 @@ +-module(sh_db_query). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../include/db_query.hrl"). + +-opaque op() :: db_query_op(). +-opaque type() :: db_query(). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([type/0, op/0]). + +-export +( + [ + new/4, + set_field/2, + add_to_field/2, + update_indexed/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (atom(), any(), sh_db_user:user(), list(op())) -> type(). +new (DBName, ObjectID, User, Ops) -> + #db_query + { + db = DBName, + id = ObjectID, + user = User, + ops = Ops + }. + +-spec set_field (non_neg_integer(), any()) -> op(). +set_field (Field, Value) -> + #set_field { field = Field, value = Value }. + +-spec add_to_field (non_neg_integer(), list(any())) -> op(). +add_to_field (Field, Values) -> + #add_to_field { field = Field, values = Values }. + +-spec update_indexed + ( + non_neg_integer(), + non_neg_integer(), + list(op()) + ) + -> op(). +update_indexed (Field, IX, Updates) -> + #update_indexed { field = Field, ix = IX, ops = Updates}. diff --git a/src/shared/struct/sh_db_user.erl b/src/shared/struct/sh_db_user.erl new file mode 100644 index 0000000..40a46d3 --- /dev/null +++ b/src/shared/struct/sh_db_user.erl @@ -0,0 +1,28 @@ +-module(sh_db_user). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-include("../include/db_user.hrl"). + +-type user() :: db_user(). +-type permission() :: db_permission(). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export_type([user/0, permission/0]). + +-export([can_access/2]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec can_access (permission(), user()) -> boolean(). +can_access (_, admin) -> true; +can_access (any, _) -> true; +can_access (List, {'user', User}) -> + lists:member(User, List). diff --git a/src/shared/struct/sh_statistics.erl b/src/shared/struct/sh_statistics.erl new file mode 100644 index 0000000..7cf2b06 --- /dev/null +++ b/src/shared/struct/sh_statistics.erl @@ -0,0 +1,193 @@ +-module(sh_statistics). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + statistics, + { + movement_points :: non_neg_integer(), + health :: non_neg_integer(), + dodges :: non_neg_integer(), + parries :: non_neg_integer(), + damage_min :: non_neg_integer(), + damage_max :: non_neg_integer(), + accuracy :: non_neg_integer(), + double_hits :: non_neg_integer(), + critical_hits :: non_neg_integer() + } +). + +-opaque type() :: #statistics{}. + +-export_type([type/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_movement_points/1, + get_health/1, + get_dodges/1, + get_parries/1, + get_damage_min/1, + get_damage_max/1, + get_accuracy/1, + get_double_hits/1, + get_critical_hits/1, + + get_damages/1 + ] +). + +-export +( + [ + new/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec ceil (float()) -> integer(). +ceil (F) -> + I = trunc(F), + case (F > I) of + true -> (I + 1); + _ -> I + end. + +-spec float_to_int (float()) -> integer(). +float_to_int (F) -> ceil(F). + +-spec min_max (number(), number(), number()) -> number(). +min_max (Min, Max, V) -> min(Max, max(Min, V)). + +-spec average (list(number())) -> number(). +%average ([]) -> 0; +average (L) -> lists:sum(L) / length(L). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 004 | 023 | 058 | 104 | 200 | +-spec gentle_squared_growth (number()) -> non_neg_integer(). +gentle_squared_growth (V) -> float_to_int(math:pow(V, 1.8) / 20). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 001 | 005 | 018 | 041 | 100 | +-spec sudden_squared_growth (number()) -> non_neg_integer(). +sudden_squared_growth (V) -> float_to_int(math:pow(V, 2.5) / 1000). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 002 | 006 | 016 | 049 | 256 | +-spec sudden_exp_growth (number()) -> non_neg_integer(). +sudden_exp_growth (V) -> float_to_int(math:pow(4, V / 25)). + +% V | 010 | 030 | 050 | 070 | 100 | +% F | 040 | 066 | 079 | 088 | 099 | +% Seems too generous, values for attributes below 50 should dip faster and +% lower. +%-spec already_high_slow_growth (non_neg_integer()) -> non_neg_integer(). +%already_high_slow_growth (V) -> float_to_int(30 * math:log((V + 5)/4)). + +-spec damage_base_modifier (non_neg_integer()) -> float(). +damage_base_modifier (Strength) -> ((math:pow(Strength, 1.8) / 2000.0) - 0.75). + +-spec apply_damage_base_modifier + ( + float(), + non_neg_integer() + ) + -> non_neg_integer(). +apply_damage_base_modifier (Modifier, BaseValue) -> + max(0, float_to_int(BaseValue + (BaseValue * Modifier))). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_movement_points (type()) -> non_neg_integer(). +get_movement_points (Stats) -> Stats#statistics.movement_points. + +-spec get_health (type()) -> non_neg_integer(). +get_health (Stats) -> Stats#statistics.health. + +-spec get_dodges (type()) -> non_neg_integer(). +get_dodges (Stats) -> Stats#statistics.dodges. + +-spec get_parries (type()) -> non_neg_integer(). +get_parries (Stats) -> Stats#statistics.parries. + +-spec get_damage_min (type()) -> non_neg_integer(). +get_damage_min (Stats) -> Stats#statistics.damage_min. + +-spec get_damage_max (type()) -> non_neg_integer(). +get_damage_max (Stats) -> Stats#statistics.damage_max. + +-spec get_accuracy (type()) -> non_neg_integer(). +get_accuracy (Stats) -> Stats#statistics.accuracy. + +-spec get_double_hits (type()) -> non_neg_integer(). +get_double_hits (Stats) -> Stats#statistics.double_hits. + +-spec get_critical_hits (type()) -> non_neg_integer(). +get_critical_hits (Stats) -> Stats#statistics.critical_hits. + +-spec get_damages (type()) -> {non_neg_integer(), non_neg_integer()}. +get_damages (Stats) -> + { + Stats#statistics.damage_min, + Stats#statistics.damage_max + }. + +-spec new + ( + attributes:type(), + {weapon:id(), weapon:id()} + ) + -> type(). +new (BaseAttributes, WeaponIDs) -> + {ActiveWeaponID, _} = WeaponIDs, + ActiveWeapon = weapon:from_id(ActiveWeaponID), + {MinDamage, MaxDamage} = weapon:get_damages(ActiveWeapon), + Attributes = weapon:apply_to_attributes(BaseAttributes, ActiveWeapon), + Constitution = attributes:get_constitution(Attributes), + Dexterity = attributes:get_dexterity(Attributes), + Intelligence = attributes:get_intelligence(Attributes), + Mind = attributes:get_mind(Attributes), + Speed = attributes:get_speed(Attributes), + Strength = attributes:get_strength(Attributes), + DamageBaseModifier = damage_base_modifier(Strength), + + #statistics + { + movement_points = + gentle_squared_growth + ( + average([Mind, Constitution, Constitution, Speed, Speed, Speed]) + ), + health = + gentle_squared_growth(average([Mind, Constitution, Constitution])), + dodges = + min_max(0, 100, sudden_exp_growth(average([Dexterity, Mind, Speed]))), + parries = + min_max + ( + 0, + 75, + sudden_exp_growth + ( + average([Dexterity, Intelligence, Speed, Strength]) + ) + ), + damage_min = apply_damage_base_modifier(DamageBaseModifier, MinDamage), + damage_max = apply_damage_base_modifier(DamageBaseModifier, MaxDamage), + accuracy = min_max(0, 100, sudden_squared_growth(Dexterity)), + double_hits = + min_max(0, 100, sudden_squared_growth(average([Mind, Speed]))), + critical_hits = min_max(0, 100, sudden_squared_growth(Intelligence)) + }. -- cgit v1.2.3-70-g09d2