From acb9dd3220a3edcac93aa11d1d74d008e2fb23ed Mon Sep 17 00:00:00 2001 From: nsensfel Date: Wed, 11 Jul 2018 18:02:26 +0200 Subject: "sh_" -> "shr_". --- src/shared/io/sh_database.erl | 58 ---- src/shared/io/sh_timed_cache.erl | 130 --------- src/shared/io/sh_timed_caches_manager.erl | 152 ----------- src/shared/io/shr_database.erl | 58 ++++ src/shared/io/shr_timed_cache.erl | 130 +++++++++ src/shared/io/shr_timed_caches_manager.erl | 152 +++++++++++ src/shared/sh_roll.erl | 32 --- src/shared/shr_roll.erl | 32 +++ src/shared/struct/sh_armor.erl | 185 ------------- src/shared/struct/sh_attributes.erl | 135 ---------- src/shared/struct/sh_db_item.erl | 80 ------ src/shared/struct/sh_db_query.erl | 214 --------------- src/shared/struct/sh_db_user.erl | 31 --- src/shared/struct/sh_statistics.erl | 200 -------------- src/shared/struct/sh_weapon.erl | 418 ----------------------------- src/shared/struct/shr_armor.erl | 185 +++++++++++++ src/shared/struct/shr_attributes.erl | 135 ++++++++++ src/shared/struct/shr_db_item.erl | 80 ++++++ src/shared/struct/shr_db_query.erl | 214 +++++++++++++++ src/shared/struct/shr_db_user.erl | 31 +++ src/shared/struct/shr_statistics.erl | 200 ++++++++++++++ src/shared/struct/shr_weapon.erl | 418 +++++++++++++++++++++++++++++ src/shared/util/sh_array_util.erl | 152 ----------- src/shared/util/sh_math_util.erl | 30 --- src/shared/util/shr_array_util.erl | 152 +++++++++++ src/shared/util/shr_math_util.erl | 30 +++ 26 files changed, 1817 insertions(+), 1817 deletions(-) delete mode 100644 src/shared/io/sh_database.erl delete mode 100644 src/shared/io/sh_timed_cache.erl delete mode 100644 src/shared/io/sh_timed_caches_manager.erl create mode 100644 src/shared/io/shr_database.erl create mode 100644 src/shared/io/shr_timed_cache.erl create mode 100644 src/shared/io/shr_timed_caches_manager.erl delete mode 100644 src/shared/sh_roll.erl create mode 100644 src/shared/shr_roll.erl delete mode 100644 src/shared/struct/sh_armor.erl delete mode 100644 src/shared/struct/sh_attributes.erl delete mode 100644 src/shared/struct/sh_db_item.erl delete mode 100644 src/shared/struct/sh_db_query.erl delete mode 100644 src/shared/struct/sh_db_user.erl delete mode 100644 src/shared/struct/sh_statistics.erl delete mode 100644 src/shared/struct/sh_weapon.erl create mode 100644 src/shared/struct/shr_armor.erl create mode 100644 src/shared/struct/shr_attributes.erl create mode 100644 src/shared/struct/shr_db_item.erl create mode 100644 src/shared/struct/shr_db_query.erl create mode 100644 src/shared/struct/shr_db_user.erl create mode 100644 src/shared/struct/shr_statistics.erl create mode 100644 src/shared/struct/shr_weapon.erl delete mode 100644 src/shared/util/sh_array_util.erl delete mode 100644 src/shared/util/sh_math_util.erl create mode 100644 src/shared/util/shr_array_util.erl create mode 100644 src/shared/util/shr_math_util.erl (limited to 'src/shared') diff --git a/src/shared/io/sh_database.erl b/src/shared/io/sh_database.erl deleted file mode 100644 index 233e37d..0000000 --- a/src/shared/io/sh_database.erl +++ /dev/null @@ -1,58 +0,0 @@ --module(sh_database). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - insert/4, - fetch/2, - commit/1 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec get_db_node () -> node(). -get_db_node () -> list_to_atom("db_node@" ++ net_adm:localhost()). - --spec do_remote_operation (atom(), list(any())) -> - ( - {'badrpc', any()} - | {'aborted', any()} - | {'atomic', ({'ok', any()} | 'ok' | 'not_found')} - ). -do_remote_operation (Op, Params) -> - rpc:call(get_db_node(), db_access, Op, Params). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec insert (atom(), any(), sh_db_user:permission(), any()) -> 'ok'. -insert (DB, ObjectID, Permission, Value) -> - {atomic, _} = do_remote_operation(insert, [DB, ObjectID, Permission, Value]), - io:format - ( - "~nsh_database:insert(~p) -> ok.~n", - [{DB, ObjectID, Permission, Value}] - ), - - ok. - --spec fetch (atom(), any()) -> ({'ok', any()} | 'not_found'). -fetch (DB, ObjectID) -> - {atomic, Reply} = do_remote_operation(read, [DB, ObjectID]), - io:format("~nsh_database:fetch(~p) -> ~p.~n", [{DB, ObjectID}, Reply]), - Reply. - --spec commit (sh_db_query:type()) -> 'ok'. -commit (Query) -> - {atomic, ok} = do_remote_operation(query, [Query]), - io:format("~nsh_database:commit(~p) -> ok.~n", [Query]), - ok. diff --git a/src/shared/io/sh_timed_cache.erl b/src/shared/io/sh_timed_cache.erl deleted file mode 100644 index 6f3d973..0000000 --- a/src/shared/io/sh_timed_cache.erl +++ /dev/null @@ -1,130 +0,0 @@ --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} = 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}, sh_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 deleted file mode 100644 index ea92c08..0000000 --- a/src/shared/io/sh_timed_caches_manager.erl +++ /dev/null @@ -1,152 +0,0 @@ --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(?MODULE, [], []). - -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/io/shr_database.erl b/src/shared/io/shr_database.erl new file mode 100644 index 0000000..bffcb9f --- /dev/null +++ b/src/shared/io/shr_database.erl @@ -0,0 +1,58 @@ +-module(shr_database). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + insert/4, + fetch/2, + commit/1 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_db_node () -> node(). +get_db_node () -> list_to_atom("db_node@" ++ net_adm:localhost()). + +-spec do_remote_operation (atom(), list(any())) -> + ( + {'badrpc', any()} + | {'aborted', any()} + | {'atomic', ({'ok', any()} | 'ok' | 'not_found')} + ). +do_remote_operation (Op, Params) -> + rpc:call(get_db_node(), db_access, Op, Params). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec insert (atom(), any(), shr_db_user:permission(), any()) -> 'ok'. +insert (DB, ObjectID, Permission, Value) -> + {atomic, _} = do_remote_operation(insert, [DB, ObjectID, Permission, Value]), + io:format + ( + "~nshr_database:insert(~p) -> ok.~n", + [{DB, ObjectID, Permission, Value}] + ), + + ok. + +-spec fetch (atom(), any()) -> ({'ok', any()} | 'not_found'). +fetch (DB, ObjectID) -> + {atomic, Reply} = do_remote_operation(read, [DB, ObjectID]), + io:format("~nshr_database:fetch(~p) -> ~p.~n", [{DB, ObjectID}, Reply]), + Reply. + +-spec commit (shr_db_query:type()) -> 'ok'. +commit (Query) -> + {atomic, ok} = do_remote_operation(query, [Query]), + io:format("~nshr_database:commit(~p) -> ok.~n", [Query]), + ok. diff --git a/src/shared/io/shr_timed_cache.erl b/src/shared/io/shr_timed_cache.erl new file mode 100644 index 0000000..b89de48 --- /dev/null +++ b/src/shared/io/shr_timed_cache.erl @@ -0,0 +1,130 @@ +-module(shr_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} = shr_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}, shr_timed_caches_manager:get_timeout()}. + +handle_call (invalidate, _, State) -> + {stop, normal, State}; +handle_call (ping, _, State) -> + {noreply, State, shr_timed_caches_manager:get_timeout()}. + +handle_cast (invalidate, State) -> + {stop, normal, State}; +handle_cast (ping, State) -> + {noreply, State, shr_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}, shr_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/shr_timed_caches_manager.erl b/src/shared/io/shr_timed_caches_manager.erl new file mode 100644 index 0000000..8303cb8 --- /dev/null +++ b/src/shared/io/shr_timed_caches_manager.erl @@ -0,0 +1,152 @@ +-module(shr_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(?MODULE, [], []). + +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/sh_roll.erl b/src/shared/sh_roll.erl deleted file mode 100644 index f2212b1..0000000 --- a/src/shared/sh_roll.erl +++ /dev/null @@ -1,32 +0,0 @@ --module(sh_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/shared/shr_roll.erl b/src/shared/shr_roll.erl new file mode 100644 index 0000000..8e688c7 --- /dev/null +++ b/src/shared/shr_roll.erl @@ -0,0 +1,32 @@ +-module(shr_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/shared/struct/sh_armor.erl b/src/shared/struct/sh_armor.erl deleted file mode 100644 index cea2ce9..0000000 --- a/src/shared/struct/sh_armor.erl +++ /dev/null @@ -1,185 +0,0 @@ --module(sh_armor). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --opaque id() :: non_neg_integer(). - --type category() :: 'kinetic' | 'leather' | 'chain' | 'plate'. - --record -( - armor, - { - id :: id(), - name :: binary(), - category :: category(), - coef :: float() - } -). - --opaque type() :: #armor{}. - --export_type([type/0, id/0]). --export_type ([category/0]). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_name/1, - get_coefficient/1, - get_category/1 - ] -). - --export -( - [ - random_id/0, - from_id/1, - apply_to_attributes/2, - get_resistance_to/2 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_id (type()) -> id(). -get_id (Ar) -> Ar#armor.id. - --spec get_name (type()) -> binary(). -get_name (Ar) -> Ar#armor.name. - --spec get_coefficient (type()) -> float(). -get_coefficient (Ar) -> Ar#armor.coef. - --spec get_category (type()) -> category(). -get_category (Ar) -> Ar#armor.category. - --spec from_id (id()) -> type(). -from_id (0) -> - #armor{ - id = 0, - name = <<"None">>, - category = leather, - coef = 0.0 - }; -from_id (1) -> - #armor{ - id = 1, - name = <<"Last Meal's Pelts">>, - category = leather, - coef = 0.5 - }; -from_id (2) -> - #armor{ - id = 2, - name = <<"Bits of Wall">>, - category = plate, - coef = 0.5 - }; -from_id (3) -> - #armor{ - id = 3, - name = <<"Garden Fence">>, - category = chain, - coef = 0.5 - }; -from_id (4) -> - #armor{ - id = 4, - name = <<"Morrigan's Pity">>, - category = kinetic, - coef = 0.5 - }. - --spec random_id () -> id(). -random_id () -> sh_roll:between(0, 4). - --spec apply_to_attributes - ( - type(), - sh_attributes:type() - ) - -> sh_attributes:type(). -apply_to_attributes (Ar, Att) -> - Constitution = sh_attributes:get_constitution(Att), - Dexterity = sh_attributes:get_dexterity(Att), - Speed = sh_attributes:get_speed(Att), - Strength = sh_attributes:get_strength(Att), - Mind = sh_attributes:get_mind(Att), - Impact = sh_math_util:ceil(20.0 * Ar#armor.coef), - HalfImpact = sh_math_util:ceil(10.0 * Ar#armor.coef), - Category = Ar#armor.category, - - case Category of - kinetic -> sh_attributes:set_unsafe_mind((Mind - Impact), Att); - leather -> - sh_attributes:set_unsafe_constitution - ( - (Constitution - HalfImpact), - sh_attributes:set_unsafe_dexterity((Dexterity - HalfImpact), Att) - ); - - chain -> - sh_attributes:set_unsafe_constitution - ( - (Constitution - HalfImpact), - sh_attributes:set_unsafe_dexterity - ( - (Dexterity - HalfImpact), - sh_attributes:set_unsafe_speed((Speed - Impact), Att) - ) - ); - - plate -> - sh_attributes:set_unsafe_constitution - ( - (Constitution - HalfImpact), - sh_attributes:set_unsafe_dexterity - ( - (Dexterity - HalfImpact), - sh_attributes:set_unsafe_speed - ( - (Speed - Impact), - sh_attributes:set_unsafe_strength((Strength - Impact), Att) - ) - ) - ) - end. - --spec get_resistance_to (sh_weapon:damage_type(), type()) -> non_neg_integer(). -get_resistance_to (DamageType, Armor) -> - ArmorCategory = Armor#armor.category, - BaseResistance = - case {DamageType, ArmorCategory} of - {slash, kinetic} -> 0.0; - {slash, leather} -> 20.0; - {slash, chain} -> 30.0; - {slash, plate} -> 30.0; - {blunt, kinetic} -> 20.0; - {blunt, leather} -> 20.0; - {blunt, chain} -> 20.0; - {blunt, plate} -> 20.0; - {pierce, kinetic} -> 20.0; - {pierce, leather} -> 20.0; - {pierce, chain} -> 20.0; - {pierce, plate} -> 30.0 - end, - - ArmorCoefficient = Armor#armor.coef, - ActualResistance = (ArmorCoefficient * BaseResistance), - - sh_math_util:ceil(ActualResistance). diff --git a/src/shared/struct/sh_attributes.erl b/src/shared/struct/sh_attributes.erl deleted file mode 100644 index 9b4478f..0000000 --- a/src/shared/struct/sh_attributes.erl +++ /dev/null @@ -1,135 +0,0 @@ --module(sh_attributes). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - attributes, - { - constitution :: non_neg_integer(), - dexterity :: non_neg_integer(), - intelligence :: non_neg_integer(), - mind :: non_neg_integer(), - speed :: non_neg_integer(), - strength :: non_neg_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, - - set_unsafe_constitution/2, - set_unsafe_dexterity/2, - set_unsafe_intelligence/2, - set_unsafe_mind/2, - set_unsafe_speed/2, - set_unsafe_strength/2 - ] -). - -%%%% Accessors --export -( - [ - random/0 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec make_safe (integer()) -> non_neg_integer(). -make_safe (Val) -> max(0, min(100, Val)). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --spec get_constitution (type()) -> non_neg_integer(). -get_constitution (Att) -> Att#attributes.constitution. - --spec get_dexterity (type()) -> non_neg_integer(). -get_dexterity (Att) -> Att#attributes.dexterity. - --spec get_intelligence (type()) -> non_neg_integer(). -get_intelligence (Att) -> Att#attributes.intelligence. - --spec get_mind (type()) -> non_neg_integer(). -get_mind (Att) -> Att#attributes.mind. - --spec get_speed (type()) -> non_neg_integer(). -get_speed (Att) -> Att#attributes.speed. - --spec get_strength (type()) -> non_neg_integer(). -get_strength (Att) -> Att#attributes.strength. - --spec set_constitution (non_neg_integer(), type()) -> type(). -set_constitution (Val, Att) -> Att#attributes{ constitution = Val }. - --spec set_dexterity (non_neg_integer(), type()) -> type(). -set_dexterity (Val, Att) -> Att#attributes{ dexterity = Val }. - --spec set_intelligence (non_neg_integer(), type()) -> type(). -set_intelligence (Val, Att) -> Att#attributes{ intelligence = Val }. - --spec set_mind (non_neg_integer(), type()) -> type(). -set_mind (Val, Att) -> Att#attributes{ mind = Val }. - --spec set_speed (non_neg_integer(), type()) -> type(). -set_speed (Val, Att) -> Att#attributes{ speed = Val }. - --spec set_strength (non_neg_integer(), type()) -> type(). -set_strength (Val, Att) -> Att#attributes{ strength = Val }. - --spec set_unsafe_constitution (integer(), type()) -> type(). -set_unsafe_constitution (Val, Att) -> set_constitution(make_safe(Val), Att). - --spec set_unsafe_dexterity (integer(), type()) -> type(). -set_unsafe_dexterity (Val, Att) -> set_dexterity(make_safe(Val), Att). - --spec set_unsafe_intelligence (integer(), type()) -> type(). -set_unsafe_intelligence (Val, Att) -> set_intelligence(make_safe(Val), Att). - --spec set_unsafe_mind (integer(), type()) -> type(). -set_unsafe_mind (Val, Att) -> set_mind(make_safe(Val), Att). - --spec set_unsafe_speed (integer(), type()) -> type(). -set_unsafe_speed (Val, Att) -> set_speed(make_safe(Val), Att). - --spec set_unsafe_strength (integer(), type()) -> type(). -set_unsafe_strength (Val, Att) -> set_strength(make_safe(Val), Att). - --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 deleted file mode 100644 index 3692a88..0000000 --- a/src/shared/struct/sh_db_item.erl +++ /dev/null @@ -1,80 +0,0 @@ --module(sh_db_item). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( - db_item, - { - id :: any(), - perm :: sh_db_user:permission(), - val :: any() - } -). - --type db_item() :: #db_item{}. - --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(), sh_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()) -> sh_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 (sh_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 deleted file mode 100644 index 47d85d6..0000000 --- a/src/shared/struct/sh_db_query.erl +++ /dev/null @@ -1,214 +0,0 @@ --module(sh_db_query). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 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 :: sh_db_user:permission() - } -). - --record -( - set_val, - { - val :: any() - } -). - --record -( - db_query, - { - db :: atom(), - id :: any(), - user :: sh_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{}. - --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/3, - update_indexed/3 - ] -). --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(), - sh_db_item:type() - ) - -> sh_db_item:type(). -apply_master_op_to (MOp, Elem) when is_record(MOp, set_perm) -> - NewPerm = MOp#set_perm.perm, - - sh_db_item:set_permission(NewPerm, Elem); -apply_master_op_to (MOp, Elem) when is_record(MOp, set_val) -> - NewVal = MOp#set_val.val, - - sh_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), - - sh_db_item:set_value(NewValue, Elem). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% 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()), boolean()) -> op(). -add_to_field (Field, Values, IsPrefix) -> - #add_to_field { field = Field, values = Values, head = IsPrefix}. - --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}. - --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(), - sh_db_item:type() - ) - -> ({'ok', sh_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/struct/sh_db_user.erl b/src/shared/struct/sh_db_user.erl deleted file mode 100644 index f2d4dfe..0000000 --- a/src/shared/struct/sh_db_user.erl +++ /dev/null @@ -1,31 +0,0 @@ --module(sh_db_user). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type db_named_user() :: {'user', any()}. --type db_user() :: (db_named_user() | 'admin' | 'any'). --type db_permission() :: (list(db_named_user()) | 'any'). - - --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 deleted file mode 100644 index 497cf41..0000000 --- a/src/shared/struct/sh_statistics.erl +++ /dev/null @@ -1,200 +0,0 @@ --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/3 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec float_to_int (float()) -> integer(). -float_to_int (F) -> - I = trunc(F), - case (F > I) of - true -> (I + 1); - _ -> I - end. - --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.0). - -% 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.0). - -% 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.0, V / 25.0)). - -% 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 - ( - sh_attributes:type(), - {sh_weapon:id(), sh_weapon:id()}, - sh_armor:id() - ) - -> type(). -new (BaseAttributes, WeaponIDs, ArmorID) -> - {ActiveWeaponID, _} = WeaponIDs, - ActiveWeapon = sh_weapon:from_id(ActiveWeaponID), - {MinDamage, MaxDamage} = sh_weapon:get_damages(ActiveWeapon), - Armor = sh_armor:from_id(ArmorID), - Attributes = - sh_armor:apply_to_attributes - ( - Armor, - sh_weapon:apply_to_attributes(ActiveWeapon, BaseAttributes) - ), - Constitution = sh_attributes:get_constitution(Attributes), - Dexterity = sh_attributes:get_dexterity(Attributes), - Intelligence = sh_attributes:get_intelligence(Attributes), - Mind = sh_attributes:get_mind(Attributes), - Speed = sh_attributes:get_speed(Attributes), - Strength = sh_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([Constitution, Constitution, Constitution, Mind]) - ), - 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/shared/struct/sh_weapon.erl b/src/shared/struct/sh_weapon.erl deleted file mode 100644 index 74c7a42..0000000 --- a/src/shared/struct/sh_weapon.erl +++ /dev/null @@ -1,418 +0,0 @@ --module(sh_weapon). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --opaque id() :: non_neg_integer(). - --type range_type() :: 'ranged' | 'melee'. --type range_modifier() :: 'long' | 'short'. --type damage_type() :: 'slash' | 'pierce' | 'blunt'. --type damage_modifier() :: 'heavy' | 'light'. - --record -( - weapon, - { - id :: id(), - name :: binary(), - range_type :: range_type(), - range_mod :: range_modifier(), - damage_type :: damage_type(), - damage_mod :: damage_modifier(), - coef :: float() - } -). - --opaque type() :: #weapon{}. - --export_type([type/0, id/0]). --export_type -( - [ - range_type/0, - range_modifier/0, - damage_type/0, - damage_modifier/0 - ] -). - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%% Accessors --export -( - [ - get_id/1, - get_name/1, - get_range_type/1, - get_range_modifier/1, - get_damage_type/1, - get_damage_modifier/1, - get_coefficient/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_modifier() - ) - -> {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_modifier() - ) - -> {non_neg_integer(), non_neg_integer()}. -damages_of_type (ranged, heavy) -> {15, 30}; -damages_of_type (ranged, light) -> {10, 25}; -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_name (type()) -> binary(). -get_name (Wp) -> Wp#weapon.name. - --spec get_range_type (type()) -> range_type(). -get_range_type (Wp) -> Wp#weapon.range_type. - --spec get_range_modifier (type()) -> range_modifier(). -get_range_modifier (Wp) -> Wp#weapon.range_mod. - --spec get_damage_type (type()) -> damage_type(). -get_damage_type (Wp) -> Wp#weapon.damage_type. - --spec get_damage_modifier (type()) -> damage_modifier(). -get_damage_modifier (Wp) -> Wp#weapon.damage_mod. - --spec get_coefficient (type()) -> float(). -get_coefficient (Wp) -> Wp#weapon.coef. - --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) -> - Coef = Wp#weapon.coef, - {Min, Max} = damages_of_type(Wp#weapon.range_type, Wp#weapon.damage_mod), - {sh_math_util:ceil(Min * Coef), sh_math_util:ceil(Max * Coef)}. - --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, - coef = 0.3 - }; -from_id (1) -> - #weapon{ - id = 1, - name = <<"Dagger">>, - range_type = melee, - range_mod = short, - damage_type = slash, - damage_mod = light, - coef = 1.0 - }; -from_id (2) -> - #weapon{ - id = 2, - name = <<"Sword">>, - range_type = melee, - range_mod = short, - damage_type = slash, - damage_mod = heavy, - coef = 1.0 - }; -from_id (3) -> - #weapon{ - id = 3, - name = <<"Claymore">>, - range_type = melee, - range_mod = long, - damage_type = slash, - damage_mod = light, - coef = 1.0 - }; -from_id (4) -> - #weapon{ - id = 4, - name = <<"Bardiche">>, - range_type = melee, - range_mod = long, - damage_type = slash, - damage_mod = heavy, - coef = 1.0 - }; -from_id (5) -> - #weapon{ - id = 5, - name = <<"Stiletto">>, - range_type = melee, - range_mod = short, - damage_type = pierce, - damage_mod = light, - coef = 1.0 - }; -from_id (6) -> - #weapon{ - id = 6, - name = <<"Pickaxe">>, - range_type = melee, - range_mod = short, - damage_type = pierce, - damage_mod = heavy, - coef = 1.0 - }; -from_id (7) -> - #weapon{ - id = 7, - name = <<"Rapier">>, - range_type = melee, - range_mod = long, - damage_type = pierce, - damage_mod = light, - coef = 1.0 - }; -from_id (8) -> - #weapon{ - id = 8, - name = <<"Pike">>, - range_type = melee, - range_mod = long, - damage_type = pierce, - damage_mod = heavy, - coef = 1.0 - }; -from_id (9) -> - #weapon{ - id = 9, - name = <<"Club">>, - range_type = melee, - range_mod = short, - damage_type = blunt, - damage_mod = light, - coef = 1.0 - }; -from_id (10) -> - #weapon{ - id = 10, - name = <<"Mace">>, - range_type = melee, - range_mod = short, - damage_type = blunt, - damage_mod = heavy, - coef = 1.0 - }; -from_id (11) -> - #weapon{ - id = 11, - name = <<"Staff">>, - range_type = melee, - range_mod = long, - damage_type = blunt, - damage_mod = light, - coef = 1.0 - }; -from_id (12) -> - #weapon{ - id = 12, - name = <<"War Hammer">>, - range_type = melee, - range_mod = long, - damage_type = blunt, - damage_mod = heavy, - coef = 1.0 - }; -from_id (13) -> - #weapon{ - id = 13, - name = <<"Short Bow (Broadhead)">>, - range_type = ranged, - range_mod = short, - damage_type = slash, - damage_mod = light, - coef = 1.0 - }; -from_id (14) -> - #weapon{ - id = 14, - name = <<"Short Bow (Blunt)">>, - range_type = ranged, - range_mod = short, - damage_type = blunt, - damage_mod = light, - coef = 1.0 - }; -from_id (15) -> - #weapon{ - id = 15, - name = <<"Short Bow (Bodkin Point)">>, - range_type = ranged, - range_mod = short, - damage_type = pierce, - damage_mod = light, - coef = 1.0 - }; -from_id (16) -> - #weapon{ - id = 16, - name = <<"Long Bow (Broadhead)">>, - range_type = ranged, - range_mod = long, - damage_type = slash, - damage_mod = light, - coef = 1.0 - }; -from_id (17) -> - #weapon{ - id = 17, - name = <<"Long Bow (Blunt)">>, - range_type = ranged, - range_mod = long, - damage_type = blunt, - damage_mod = light, - coef = 1.0 - }; -from_id (18) -> - #weapon{ - id = 18, - name = <<"Long Bow (Bodkin Point)">>, - range_type = ranged, - range_mod = long, - damage_type = pierce, - damage_mod = light, - coef = 1.0 - }; -from_id (19) -> - #weapon{ - id = 19, - name = <<"Crossbow (Broadhead)">>, - range_type = ranged, - range_mod = short, - damage_type = slash, - damage_mod = heavy, - coef = 1.0 - }; -from_id (20) -> - #weapon{ - id = 20, - name = <<"Crossbow (Blunt)">>, - range_type = ranged, - range_mod = short, - damage_type = blunt, - damage_mod = heavy, - coef = 1.0 - }; -from_id (21) -> - #weapon{ - id = 21, - name = <<"Crossbow (Bodkin Point)">>, - range_type = ranged, - range_mod = short, - damage_type = pierce, - damage_mod = heavy, - coef = 1.0 - }; -from_id (22) -> - #weapon{ - id = 22, - name = <<"Arbalest (Broadhead)">>, - range_type = ranged, - range_mod = long, - damage_type = slash, - damage_mod = heavy, - coef = 1.0 - }; -from_id (23) -> - #weapon{ - id = 23, - name = <<"Arbalest (Blunt)">>, - range_type = ranged, - range_mod = long, - damage_type = blunt, - damage_mod = heavy, - coef = 1.0 - }; -from_id (24) -> - #weapon{ - id = 24, - name = <<"Arbalest (Bodkin Point)">>, - range_type = ranged, - range_mod = long, - damage_type = pierce, - damage_mod = heavy, - coef = 1.0 - }. - --spec random_id () -> id(). -random_id () -> sh_roll:between(0, 24). - --spec apply_to_attributes - ( - type(), - sh_attributes:type() - ) - -> sh_attributes:type(). -apply_to_attributes (Weapon, Attributes) -> - Dexterity = sh_attributes:get_dexterity(Attributes), - Speed = sh_attributes:get_speed(Attributes), - RangeModifier = Weapon#weapon.range_mod, - DamageModifier = Weapon#weapon.damage_mod, - - Impact = (20.0 * Weapon#weapon.coef), - FullImpact = sh_math_util:ceil(Impact), - QuarterImpact = sh_math_util:ceil(Impact / 4.0), - - ResultingDexterity = - case RangeModifier of - long -> (Dexterity - FullImpact); - short -> (Dexterity - QuarterImpact) - end, - ResultingSpeed = - case DamageModifier of - heavy -> (Speed - FullImpact); - light -> (Speed - QuarterImpact) - end, - - S0Attributes = sh_attributes:set_unsafe_speed(ResultingSpeed, Attributes), - S1Attributes = - sh_attributes:set_unsafe_dexterity(ResultingDexterity, S0Attributes), - - S1Attributes. diff --git a/src/shared/struct/shr_armor.erl b/src/shared/struct/shr_armor.erl new file mode 100644 index 0000000..65445ca --- /dev/null +++ b/src/shared/struct/shr_armor.erl @@ -0,0 +1,185 @@ +-module(shr_armor). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-opaque id() :: non_neg_integer(). + +-type category() :: 'kinetic' | 'leather' | 'chain' | 'plate'. + +-record +( + armor, + { + id :: id(), + name :: binary(), + category :: category(), + coef :: float() + } +). + +-opaque type() :: #armor{}. + +-export_type([type/0, id/0]). +-export_type ([category/0]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_name/1, + get_coefficient/1, + get_category/1 + ] +). + +-export +( + [ + random_id/0, + from_id/1, + apply_to_attributes/2, + get_resistance_to/2 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Ar) -> Ar#armor.id. + +-spec get_name (type()) -> binary(). +get_name (Ar) -> Ar#armor.name. + +-spec get_coefficient (type()) -> float(). +get_coefficient (Ar) -> Ar#armor.coef. + +-spec get_category (type()) -> category(). +get_category (Ar) -> Ar#armor.category. + +-spec from_id (id()) -> type(). +from_id (0) -> + #armor{ + id = 0, + name = <<"None">>, + category = leather, + coef = 0.0 + }; +from_id (1) -> + #armor{ + id = 1, + name = <<"Last Meal's Pelts">>, + category = leather, + coef = 0.5 + }; +from_id (2) -> + #armor{ + id = 2, + name = <<"Bits of Wall">>, + category = plate, + coef = 0.5 + }; +from_id (3) -> + #armor{ + id = 3, + name = <<"Garden Fence">>, + category = chain, + coef = 0.5 + }; +from_id (4) -> + #armor{ + id = 4, + name = <<"Morrigan's Pity">>, + category = kinetic, + coef = 0.5 + }. + +-spec random_id () -> id(). +random_id () -> shr_roll:between(0, 4). + +-spec apply_to_attributes + ( + type(), + shr_attributes:type() + ) + -> shr_attributes:type(). +apply_to_attributes (Ar, Att) -> + Constitution = shr_attributes:get_constitution(Att), + Dexterity = shr_attributes:get_dexterity(Att), + Speed = shr_attributes:get_speed(Att), + Strength = shr_attributes:get_strength(Att), + Mind = shr_attributes:get_mind(Att), + Impact = shr_math_util:ceil(20.0 * Ar#armor.coef), + HalfImpact = shr_math_util:ceil(10.0 * Ar#armor.coef), + Category = Ar#armor.category, + + case Category of + kinetic -> shr_attributes:set_unsafe_mind((Mind - Impact), Att); + leather -> + shr_attributes:set_unsafe_constitution + ( + (Constitution - HalfImpact), + shr_attributes:set_unsafe_dexterity((Dexterity - HalfImpact), Att) + ); + + chain -> + shr_attributes:set_unsafe_constitution + ( + (Constitution - HalfImpact), + shr_attributes:set_unsafe_dexterity + ( + (Dexterity - HalfImpact), + shr_attributes:set_unsafe_speed((Speed - Impact), Att) + ) + ); + + plate -> + shr_attributes:set_unsafe_constitution + ( + (Constitution - HalfImpact), + shr_attributes:set_unsafe_dexterity + ( + (Dexterity - HalfImpact), + shr_attributes:set_unsafe_speed + ( + (Speed - Impact), + shr_attributes:set_unsafe_strength((Strength - Impact), Att) + ) + ) + ) + end. + +-spec get_resistance_to (shr_weapon:damage_type(), type()) -> non_neg_integer(). +get_resistance_to (DamageType, Armor) -> + ArmorCategory = Armor#armor.category, + BaseResistance = + case {DamageType, ArmorCategory} of + {slash, kinetic} -> 0.0; + {slash, leather} -> 20.0; + {slash, chain} -> 30.0; + {slash, plate} -> 30.0; + {blunt, kinetic} -> 20.0; + {blunt, leather} -> 20.0; + {blunt, chain} -> 20.0; + {blunt, plate} -> 20.0; + {pierce, kinetic} -> 20.0; + {pierce, leather} -> 20.0; + {pierce, chain} -> 20.0; + {pierce, plate} -> 30.0 + end, + + ArmorCoefficient = Armor#armor.coef, + ActualResistance = (ArmorCoefficient * BaseResistance), + + shr_math_util:ceil(ActualResistance). diff --git a/src/shared/struct/shr_attributes.erl b/src/shared/struct/shr_attributes.erl new file mode 100644 index 0000000..23824e4 --- /dev/null +++ b/src/shared/struct/shr_attributes.erl @@ -0,0 +1,135 @@ +-module(shr_attributes). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + attributes, + { + constitution :: non_neg_integer(), + dexterity :: non_neg_integer(), + intelligence :: non_neg_integer(), + mind :: non_neg_integer(), + speed :: non_neg_integer(), + strength :: non_neg_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, + + set_unsafe_constitution/2, + set_unsafe_dexterity/2, + set_unsafe_intelligence/2, + set_unsafe_mind/2, + set_unsafe_speed/2, + set_unsafe_strength/2 + ] +). + +%%%% Accessors +-export +( + [ + random/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec make_safe (integer()) -> non_neg_integer(). +make_safe (Val) -> max(0, min(100, Val)). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_constitution (type()) -> non_neg_integer(). +get_constitution (Att) -> Att#attributes.constitution. + +-spec get_dexterity (type()) -> non_neg_integer(). +get_dexterity (Att) -> Att#attributes.dexterity. + +-spec get_intelligence (type()) -> non_neg_integer(). +get_intelligence (Att) -> Att#attributes.intelligence. + +-spec get_mind (type()) -> non_neg_integer(). +get_mind (Att) -> Att#attributes.mind. + +-spec get_speed (type()) -> non_neg_integer(). +get_speed (Att) -> Att#attributes.speed. + +-spec get_strength (type()) -> non_neg_integer(). +get_strength (Att) -> Att#attributes.strength. + +-spec set_constitution (non_neg_integer(), type()) -> type(). +set_constitution (Val, Att) -> Att#attributes{ constitution = Val }. + +-spec set_dexterity (non_neg_integer(), type()) -> type(). +set_dexterity (Val, Att) -> Att#attributes{ dexterity = Val }. + +-spec set_intelligence (non_neg_integer(), type()) -> type(). +set_intelligence (Val, Att) -> Att#attributes{ intelligence = Val }. + +-spec set_mind (non_neg_integer(), type()) -> type(). +set_mind (Val, Att) -> Att#attributes{ mind = Val }. + +-spec set_speed (non_neg_integer(), type()) -> type(). +set_speed (Val, Att) -> Att#attributes{ speed = Val }. + +-spec set_strength (non_neg_integer(), type()) -> type(). +set_strength (Val, Att) -> Att#attributes{ strength = Val }. + +-spec set_unsafe_constitution (integer(), type()) -> type(). +set_unsafe_constitution (Val, Att) -> set_constitution(make_safe(Val), Att). + +-spec set_unsafe_dexterity (integer(), type()) -> type(). +set_unsafe_dexterity (Val, Att) -> set_dexterity(make_safe(Val), Att). + +-spec set_unsafe_intelligence (integer(), type()) -> type(). +set_unsafe_intelligence (Val, Att) -> set_intelligence(make_safe(Val), Att). + +-spec set_unsafe_mind (integer(), type()) -> type(). +set_unsafe_mind (Val, Att) -> set_mind(make_safe(Val), Att). + +-spec set_unsafe_speed (integer(), type()) -> type(). +set_unsafe_speed (Val, Att) -> set_speed(make_safe(Val), Att). + +-spec set_unsafe_strength (integer(), type()) -> type(). +set_unsafe_strength (Val, Att) -> set_strength(make_safe(Val), Att). + +-spec random () -> type(). +random () -> + #attributes + { + constitution = shr_roll:percentage(), + dexterity = shr_roll:percentage(), + intelligence = shr_roll:percentage(), + mind = shr_roll:percentage(), + speed = shr_roll:percentage(), + strength = shr_roll:percentage() + }. diff --git a/src/shared/struct/shr_db_item.erl b/src/shared/struct/shr_db_item.erl new file mode 100644 index 0000000..546462e --- /dev/null +++ b/src/shared/struct/shr_db_item.erl @@ -0,0 +1,80 @@ +-module(shr_db_item). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-record +( + db_item, + { + id :: any(), + perm :: shr_db_user:permission(), + val :: any() + } +). + +-type db_item() :: #db_item{}. + +-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(), shr_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()) -> shr_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 (shr_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/shr_db_query.erl b/src/shared/struct/shr_db_query.erl new file mode 100644 index 0000000..284cc2c --- /dev/null +++ b/src/shared/struct/shr_db_query.erl @@ -0,0 +1,214 @@ +-module(shr_db_query). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% 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 :: shr_db_user:permission() + } +). + +-record +( + set_val, + { + val :: any() + } +). + +-record +( + db_query, + { + db :: atom(), + id :: any(), + user :: shr_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{}. + +-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/3, + update_indexed/3 + ] +). +-export +( + [ + get_database/1, + get_entry_id/1 + ] +). +-export([apply_to/2]). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_user (db_query()) -> shr_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(), + shr_db_item:type() + ) + -> shr_db_item:type(). +apply_master_op_to (MOp, Elem) when is_record(MOp, set_perm) -> + NewPerm = MOp#set_perm.perm, + + shr_db_item:set_permission(NewPerm, Elem); +apply_master_op_to (MOp, Elem) when is_record(MOp, set_val) -> + NewVal = MOp#set_val.val, + + shr_db_item:set_value(NewVal, Elem); +apply_master_op_to (MOp, Elem) -> + OldValue = shr_db_item:get_value(Elem), + NewValue = apply_op_to(MOp, OldValue), + + shr_db_item:set_value(NewValue, Elem). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec new (atom(), any(), shr_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()), boolean()) -> op(). +add_to_field (Field, Values, IsPrefix) -> + #add_to_field { field = Field, values = Values, head = IsPrefix}. + +-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}. + +-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(), + shr_db_item:type() + ) + -> ({'ok', shr_db_item:type()} | 'error'). +apply_to (DBQuery, DBItem) -> + true = + shr_db_user:can_access + ( + shr_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/struct/shr_db_user.erl b/src/shared/struct/shr_db_user.erl new file mode 100644 index 0000000..01840e2 --- /dev/null +++ b/src/shared/struct/shr_db_user.erl @@ -0,0 +1,31 @@ +-module(shr_db_user). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type db_named_user() :: {'user', any()}. +-type db_user() :: (db_named_user() | 'admin' | 'any'). +-type db_permission() :: (list(db_named_user()) | 'any'). + + +-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/shr_statistics.erl b/src/shared/struct/shr_statistics.erl new file mode 100644 index 0000000..cf48d96 --- /dev/null +++ b/src/shared/struct/shr_statistics.erl @@ -0,0 +1,200 @@ +-module(shr_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/3 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec float_to_int (float()) -> integer(). +float_to_int (F) -> + I = trunc(F), + case (F > I) of + true -> (I + 1); + _ -> I + end. + +-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.0). + +% 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.0). + +% 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.0, V / 25.0)). + +% 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 + ( + shr_attributes:type(), + {shr_weapon:id(), shr_weapon:id()}, + shr_armor:id() + ) + -> type(). +new (BaseAttributes, WeaponIDs, ArmorID) -> + {ActiveWeaponID, _} = WeaponIDs, + ActiveWeapon = shr_weapon:from_id(ActiveWeaponID), + {MinDamage, MaxDamage} = shr_weapon:get_damages(ActiveWeapon), + Armor = shr_armor:from_id(ArmorID), + Attributes = + shr_armor:apply_to_attributes + ( + Armor, + shr_weapon:apply_to_attributes(ActiveWeapon, BaseAttributes) + ), + Constitution = shr_attributes:get_constitution(Attributes), + Dexterity = shr_attributes:get_dexterity(Attributes), + Intelligence = shr_attributes:get_intelligence(Attributes), + Mind = shr_attributes:get_mind(Attributes), + Speed = shr_attributes:get_speed(Attributes), + Strength = shr_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([Constitution, Constitution, Constitution, Mind]) + ), + 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/shared/struct/shr_weapon.erl b/src/shared/struct/shr_weapon.erl new file mode 100644 index 0000000..3ecb749 --- /dev/null +++ b/src/shared/struct/shr_weapon.erl @@ -0,0 +1,418 @@ +-module(shr_weapon). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-opaque id() :: non_neg_integer(). + +-type range_type() :: 'ranged' | 'melee'. +-type range_modifier() :: 'long' | 'short'. +-type damage_type() :: 'slash' | 'pierce' | 'blunt'. +-type damage_modifier() :: 'heavy' | 'light'. + +-record +( + weapon, + { + id :: id(), + name :: binary(), + range_type :: range_type(), + range_mod :: range_modifier(), + damage_type :: damage_type(), + damage_mod :: damage_modifier(), + coef :: float() + } +). + +-opaque type() :: #weapon{}. + +-export_type([type/0, id/0]). +-export_type +( + [ + range_type/0, + range_modifier/0, + damage_type/0, + damage_modifier/0 + ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( + [ + get_id/1, + get_name/1, + get_range_type/1, + get_range_modifier/1, + get_damage_type/1, + get_damage_modifier/1, + get_coefficient/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_modifier() + ) + -> {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_modifier() + ) + -> {non_neg_integer(), non_neg_integer()}. +damages_of_type (ranged, heavy) -> {15, 30}; +damages_of_type (ranged, light) -> {10, 25}; +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_name (type()) -> binary(). +get_name (Wp) -> Wp#weapon.name. + +-spec get_range_type (type()) -> range_type(). +get_range_type (Wp) -> Wp#weapon.range_type. + +-spec get_range_modifier (type()) -> range_modifier(). +get_range_modifier (Wp) -> Wp#weapon.range_mod. + +-spec get_damage_type (type()) -> damage_type(). +get_damage_type (Wp) -> Wp#weapon.damage_type. + +-spec get_damage_modifier (type()) -> damage_modifier(). +get_damage_modifier (Wp) -> Wp#weapon.damage_mod. + +-spec get_coefficient (type()) -> float(). +get_coefficient (Wp) -> Wp#weapon.coef. + +-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) -> + Coef = Wp#weapon.coef, + {Min, Max} = damages_of_type(Wp#weapon.range_type, Wp#weapon.damage_mod), + {shr_math_util:ceil(Min * Coef), shr_math_util:ceil(Max * Coef)}. + +-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, + coef = 0.3 + }; +from_id (1) -> + #weapon{ + id = 1, + name = <<"Dagger">>, + range_type = melee, + range_mod = short, + damage_type = slash, + damage_mod = light, + coef = 1.0 + }; +from_id (2) -> + #weapon{ + id = 2, + name = <<"Sword">>, + range_type = melee, + range_mod = short, + damage_type = slash, + damage_mod = heavy, + coef = 1.0 + }; +from_id (3) -> + #weapon{ + id = 3, + name = <<"Claymore">>, + range_type = melee, + range_mod = long, + damage_type = slash, + damage_mod = light, + coef = 1.0 + }; +from_id (4) -> + #weapon{ + id = 4, + name = <<"Bardiche">>, + range_type = melee, + range_mod = long, + damage_type = slash, + damage_mod = heavy, + coef = 1.0 + }; +from_id (5) -> + #weapon{ + id = 5, + name = <<"Stiletto">>, + range_type = melee, + range_mod = short, + damage_type = pierce, + damage_mod = light, + coef = 1.0 + }; +from_id (6) -> + #weapon{ + id = 6, + name = <<"Pickaxe">>, + range_type = melee, + range_mod = short, + damage_type = pierce, + damage_mod = heavy, + coef = 1.0 + }; +from_id (7) -> + #weapon{ + id = 7, + name = <<"Rapier">>, + range_type = melee, + range_mod = long, + damage_type = pierce, + damage_mod = light, + coef = 1.0 + }; +from_id (8) -> + #weapon{ + id = 8, + name = <<"Pike">>, + range_type = melee, + range_mod = long, + damage_type = pierce, + damage_mod = heavy, + coef = 1.0 + }; +from_id (9) -> + #weapon{ + id = 9, + name = <<"Club">>, + range_type = melee, + range_mod = short, + damage_type = blunt, + damage_mod = light, + coef = 1.0 + }; +from_id (10) -> + #weapon{ + id = 10, + name = <<"Mace">>, + range_type = melee, + range_mod = short, + damage_type = blunt, + damage_mod = heavy, + coef = 1.0 + }; +from_id (11) -> + #weapon{ + id = 11, + name = <<"Staff">>, + range_type = melee, + range_mod = long, + damage_type = blunt, + damage_mod = light, + coef = 1.0 + }; +from_id (12) -> + #weapon{ + id = 12, + name = <<"War Hammer">>, + range_type = melee, + range_mod = long, + damage_type = blunt, + damage_mod = heavy, + coef = 1.0 + }; +from_id (13) -> + #weapon{ + id = 13, + name = <<"Short Bow (Broadhead)">>, + range_type = ranged, + range_mod = short, + damage_type = slash, + damage_mod = light, + coef = 1.0 + }; +from_id (14) -> + #weapon{ + id = 14, + name = <<"Short Bow (Blunt)">>, + range_type = ranged, + range_mod = short, + damage_type = blunt, + damage_mod = light, + coef = 1.0 + }; +from_id (15) -> + #weapon{ + id = 15, + name = <<"Short Bow (Bodkin Point)">>, + range_type = ranged, + range_mod = short, + damage_type = pierce, + damage_mod = light, + coef = 1.0 + }; +from_id (16) -> + #weapon{ + id = 16, + name = <<"Long Bow (Broadhead)">>, + range_type = ranged, + range_mod = long, + damage_type = slash, + damage_mod = light, + coef = 1.0 + }; +from_id (17) -> + #weapon{ + id = 17, + name = <<"Long Bow (Blunt)">>, + range_type = ranged, + range_mod = long, + damage_type = blunt, + damage_mod = light, + coef = 1.0 + }; +from_id (18) -> + #weapon{ + id = 18, + name = <<"Long Bow (Bodkin Point)">>, + range_type = ranged, + range_mod = long, + damage_type = pierce, + damage_mod = light, + coef = 1.0 + }; +from_id (19) -> + #weapon{ + id = 19, + name = <<"Crossbow (Broadhead)">>, + range_type = ranged, + range_mod = short, + damage_type = slash, + damage_mod = heavy, + coef = 1.0 + }; +from_id (20) -> + #weapon{ + id = 20, + name = <<"Crossbow (Blunt)">>, + range_type = ranged, + range_mod = short, + damage_type = blunt, + damage_mod = heavy, + coef = 1.0 + }; +from_id (21) -> + #weapon{ + id = 21, + name = <<"Crossbow (Bodkin Point)">>, + range_type = ranged, + range_mod = short, + damage_type = pierce, + damage_mod = heavy, + coef = 1.0 + }; +from_id (22) -> + #weapon{ + id = 22, + name = <<"Arbalest (Broadhead)">>, + range_type = ranged, + range_mod = long, + damage_type = slash, + damage_mod = heavy, + coef = 1.0 + }; +from_id (23) -> + #weapon{ + id = 23, + name = <<"Arbalest (Blunt)">>, + range_type = ranged, + range_mod = long, + damage_type = blunt, + damage_mod = heavy, + coef = 1.0 + }; +from_id (24) -> + #weapon{ + id = 24, + name = <<"Arbalest (Bodkin Point)">>, + range_type = ranged, + range_mod = long, + damage_type = pierce, + damage_mod = heavy, + coef = 1.0 + }. + +-spec random_id () -> id(). +random_id () -> shr_roll:between(0, 24). + +-spec apply_to_attributes + ( + type(), + shr_attributes:type() + ) + -> shr_attributes:type(). +apply_to_attributes (Weapon, Attributes) -> + Dexterity = shr_attributes:get_dexterity(Attributes), + Speed = shr_attributes:get_speed(Attributes), + RangeModifier = Weapon#weapon.range_mod, + DamageModifier = Weapon#weapon.damage_mod, + + Impact = (20.0 * Weapon#weapon.coef), + FullImpact = shr_math_util:ceil(Impact), + QuarterImpact = shr_math_util:ceil(Impact / 4.0), + + ResultingDexterity = + case RangeModifier of + long -> (Dexterity - FullImpact); + short -> (Dexterity - QuarterImpact) + end, + ResultingSpeed = + case DamageModifier of + heavy -> (Speed - FullImpact); + light -> (Speed - QuarterImpact) + end, + + S0Attributes = shr_attributes:set_unsafe_speed(ResultingSpeed, Attributes), + S1Attributes = + shr_attributes:set_unsafe_dexterity(ResultingDexterity, S0Attributes), + + S1Attributes. diff --git a/src/shared/util/sh_array_util.erl b/src/shared/util/sh_array_util.erl deleted file mode 100644 index 6d976bc..0000000 --- a/src/shared/util/sh_array_util.erl +++ /dev/null @@ -1,152 +0,0 @@ --module(sh_array_util). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - any/2, - any_indexed/2, - none/2, - all/2, - - first/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 first_internals - ( - fun((any()) -> boolean()), - array:array(any()), - non_neg_integer() - ) - -> integer(). -first_internals (_, _, 0) -> - -1; -first_internals (Fun, Array, PrevIX) -> - IX = (PrevIX - 1), - case Fun(array:get(IX, Array)) of - true -> IX; - _ -> first_internals(Fun, Array, IX) - end. - --spec any_indexed_internals - ( - fun((non_neg_integer(), any()) -> boolean()), - array:array(any()), - non_neg_integer() - ) - -> boolean(). -any_indexed_internals (_, _, 0) -> - false; -any_indexed_internals (Fun, Array, PrevIX) -> - IX = (PrevIX - 1), - case Fun(IX, array:get(IX, Array)) of - true -> true; - _ -> any_indexed_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 first (fun((any()) -> boolean()), array:array(any())) -> integer(). -first (Fun, Array) -> - first_internals(Fun, Array, array:size(Array)). - --spec any_indexed - ( - fun((non_neg_integer(), any()) -> boolean()), - array:array(any()) - ) -> boolean(). -any_indexed (Fun, Array) -> - any_indexed_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/shared/util/sh_math_util.erl b/src/shared/util/sh_math_util.erl deleted file mode 100644 index b2e2109..0000000 --- a/src/shared/util/sh_math_util.erl +++ /dev/null @@ -1,30 +0,0 @@ --module(sh_math_util). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export -( - [ - % Somehow, erlang:ceil is not defined on 2 out of my 4 dev computers. - ceil/1 - ] -). -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec ceil (float()) -> integer(). -ceil (Float) -> - Int = trunc(Float), - - case (Int /= Float) of - true -> (Int + 1); - _ -> Int - end. diff --git a/src/shared/util/shr_array_util.erl b/src/shared/util/shr_array_util.erl new file mode 100644 index 0000000..0faff99 --- /dev/null +++ b/src/shared/util/shr_array_util.erl @@ -0,0 +1,152 @@ +-module(shr_array_util). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + any/2, + any_indexed/2, + none/2, + all/2, + + first/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 first_internals + ( + fun((any()) -> boolean()), + array:array(any()), + non_neg_integer() + ) + -> integer(). +first_internals (_, _, 0) -> + -1; +first_internals (Fun, Array, PrevIX) -> + IX = (PrevIX - 1), + case Fun(array:get(IX, Array)) of + true -> IX; + _ -> first_internals(Fun, Array, IX) + end. + +-spec any_indexed_internals + ( + fun((non_neg_integer(), any()) -> boolean()), + array:array(any()), + non_neg_integer() + ) + -> boolean(). +any_indexed_internals (_, _, 0) -> + false; +any_indexed_internals (Fun, Array, PrevIX) -> + IX = (PrevIX - 1), + case Fun(IX, array:get(IX, Array)) of + true -> true; + _ -> any_indexed_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 first (fun((any()) -> boolean()), array:array(any())) -> integer(). +first (Fun, Array) -> + first_internals(Fun, Array, array:size(Array)). + +-spec any_indexed + ( + fun((non_neg_integer(), any()) -> boolean()), + array:array(any()) + ) -> boolean(). +any_indexed (Fun, Array) -> + any_indexed_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/shared/util/shr_math_util.erl b/src/shared/util/shr_math_util.erl new file mode 100644 index 0000000..874bacc --- /dev/null +++ b/src/shared/util/shr_math_util.erl @@ -0,0 +1,30 @@ +-module(shr_math_util). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-export +( + [ + % Somehow, erlang:ceil is not defined on 2 out of my 4 dev computers. + ceil/1 + ] +). +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec ceil (float()) -> integer(). +ceil (Float) -> + Int = trunc(Float), + + case (Int /= Float) of + true -> (Int + 1); + _ -> Int + end. -- cgit v1.2.3-70-g09d2