From f539b7072c357339328d9bfd54f1f1ed51828586 Mon Sep 17 00:00:00 2001 From: nsensfel Date: Tue, 28 Nov 2017 17:14:02 +0100 Subject: Trying to tidy up this mess. --- src/battlemap.erl | 8 -- src/battlemap/cross.erl | 62 ------------ src/battlemap_instance.erl | 92 ------------------ src/battlemap_shim.erl | 47 --------- src/character.erl | 16 ---- src/character_instance.erl | 40 -------- src/character_shim.erl | 36 ------- src/data/tile.erl | 15 +++ src/database_shim.erl | 109 --------------------- src/io/database_shim.erl | 94 ++++++++++++++++++ src/io/timed_cache.erl | 85 +++++++++++++++++ src/io/timed_caches_manager.erl | 141 +++++++++++++++++++++++++++ src/query/character_turn.erl | 179 +++++++++++++++++++++++++++++++++++ src/query/load_state.erl | 123 ++++++++++++++++++++++++ src/tile.erl | 15 --- src/timed_cache.erl | 85 ----------------- src/timed_cache_data.hrl | 9 -- src/timed_caches_manager.erl | 141 --------------------------- src/type/battlemap.erl | 38 ++++++++ src/type/battlemap/cross.erl | 60 ++++++++++++ src/type/battlemap_instance.erl | 111 ++++++++++++++++++++++ src/type/battlemap_instance_shim.erl | 40 ++++++++ src/type/battlemap_shim.erl | 56 +++++++++++ src/type/character.erl | 34 +++++++ src/type/character_instance.erl | 72 ++++++++++++++ src/type/character_shim.erl | 47 +++++++++ 26 files changed, 1095 insertions(+), 660 deletions(-) delete mode 100644 src/battlemap.erl delete mode 100644 src/battlemap/cross.erl delete mode 100644 src/battlemap_instance.erl delete mode 100644 src/battlemap_shim.erl delete mode 100644 src/character.erl delete mode 100644 src/character_instance.erl delete mode 100644 src/character_shim.erl create mode 100644 src/data/tile.erl delete mode 100644 src/database_shim.erl create mode 100644 src/io/database_shim.erl create mode 100644 src/io/timed_cache.erl create mode 100644 src/io/timed_caches_manager.erl create mode 100644 src/query/character_turn.erl create mode 100644 src/query/load_state.erl delete mode 100644 src/tile.erl delete mode 100644 src/timed_cache.erl delete mode 100644 src/timed_cache_data.hrl delete mode 100644 src/timed_caches_manager.erl create mode 100644 src/type/battlemap.erl create mode 100644 src/type/battlemap/cross.erl create mode 100644 src/type/battlemap_instance.erl create mode 100644 src/type/battlemap_instance_shim.erl create mode 100644 src/type/battlemap_shim.erl create mode 100644 src/type/character.erl create mode 100644 src/type/character_instance.erl create mode 100644 src/type/character_shim.erl (limited to 'src') diff --git a/src/battlemap.erl b/src/battlemap.erl deleted file mode 100644 index ba89733..0000000 --- a/src/battlemap.erl +++ /dev/null @@ -1,8 +0,0 @@ --module(battlemap). --export([dist/2]). --include("timed_cache_data.hrl"). - --include("battlemap/cross.erl"). - -dist ({OX, OY}, {DX, DY}) -> - (abs(OX - DX) + abs(OY + DY)). diff --git a/src/battlemap/cross.erl b/src/battlemap/cross.erl deleted file mode 100644 index add9c27..0000000 --- a/src/battlemap/cross.erl +++ /dev/null @@ -1,62 +0,0 @@ --export([cross/5]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -next_loc (X, Y, <<"L">>) -> {(X - 1), Y}; -next_loc (X, Y, <<"R">>) -> {(X + 1), Y}; -next_loc (X, Y, <<"U">>) -> {X, (Y - 1)}; -next_loc (X, Y, <<"D">>) -> {X, (Y + 1)}. - -loc_to_index(X, Y, Map) -> - if - (X < 0) -> error; - (Y < 0) -> error; - (X >= Map#battlemap.width) -> error; - true -> ((Y * Map#battlemap.width) + X) - end. - -calc_new_loc (X, Y, [], Points, _Map, _CharInstsLocs) -> - io:format("~nPoints remaining: ~p ~n", [Points]), - true = (Points >= 0), - {X, Y}; -calc_new_loc (X, Y, [Step|Path], Points, Map, CharInstsLocs) -> - io:format("~nStep - Points remaining: ~p ~n", [Points]), - {NX, NY} = next_loc(X, Y, Step), - TileCost = - tile:get_cost - ( - array:get - ( - loc_to_index(NX, NY, Map), - Map#battlemap.content - ) - ), - io:format("~nStep cost: ~p ~n", [TileCost]), - NPoints = - ( - Points - - - TileCost - ), - false = lists:member({NX, NY}, CharInstsLocs), - calc_new_loc(NX, NY, Path, NPoints, Map, CharInstsLocs). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -cross (Battlemap, {X, Y}, Points, Path, CharInsts) -> - calc_new_loc - ( - X, - Y, - Path, - Points, - Battlemap, - lists:map - ( - fun character_instance:get_location/1, - CharInsts - ) - ). diff --git a/src/battlemap_instance.erl b/src/battlemap_instance.erl deleted file mode 100644 index afe6e32..0000000 --- a/src/battlemap_instance.erl +++ /dev/null @@ -1,92 +0,0 @@ --module(battlemap_instance). --export -( - [ - get_char_instances/1, - get_char_instance/2, - set_char_instance/3, - can_play_char_instance/3, - post_play_char_instance/2 - ] -). - --include("timed_cache_data.hrl"). - -get_char_instances (BattlemapInstance) -> - lists:map - ( - fun ({_K, V}) -> V end, - dict:to_list(BattlemapInstance#battlemap_instance.chars) - ). - -can_play_char_instance -( - BattlemapInstance, - PlayerID, - CharInstID -) -> - ( - ( - array:get - ( - BattlemapInstance#battlemap_instance.curr_player, - BattlemapInstance#battlemap_instance.players - ) - =:= - PlayerID - ) - and - lists:member(CharInstID, BattlemapInstance#battlemap_instance.rem_chars) - ). - -post_play_char_instance (BattlemapInstance, CharInstID) -> - case BattlemapInstance#battlemap_instance.rem_chars of - [CharInstID|[]] -> - NextPlayer = - ( - (BattlemapInstance#battlemap_instance.curr_player + 1) - rem - array:size(BattlemapInstance#battlemap_instance.players) - ), - BattlemapInstance#battlemap_instance - { - curr_player = NextPlayer, - rem_chars = - lists:filtermap - ( - fun ({K, V}) -> - case character_instance:get_owner(V) of - NextPlayer -> {true, K}; - _ -> false - end - end, - dict:to_list(BattlemapInstance#battlemap_instance.chars) - ) - }; - - _ -> - BattlemapInstance#battlemap_instance - { - rem_chars = - lists:delete - ( - CharInstID, - BattlemapInstance#battlemap_instance.rem_chars - ) - } - end. - -get_char_instance (BattlemapInstance, CharInstID) -> - dict:fetch(CharInstID, BattlemapInstance#battlemap_instance.chars). - -set_char_instance (BattlemapInstance, CharInstID, CharInst) -> - BattlemapInstance#battlemap_instance - { - chars = - dict:store - ( - CharInstID, - CharInst, - BattlemapInstance#battlemap_instance.chars - ) - }. diff --git a/src/battlemap_shim.erl b/src/battlemap_shim.erl deleted file mode 100644 index f4042d2..0000000 --- a/src/battlemap_shim.erl +++ /dev/null @@ -1,47 +0,0 @@ --module(battlemap_shim). --export -( - [ - generate/0 - ] -). - --include("timed_cache_data.hrl"). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -generate(_Prev, Result, _X, 0, _BaseWidth) -> - Result; -generate(Prev, Result, 0, Y, BaseWidth) -> - generate(Prev, Result, BaseWidth, (Y - 1), BaseWidth); -generate(Prev, Result, X, Y, BaseWidth) -> - case rand:uniform(100) of - N when (N >= 10) -> - generate(Prev, [Prev|Result], (X - 1), Y, BaseWidth); - - N -> - NewTileType = (N - 1), - generate - ( - NewTileType, - [NewTileType|Result], - (X - 1), - Y, - BaseWidth - ) - end. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -generate () -> - Width = (rand:uniform(48) + 16), - Height = (rand:uniform(48) + 16), - #battlemap - { - id = <<"0">>, - width = Width, - height = Height, - content = array:from_list(generate(0, [], Width, Height, Width)) - }. diff --git a/src/character.erl b/src/character.erl deleted file mode 100644 index 4da1684..0000000 --- a/src/character.erl +++ /dev/null @@ -1,16 +0,0 @@ --module(character). --export -( - [ - get_movement_points/1, - get_attack_range/1, - get_max_health/1 - ] -). - --include("timed_cache_data.hrl"). - -get_movement_points (Char) -> Char#character.mov_pts. -get_attack_range (Char) -> Char#character.atk_rg. - -get_max_health (Char) -> Char#character.health. diff --git a/src/character_instance.erl b/src/character_instance.erl deleted file mode 100644 index e1cf7fe..0000000 --- a/src/character_instance.erl +++ /dev/null @@ -1,40 +0,0 @@ --module(character_instance). --export -( - [ - set_location/3, - mod_health/3, - is_dead/1, % is_alive is reserved. - get_location/1, - get_owner/1 - ] -). - --include("timed_cache_data.hrl"). - -set_location (CharInst, X, Y) -> - CharInst#character_instance - { - x = X, - y = Y - }. - -mod_health (CharInst, MaxHealth, HealthMod) -> - NewHealth = (CharInst#character_instance.health + HealthMod), - if - (NewHealth < 0) -> - CharInst#character_instance{ health = 0 }; - - (NewHealth > MaxHealth) -> - CharInst#character_instance{ health = MaxHealth }; - - true -> - CharInst#character_instance{ health = NewHealth } - end. - -is_dead (CharInst) -> (CharInst#character_instance.health == 0). - -get_location (CharInst) -> - {CharInst#character_instance.x, CharInst#character_instance.y}. - -get_owner (CharInst) -> CharInst#character_instance.team. diff --git a/src/character_shim.erl b/src/character_shim.erl deleted file mode 100644 index 47d9cac..0000000 --- a/src/character_shim.erl +++ /dev/null @@ -1,36 +0,0 @@ --module(character_shim). --export -( - [ - generate/1 - ] -). - --include("timed_cache_data.hrl"). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -generate_char (N) -> - IDAsString = list_to_binary(integer_to_list(N)), - #character - { - id = IDAsString, % ID - name = IDAsString, % Name - icon = IDAsString, % Icon - portrait = IDAsString, % Portrait - health = (rand:uniform(5) + 1), - mov_pts = (rand:uniform(10) + 10), % Movement Points - atk_rg = (rand:uniform(5) - 1) % Attack Range - }. - -generate (0, Result) -> - Result; -generate (N, Prev) -> - generate((N - 1), [generate_char(N - 1)|Prev]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -generate (N) -> - generate(N, []). diff --git a/src/data/tile.erl b/src/data/tile.erl new file mode 100644 index 0000000..cb5811b --- /dev/null +++ b/src/data/tile.erl @@ -0,0 +1,15 @@ +-module(tile). +-export +( + [ + get_cost/1, + cost_when_oob/0 + ] +). +cost_when_oob () -> 255. + +get_cost (N) -> + if + (N =< 200) -> (N + 1); + true -> cost_when_oob() + end. diff --git a/src/database_shim.erl b/src/database_shim.erl deleted file mode 100644 index c840009..0000000 --- a/src/database_shim.erl +++ /dev/null @@ -1,109 +0,0 @@ --module(database_shim). --export -( - [ - generate_db/1, - fetch/2, - commit/3 - ] -). - --include("timed_cache_data.hrl"). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -create_db (_Heir) -> - ets:new - ( - db_shim, - [ - set, - public, - named_table, - {keypos, 1}, - {read_concurrency, true} - ] - ), - io:format("~ndb_shim ets created.~n"). - -add_to_db (ID, Val) -> - io:format("~nadd to db_shim: ~p.~n", [{ID, Val}]), - ets:insert(db_shim, {ID, Val}). - -generate_char_instances (Battlemap, Characters) -> - lists:map - ( - fun (Char) -> - { - Char#character.id, - #character_instance - { - x = rand:uniform(Battlemap#battlemap.width - 1), - y = rand:uniform(Battlemap#battlemap.height - 1), - team = (rand:uniform(2) - 1), - health = Char#character.health - } - } - end, - Characters - ). - -generate_map_instance (CharInts) -> - #battlemap_instance - { - id = <<"0">>, - chars = dict:from_list(CharInts), - curr_player = 0, - players = array:from_list([<<"0">>, <<"1">>]), - rem_chars = - lists:filtermap - ( - fun ({K, V}) -> - case character_instance:get_owner(V) of - 0 -> {true, K}; - _ -> false - end - end, - CharInts - ), - last_turn = [] - }. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -generate_db (Heir) -> - Pid = self(), - spawn(fun () -> create_db(Heir), Pid ! ok, receive ok -> ok end end), - receive - ok -> ok - end, - Battlemap = battlemap_shim:generate(), - Characters = character_shim:generate(rand:uniform(12) + 4), - CharacterInsts = generate_char_instances(Battlemap, Characters), - BattlemapInstance = generate_map_instance(CharacterInsts), - add_to_db({battlemap_db, Battlemap#battlemap.id}, Battlemap), - lists:map - ( - fun (Char) -> - add_to_db({character_db, Char#character.id}, Char) - end, - Characters - ), - add_to_db - ( - {battlemap_instance_db, BattlemapInstance#battlemap_instance.id}, - BattlemapInstance - ). - -fetch (DB, ObjectID) -> - io:format("~ndb_shim lookup: ~p.~n", [{DB, ObjectID}]), - case ets:lookup(db_shim, {DB, ObjectID}) of - [{_Key, Value}] -> {ok, Value}; - [] -> nothing - end. - -commit (DB, ObjectID, Value) -> - add_to_db({DB, ObjectID}, Value), - timed_cache:invalidate(DB, ObjectID). diff --git a/src/io/database_shim.erl b/src/io/database_shim.erl new file mode 100644 index 0000000..243051b --- /dev/null +++ b/src/io/database_shim.erl @@ -0,0 +1,94 @@ +-module(database_shim). +-export +( + [ + generate_db/1, + fetch/2, + commit/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +create_db (_Heir) -> + ets:new + ( + db_shim, + [ + set, + public, + named_table, + {keypos, 1}, + {read_concurrency, true} + ] + ), + io:format("~ndb_shim ets created.~n"). + +add_to_db (ID, Val) -> + io:format("~nadd to db_shim: ~p.~n", [{ID, Val}]), + ets:insert(db_shim, {ID, Val}). + +generate_char_instances (Battlemap, Characters) -> + lists:map + ( + fun (Char) -> + { + character:get_id(Char), + character_instance:new_instance_of + ( + Char, + (rand:uniform(2) - 1), % team, + { + rand:uniform(battlemap:get_width(Battlemap) - 1), % X + rand:uniform(battlemap:get_heigth(Battlemap) - 1) % Y + } + ) + } + end, + Characters + ). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +generate_db (Heir) -> + Pid = self(), + spawn(fun () -> create_db(Heir), Pid ! ok, receive ok -> ok end end), + receive + ok -> ok + end, + Players = [<<"0">>, <<"1">>], + Battlemap = battlemap_shim:generate_random(), + Characters = character_shim:generate_random(rand:uniform(12) + 4), + CharacterInsts = generate_char_instances(Battlemap, Characters), + BattlemapInstance = + battlemap_instance_shim:generate_random + ( + CharacterInsts, + Players + ), + add_to_db({battlemap_db, battlemap:get_id(Battlemap)}, Battlemap), + lists:map + ( + fun (Char) -> + add_to_db({character_db, character:get_id(Char)}, Char) + end, + Characters + ), + add_to_db + ( + {battlemap_instance_db, battlemap_instance:get_id(BattlemapInstance)}, + BattlemapInstance + ). + +fetch (DB, ObjectID) -> + io:format("~ndb_shim lookup: ~p.~n", [{DB, ObjectID}]), + case ets:lookup(db_shim, {DB, ObjectID}) of + [{_Key, Value}] -> {ok, Value}; + [] -> nothing + end. + +commit (DB, ObjectID, Value) -> + add_to_db({DB, ObjectID}, Value), + timed_cache:invalidate(DB, ObjectID). diff --git a/src/io/timed_cache.erl b/src/io/timed_cache.erl new file mode 100644 index 0000000..c86caab --- /dev/null +++ b/src/io/timed_cache.erl @@ -0,0 +1,85 @@ +-module(timed_cache). +-behavior(gen_server). + +%%%% 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/2, + invalidate/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +add_to_cache (DB, ObjectID) -> + {ok, TimerPID} = gen_server:start(?MODULE, {DB, ObjectID}, []), + {ok, Data} = database_shim:fetch(DB, ObjectID), + ets:insert(DB, {ObjectID, TimerPID, Data}), + Data. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% gen_server + +init ({DB, ObjectID}) -> + {ok, {DB, ObjectID}}. + +handle_call (invalidate, _, State) -> + {stop, normal, State}; +handle_call (ping, _, {DB, ObjectID}) -> + {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}. + +handle_cast (invalidate, State) -> + {stop, normal, State}; +handle_cast (ping, {DB, ObjectID}) -> + {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}. + +terminate (_, {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(DB)}. + +%%%% interface +fetch (DB, ObjectID) -> + io:format("~nfetch from cache: ~p.~n", [{DB, ObjectID}]), + case ets:lookup(DB, ObjectID) of + [] -> add_to_cache(DB, ObjectID); + + [{_, TimerPID, Data}] -> + gen_server:cast(TimerPID, ping), + Data + end. + +invalidate (DB, ObjectID) -> + case ets:lookup(DB, ObjectID) of + [] -> ok; + + [{_, TimerPID, _}] -> + gen_server:stop(TimerPID) + end. diff --git a/src/io/timed_caches_manager.erl b/src/io/timed_caches_manager.erl new file mode 100644 index 0000000..ad66fbb --- /dev/null +++ b/src/io/timed_caches_manager.erl @@ -0,0 +1,141 @@ +-module(timed_caches_manager). +-behavior(gen_server). + +%%%% 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( + [ + add_cache/3, + inherit_cache/3, + delete_cache/2, + get_timeout/1 + ] +) +. +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%% Manager %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +delete_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, 2}, + {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, 2}, + {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. + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% gen_server +init (CacheList) -> + io:format("~nStarting Timed Caches Manager..."), + {ok, CacheList}. + +handle_call ({delete, CacheName}, _Caller, State) -> + {noreply, delete_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 ({delete, CacheName}, State) -> + {noreply, delete_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]) -> + delete_cache(CacheName), + terminate(Reason, OtherCaches). + +code_change (_, State, _) -> + {ok, State}. + +format_status (_, [_, State]) -> + [{data, [{"State", State}]}]. + +handle_info(_, State) -> + {noreply, State}. + +%%%% actual interface +delete_cache (CacheList, DB) -> + case lists:member(DB, CacheList) of + true -> + delete_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. + +get_timeout(battlemap_db) -> + 60000; +get_timeout(_) -> + 60000. diff --git a/src/query/character_turn.erl b/src/query/character_turn.erl new file mode 100644 index 0000000..cf55585 --- /dev/null +++ b/src/query/character_turn.erl @@ -0,0 +1,179 @@ +-module(character_turn). +-record +( + input, + { + session_token, + player_id, + battlemap_id, + instance_id, + char_id, + path, + target_id + } +). +-record +( + query_state, + { + input, + battlemap, + battlemap_inst, + main_char, + main_char_inst, + main_char_new_loc, + target_char, + target_char_inst + } +). +-export([out/1]). + +parse_input (Req) -> + JSONReqMap = jiffy:decode(Req, [return_maps]), + #input + { + session_token = maps:get(<<"session_token">>, JSONReqMap), + player_id = maps:get(<<"player_id">>, JSONReqMap), + battlemap_id = maps:get(<<"battlemap_id">>, JSONReqMap), + instance_id = maps:get(<<"instance_id">>, JSONReqMap), + char_id = maps:get(<<"char_id">>, JSONReqMap), + path = maps:get(<<"path">>, JSONReqMap), + target_id = maps:get(<<"target_id">>, JSONReqMap) + }. + +fetch_data (Input) -> + Battlemap = timed_cache:fetch(battlemap_db, Input#input.battlemap_id), + BattlemapInst = + timed_cache:fetch + ( + battlemap_instance_db, + <<"0">> + ), + MainChar = timed_cache:fetch(character_db, Input#input.char_id), + MainCharInst = + battlemap_instance:get_char_instance + ( + BattlemapInst, + Input#input.char_id + ), + case Input#input.target_id of + <<"">> -> + TargetChar = nothing, + TargetCharInst = nothing; + + TargetID -> + TargetChar = timed_cache:fetch(character_db, TargetID), + TargetCharInst = + battlemap_instance:get_char_instance + ( + BattlemapInst, + TargetID + ) + end, + #query_state + { + input = Input, + battlemap = Battlemap, + battlemap_inst = BattlemapInst, + main_char = MainChar, + main_char_inst = MainCharInst, + main_char_new_loc = nothing, + target_char = TargetChar, + target_char_inst = TargetCharInst + }. + +assert_main_char_can_be_used (QueryState) -> + false = character_instance:is_dead(QueryState#query_state.main_char_inst), + true = + battlemap_instance:can_play_char_instance + ( + QueryState#query_state.battlemap_inst, + QueryState#query_state.input#input.player_id, + QueryState#query_state.input#input.char_id + ). + +handle_main_char_movement (QueryState) -> + {X, Y} = + battlemap:cross + ( + QueryState#query_state.battlemap, + character_instance:get_location(QueryState#query_state.main_char_inst), + character:get_movement_points(QueryState#query_state.main_char), + QueryState#query_state.input#input.path, + battlemap_instance:get_char_instances + ( + QueryState#query_state.battlemap_inst + ) + ), + QueryState#query_state + { + battlemap_inst = + battlemap_instance:set_char_instance + ( + battlemap_instance:post_play_char_instance + ( + QueryState#query_state.battlemap_inst, + QueryState#query_state.input#input.char_id + ), + QueryState#query_state.input#input.char_id, + character_instance:set_location + ( + QueryState#query_state.main_char_inst, + X, + Y + ) + ), + main_char_new_loc = {X, Y} + }. + +handle_target (QueryState) + when (QueryState#query_state.target_char_inst == nothing) -> + QueryState; +handle_target (QueryState) -> + TargetLoc = + character_instance:get_location(QueryState#query_state.main_char_inst), + Dist = + battlemap:dist(QueryState#query_state.main_char_new_loc, TargetLoc), + true = + (Dist =< character:get_attack_range(QueryState#query_state.main_char)), + %% TODO: test for (and handle) riposte. + QueryState#query_state + { + battlemap_inst = + battlemap_instance:set_char_instance + ( + QueryState#query_state.battlemap_inst, + QueryState#query_state.input#input.target_id, + character_instance:mod_health + ( + QueryState#query_state.target_char_inst, + -1, + character:get_max_health(QueryState#query_state.main_char) + ) + ) + }. + +handle (Req) -> + %%%% Parse + Input = parse_input(Req), + %%%% Fetch + QueryState = fetch_data(Input), + %%%% Calc + assert_main_char_can_be_used(QueryState), + NQueryState = handle_target(handle_main_char_movement(QueryState)), + %%%% Commit + database_shim:commit + ( + battlemap_instance_db, + <<"0">>, + NQueryState#query_state.battlemap_inst + ), + %%%% Reply + jiffy:encode([[<<"okay">>]]). + +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/query/load_state.erl b/src/query/load_state.erl new file mode 100644 index 0000000..f2818bd --- /dev/null +++ b/src/query/load_state.erl @@ -0,0 +1,123 @@ +-module(load_state). +-record(input, {session_token, player_id, battlemap_id, instance_id}). +-export([out/1]). + +parse_input (Req) -> + JSONReqMap = jiffy:decode(Req, [return_maps]), + #input + { + session_token = maps:get(<<"session_token">>, JSONReqMap), + player_id = maps:get(<<"player_id">>, JSONReqMap), + battlemap_id = maps:get(<<"battlemap_id">>, JSONReqMap), + instance_id = maps:get(<<"instance_id">>, JSONReqMap) + }. + +generate_set_map (Battlemap) -> + jiffy:encode + ( + { + [ + {<<"width">>, battlemap:get_width(Battlemap)}, + {<<"height">>, battlemap:get_height(Battlemap)}, + {<<"content">>, battlemap:list_tiles(Battlemap)} + ] + } + ). + +generate_add_char (Char, CharInstance, BattlemapInstance, PlayerID) -> + {X, Y} = character_instance:get_location(CharInstance), + CharID = character:get_id(Char), + jiffy:encode + ( + { + [ + {<<"id">>, character:get_id(Char)}, + {<<"name">>, character:get_name(Char)}, + {<<"icon">>, character:get_icon(Char)}, + {<<"portrait">>, character:get_portrait(Char)}, + {<<"loc_x">>, X}, + {<<"loc_y">>, Y}, + {<<"team">>, character_instance:get_owner(CharInstance)}, + {<<"mov_pts">>, character:get_movement_points(Char)}, + {<<"atk_rg">>, character:get_attack_range(Char)}, + { + <<"enabled">>, + battlemap_instance:can_play_char_instance + ( + BattlemapInstance, + PlayerID, + CharID + ) + } + ] + } + ). + +generate_reply (Battlemap, BattlemapInstance, Characters, PlayerID) -> + jiffy:encode + ( + [ + [ + <<"set_map">>, + generate_set_map(Battlemap) + ] + | + lists:map + ( + fun ({CharID, CharInstance}) -> + [ + <<"add_char">>, + generate_add_char + ( + CharID, + CharInstance, + BattlemapInstance, + PlayerID + ) + ] + end, + Characters + ) + ] + ). + +handle (Req) -> + %%%% Parse + Input = parse_input(Req), + %%%% Fetch + Battlemap = timed_cache:fetch(battlemap_db, Input#input.battlemap_id), + BattlemapInstance = + timed_cache:fetch + ( + battlemap_instance_db, + <<"0">> +% {Input#input.battlemap_id, Input#input.battlemap_instance_id} + ), + Characters = + lists:map + ( + fun ({CharID, CharInst}) -> + { + timed_cache:fetch(character_db, CharID), + CharInst + } + end, + battlemap_instance:list_characters(BattlemapInstance) + ), + %%%% Calc + %%%% Commit + %%%% Reply + generate_reply + ( + Battlemap, + BattlemapInstance, + Characters, + Input#input.player_id + ). + +out(A) -> + { + content, + "application/json; charset=UTF-8", + handle(A#arg.clidata) + }. diff --git a/src/tile.erl b/src/tile.erl deleted file mode 100644 index cb5811b..0000000 --- a/src/tile.erl +++ /dev/null @@ -1,15 +0,0 @@ --module(tile). --export -( - [ - get_cost/1, - cost_when_oob/0 - ] -). -cost_when_oob () -> 255. - -get_cost (N) -> - if - (N =< 200) -> (N + 1); - true -> cost_when_oob() - end. diff --git a/src/timed_cache.erl b/src/timed_cache.erl deleted file mode 100644 index c86caab..0000000 --- a/src/timed_cache.erl +++ /dev/null @@ -1,85 +0,0 @@ --module(timed_cache). --behavior(gen_server). - -%%%% 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/2, - invalidate/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -add_to_cache (DB, ObjectID) -> - {ok, TimerPID} = gen_server:start(?MODULE, {DB, ObjectID}, []), - {ok, Data} = database_shim:fetch(DB, ObjectID), - ets:insert(DB, {ObjectID, TimerPID, Data}), - Data. - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% gen_server - -init ({DB, ObjectID}) -> - {ok, {DB, ObjectID}}. - -handle_call (invalidate, _, State) -> - {stop, normal, State}; -handle_call (ping, _, {DB, ObjectID}) -> - {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}. - -handle_cast (invalidate, State) -> - {stop, normal, State}; -handle_cast (ping, {DB, ObjectID}) -> - {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout(DB)}. - -terminate (_, {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(DB)}. - -%%%% interface -fetch (DB, ObjectID) -> - io:format("~nfetch from cache: ~p.~n", [{DB, ObjectID}]), - case ets:lookup(DB, ObjectID) of - [] -> add_to_cache(DB, ObjectID); - - [{_, TimerPID, Data}] -> - gen_server:cast(TimerPID, ping), - Data - end. - -invalidate (DB, ObjectID) -> - case ets:lookup(DB, ObjectID) of - [] -> ok; - - [{_, TimerPID, _}] -> - gen_server:stop(TimerPID) - end. diff --git a/src/timed_cache_data.hrl b/src/timed_cache_data.hrl deleted file mode 100644 index 89e0f41..0000000 --- a/src/timed_cache_data.hrl +++ /dev/null @@ -1,9 +0,0 @@ -%% TODO: add types. --record(battlemap, {id, width, height, content, instances}). --record(battlemap_instance, {id, chars, curr_player, players, rem_chars, last_turn}). --record(character, {id, name, icon, portrait, health, mov_pts, atk_rg}). --record(character_turn, {id, path, target}). --record(player, {id, battlemaps, characters}). - -%% Not stored in its own timed cache. --record(character_instance, {x, y, health, team}). diff --git a/src/timed_caches_manager.erl b/src/timed_caches_manager.erl deleted file mode 100644 index ad66fbb..0000000 --- a/src/timed_caches_manager.erl +++ /dev/null @@ -1,141 +0,0 @@ --module(timed_caches_manager). --behavior(gen_server). - -%%%% 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( - [ - add_cache/3, - inherit_cache/3, - delete_cache/2, - get_timeout/1 - ] -) -. -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%% Manager %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -delete_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, 2}, - {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, 2}, - {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. - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% gen_server -init (CacheList) -> - io:format("~nStarting Timed Caches Manager..."), - {ok, CacheList}. - -handle_call ({delete, CacheName}, _Caller, State) -> - {noreply, delete_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 ({delete, CacheName}, State) -> - {noreply, delete_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]) -> - delete_cache(CacheName), - terminate(Reason, OtherCaches). - -code_change (_, State, _) -> - {ok, State}. - -format_status (_, [_, State]) -> - [{data, [{"State", State}]}]. - -handle_info(_, State) -> - {noreply, State}. - -%%%% actual interface -delete_cache (CacheList, DB) -> - case lists:member(DB, CacheList) of - true -> - delete_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. - -get_timeout(battlemap_db) -> - 60000; -get_timeout(_) -> - 60000. diff --git a/src/type/battlemap.erl b/src/type/battlemap.erl new file mode 100644 index 0000000..cce1a76 --- /dev/null +++ b/src/type/battlemap.erl @@ -0,0 +1,38 @@ +-module(battlemap). +-record +( + battlemap, + { + id, + width, + height, + content, + instances + } +). +-export +( + [ + get_id/1, + get_width/1, + get_height/1, + list_tiles/1, + get_instances/1 + ] +). +-export +( + [dist/2] +). +-export([cross/5]). + +get_id (Battlemap) -> Battlemap#battlemap.id. +get_width (Battlemap) -> Battlemap#battlemap.width. +get_height (Battlemap) -> Battlemap#battlemap.height. +list_tiles (Battlemap) -> array:sparse_to_list(Battlemap#battlemap.content). +get_instances (Battlemap) -> Battlemap#battlemap.instances. + +-include("battlemap/cross.erl"). + +dist ({OX, OY}, {DX, DY}) -> + (abs(OX - DX) + abs(OY + DY)). diff --git a/src/type/battlemap/cross.erl b/src/type/battlemap/cross.erl new file mode 100644 index 0000000..aa1645e --- /dev/null +++ b/src/type/battlemap/cross.erl @@ -0,0 +1,60 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +next_loc (X, Y, <<"L">>) -> {(X - 1), Y}; +next_loc (X, Y, <<"R">>) -> {(X + 1), Y}; +next_loc (X, Y, <<"U">>) -> {X, (Y - 1)}; +next_loc (X, Y, <<"D">>) -> {X, (Y + 1)}. + +loc_to_index(X, Y, Map) -> + if + (X < 0) -> error; + (Y < 0) -> error; + (X >= Map#battlemap.width) -> error; + true -> ((Y * Map#battlemap.width) + X) + end. + +calc_new_loc (X, Y, [], Points, _Map, _CharInstsLocs) -> + io:format("~nPoints remaining: ~p ~n", [Points]), + true = (Points >= 0), + {X, Y}; +calc_new_loc (X, Y, [Step|Path], Points, Map, CharInstsLocs) -> + io:format("~nStep - Points remaining: ~p ~n", [Points]), + {NX, NY} = next_loc(X, Y, Step), + TileCost = + tile:get_cost + ( + array:get + ( + loc_to_index(NX, NY, Map), + Map#battlemap.content + ) + ), + io:format("~nStep cost: ~p ~n", [TileCost]), + NPoints = + ( + Points + - + TileCost + ), + false = lists:member({NX, NY}, CharInstsLocs), + calc_new_loc(NX, NY, Path, NPoints, Map, CharInstsLocs). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +cross (Battlemap, {X, Y}, Points, Path, CharInsts) -> + calc_new_loc + ( + X, + Y, + Path, + Points, + Battlemap, + lists:map + ( + fun character_instance:get_location/1, + CharInsts + ) + ). diff --git a/src/type/battlemap_instance.erl b/src/type/battlemap_instance.erl new file mode 100644 index 0000000..26ca5b1 --- /dev/null +++ b/src/type/battlemap_instance.erl @@ -0,0 +1,111 @@ +-module(battlemap_instance). +-record +( + battlemap_instance, + { + id, + chars, + curr_player, + players, + rem_chars, + last_turn + } +). +-export +( + [ + list_characters/1 + ] +). +-export +( + [ + get_char_instances/1, + get_char_instance/2, + set_char_instance/3, + can_play_char_instance/3, + post_play_char_instance/2 + ] +). + +list_characters (BattlemapInstance) -> + dict:to_list(BattlemapInstance#battlemap_instance.chars). + +get_char_instances (BattlemapInstance) -> + lists:map + ( + fun ({_K, V}) -> V end, + dict:to_list(BattlemapInstance#battlemap_instance.chars) + ). + +can_play_char_instance +( + BattlemapInstance, + PlayerID, + CharInstID +) -> + ( + ( + array:get + ( + BattlemapInstance#battlemap_instance.curr_player, + BattlemapInstance#battlemap_instance.players + ) + =:= + PlayerID + ) + and + lists:member(CharInstID, BattlemapInstance#battlemap_instance.rem_chars) + ). + +post_play_char_instance (BattlemapInstance, CharInstID) -> + case BattlemapInstance#battlemap_instance.rem_chars of + [CharInstID|[]] -> + NextPlayer = + ( + (BattlemapInstance#battlemap_instance.curr_player + 1) + rem + array:size(BattlemapInstance#battlemap_instance.players) + ), + BattlemapInstance#battlemap_instance + { + curr_player = NextPlayer, + rem_chars = + lists:filtermap + ( + fun ({K, V}) -> + case character_instance:get_owner(V) of + NextPlayer -> {true, K}; + _ -> false + end + end, + dict:to_list(BattlemapInstance#battlemap_instance.chars) + ) + }; + + _ -> + BattlemapInstance#battlemap_instance + { + rem_chars = + lists:delete + ( + CharInstID, + BattlemapInstance#battlemap_instance.rem_chars + ) + } + end. + +get_char_instance (BattlemapInstance, CharInstID) -> + dict:fetch(CharInstID, BattlemapInstance#battlemap_instance.chars). + +set_char_instance (BattlemapInstance, CharInstID, CharInst) -> + BattlemapInstance#battlemap_instance + { + chars = + dict:store + ( + CharInstID, + CharInst, + BattlemapInstance#battlemap_instance.chars + ) + }. diff --git a/src/type/battlemap_instance_shim.erl b/src/type/battlemap_instance_shim.erl new file mode 100644 index 0000000..80a1007 --- /dev/null +++ b/src/type/battlemap_instance_shim.erl @@ -0,0 +1,40 @@ +-module(battlemap_instance_shim). +-record +( + battlemap_instance, + { + id, + chars, + curr_player, + players, + rem_chars, + last_turn + } +). +-export +( + [ + generate_random/2 + ] +). + +generate_random (CharInsts, Players) -> + #battlemap_instance + { + id = <<"0">>, + chars = dict:from_list(CharInsts), + curr_player = 0, + players = array:from_list(Players), + rem_chars = + lists:filtermap + ( + fun ({K, V}) -> + case character_instance:get_owner(V) of + 0 -> {true, K}; + _ -> false + end + end, + CharInsts + ), + last_turn = [] + }. diff --git a/src/type/battlemap_shim.erl b/src/type/battlemap_shim.erl new file mode 100644 index 0000000..1fb035e --- /dev/null +++ b/src/type/battlemap_shim.erl @@ -0,0 +1,56 @@ +-module(battlemap_shim). +-record +( + battlemap, + { + id, + width, + height, + content, + instances + } +). +-export +( + [ + generate_random/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +generate(_Prev, Result, _X, 0, _BaseWidth) -> + Result; +generate(Prev, Result, 0, Y, BaseWidth) -> + generate(Prev, Result, BaseWidth, (Y - 1), BaseWidth); +generate(Prev, Result, X, Y, BaseWidth) -> + case rand:uniform(100) of + N when (N >= 10) -> + generate(Prev, [Prev|Result], (X - 1), Y, BaseWidth); + + N -> + NewTileType = (N - 1), + generate + ( + NewTileType, + [NewTileType|Result], + (X - 1), + Y, + BaseWidth + ) + end. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +generate_random () -> + Width = (rand:uniform(48) + 16), + Height = (rand:uniform(48) + 16), + #battlemap + { + id = <<"0">>, + width = Width, + height = Height, + content = array:from_list(generate(0, [], Width, Height, Width)) + }. diff --git a/src/type/character.erl b/src/type/character.erl new file mode 100644 index 0000000..e5b6d9f --- /dev/null +++ b/src/type/character.erl @@ -0,0 +1,34 @@ +-module(character). +-record +( + character, + { + id, + name, + icon, + portrait, + health, + mov_pts, + atk_rg + } +). +-export +( + [ + get_id/1, + get_name/1, + get_icon/1, + get_portrait/1, + get_max_health/1, + get_movement_points/1, + get_attack_range/1 + ] +). + +get_id (Char) -> Char#character.id. +get_name (Char) -> Char#character.name. +get_icon (Char) -> Char#character.icon. +get_portrait (Char) -> Char#character.portrait. +get_max_health (Char) -> Char#character.health. +get_movement_points (Char) -> Char#character.mov_pts. +get_attack_range (Char) -> Char#character.atk_rg. diff --git a/src/type/character_instance.erl b/src/type/character_instance.erl new file mode 100644 index 0000000..5432c99 --- /dev/null +++ b/src/type/character_instance.erl @@ -0,0 +1,72 @@ +-module(character_instance). +-record +( + character_instance, + { + x, + y, + health, + team + } +). +-export +( + [ + get_location/1, + get_current_health/1, + get_owner/1 + ] +). +-export +( + [ + new_instance_of/3 + ] +). +-export +( + [ + set_location/3, + mod_health/3, + is_dead/1 % is_alive is reserved. + ] +). + +get_location (CharInst) -> + {CharInst#character_instance.x, CharInst#character_instance.y}. + +get_current_health (CharInst) -> CharInst#character_instance.health. + +get_owner (CharInst) -> CharInst#character_instance.team. + +new_instance_of (Char, Owner, {X, Y}) -> + #character_instance + { + x = X, + y = Y, + health = character:get_max_health(Char), + team = Owner + }. + +set_location (CharInst, X, Y) -> + CharInst#character_instance + { + x = X, + y = Y + }. + +mod_health (CharInst, MaxHealth, HealthMod) -> + NewHealth = (CharInst#character_instance.health + HealthMod), + if + (NewHealth < 0) -> + CharInst#character_instance{ health = 0 }; + + (NewHealth > MaxHealth) -> + CharInst#character_instance{ health = MaxHealth }; + + true -> + CharInst#character_instance{ health = NewHealth } + end. + +is_dead (CharInst) -> (CharInst#character_instance.health == 0). + diff --git a/src/type/character_shim.erl b/src/type/character_shim.erl new file mode 100644 index 0000000..0ad357d --- /dev/null +++ b/src/type/character_shim.erl @@ -0,0 +1,47 @@ +-module(character_shim). +-record +( + character, + { + id, + name, + icon, + portrait, + health, + mov_pts, + atk_rg + } +). +-export +( + [ + generate_random/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +generate_char (N) -> + IDAsString = list_to_binary(integer_to_list(N)), + #character + { + id = IDAsString, % ID + name = IDAsString, % Name + icon = IDAsString, % Icon + portrait = IDAsString, % Portrait + health = (rand:uniform(5) + 1), + mov_pts = (rand:uniform(10) + 10), % Movement Points + atk_rg = (rand:uniform(5) - 1) % Attack Range + }. + +generate (0, Result) -> + Result; +generate (N, Prev) -> + generate((N - 1), [generate_char(N - 1)|Prev]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +generate_random (N) -> + generate(N, []). -- cgit v1.2.3-70-g09d2