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/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 +++++++++++++++++++++++++++++++++++ 14 files changed, 1263 insertions(+), 1263 deletions(-) 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 (limited to 'src/shared/struct') 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. -- cgit v1.2.3-70-g09d2