| summaryrefslogtreecommitdiff | 
diff options
Diffstat (limited to 'src/shared')
| -rw-r--r-- | src/shared/include/db_item.hrl | 15 | ||||
| -rw-r--r-- | src/shared/include/db_query.hrl | 63 | ||||
| -rw-r--r-- | src/shared/include/db_user.hrl | 7 | ||||
| -rw-r--r-- | src/shared/io/sh_timed_cache.erl | 2 | ||||
| -rw-r--r-- | src/shared/struct/sh_db_item.erl | 12 | ||||
| -rw-r--r-- | src/shared/struct/sh_db_query.erl | 157 | ||||
| -rw-r--r-- | src/shared/struct/sh_db_user.erl | 5 | ||||
| -rw-r--r-- | src/shared/struct/sh_statistics.erl | 29 | ||||
| -rw-r--r-- | src/shared/struct/sh_weapon.erl | 360 | 
9 files changed, 545 insertions, 105 deletions
diff --git a/src/shared/include/db_item.hrl b/src/shared/include/db_item.hrl deleted file mode 100644 index 86d5863..0000000 --- a/src/shared/include/db_item.hrl +++ /dev/null @@ -1,15 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( -   db_item, -   { -      id :: any(), -      perm :: db_user:permission(), -      val :: any() -   } -). - --type db_item() :: #db_item{}. - diff --git a/src/shared/include/db_query.hrl b/src/shared/include/db_query.hrl deleted file mode 100644 index 7e5a5b0..0000000 --- a/src/shared/include/db_query.hrl +++ /dev/null @@ -1,63 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --record -( -   set_field, -   { -      field :: non_neg_integer(), -      value :: any() -   } -). - --record -( -   add_to_field, -   { -      field :: non_neg_integer(), -      values :: list(any()), -      head :: boolean() -   } -). - --record -( -   update_indexed, -   { -      field :: non_neg_integer(), -      ix :: non_neg_integer(), -      ops :: list(db_query_op()) -   } -). - --record -( -   set_perm, -   { -      perm :: db_user:permission() -   } -). - --record -( -   set_val, -   { -      val :: any() -   } -). - --record -( -   db_query, -   { -      db :: atom(), -      id :: any(), -      user :: db_user:user(), -      ops :: list(db_query_master_op()) -   } -). - --type db_query_op() :: (#set_field{} | #add_to_field{} | #update_indexed{}). --type db_query_master_op() :: (db_query_op() | #set_perm{} | #set_val{}). --type db_query() :: #db_query{}. - diff --git a/src/shared/include/db_user.hrl b/src/shared/include/db_user.hrl deleted file mode 100644 index c5b033e..0000000 --- a/src/shared/include/db_user.hrl +++ /dev/null @@ -1,7 +0,0 @@ -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --type db_named_user() :: {'user', any()}. --type db_user() :: (db_named_user() | 'admin' | 'any'). --type db_permission() :: (list(db_named_user()) | 'any'). - diff --git a/src/shared/io/sh_timed_cache.erl b/src/shared/io/sh_timed_cache.erl index 1839992..de2f409 100644 --- a/src/shared/io/sh_timed_cache.erl +++ b/src/shared/io/sh_timed_cache.erl @@ -83,7 +83,7 @@ format_status (_, [_, State]) ->  handle_info(timeout, State) ->     {stop, normal, State};  handle_info(_, {DB, ObjectID}) -> -   {noreply, {DB, ObjectID}, timed_caches_manager:get_timeout()}. +   {noreply, {DB, ObjectID}, sh_timed_caches_manager:get_timeout()}.  %%%% Interface Functions  -spec fetch (atom(), any(), any()) -> any(). diff --git a/src/shared/struct/sh_db_item.erl b/src/shared/struct/sh_db_item.erl index e499634..98a1cb4 100644 --- a/src/shared/struct/sh_db_item.erl +++ b/src/shared/struct/sh_db_item.erl @@ -3,7 +3,17 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../include/db_item.hrl"). +-record +( +   db_item, +   { +      id :: any(), +      perm :: sh_db_user:permission(), +      val :: any() +   } +). + +-type db_item() :: #db_item{}.  -type type() :: db_item(). diff --git a/src/shared/struct/sh_db_query.erl b/src/shared/struct/sh_db_query.erl index 998568e..4eb50ba 100644 --- a/src/shared/struct/sh_db_query.erl +++ b/src/shared/struct/sh_db_query.erl @@ -3,7 +3,65 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../include/db_query.hrl"). +-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 :: 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(). @@ -22,10 +80,84 @@        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_perm(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 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -57,3 +189,26 @@ add_to_field (Field, Values) ->     -> 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 index 40a46d3..f2d4dfe 100644 --- a/src/shared/struct/sh_db_user.erl +++ b/src/shared/struct/sh_db_user.erl @@ -3,7 +3,10 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --include("../include/db_user.hrl"). +-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(). diff --git a/src/shared/struct/sh_statistics.erl b/src/shared/struct/sh_statistics.erl index 7cf2b06..92cd8d6 100644 --- a/src/shared/struct/sh_statistics.erl +++ b/src/shared/struct/sh_statistics.erl @@ -54,17 +54,14 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec ceil (float()) -> integer(). -ceil (F) -> +-spec float_to_int (float()) -> integer(). +float_to_int (F) ->     I = trunc(F),     case (F > I) of        true -> (I + 1);        _ -> I     end. --spec float_to_int (float()) -> integer(). -float_to_int (F) -> ceil(F). -  -spec min_max (number(), number(), number()) -> number().  min_max (Min, Max, V) -> min(Max, max(Min, V)). @@ -146,21 +143,21 @@ get_damages (Stats) ->  -spec new     ( -      attributes:type(), -      {weapon:id(), weapon:id()} +      sh_attributes:type(), +      {sh_weapon:id(), sh_weapon:id()}     )     -> type().  new (BaseAttributes, WeaponIDs) ->     {ActiveWeaponID, _} = WeaponIDs, -   ActiveWeapon = weapon:from_id(ActiveWeaponID), -   {MinDamage, MaxDamage} = weapon:get_damages(ActiveWeapon), -   Attributes = weapon:apply_to_attributes(BaseAttributes, ActiveWeapon), -   Constitution = attributes:get_constitution(Attributes), -   Dexterity = attributes:get_dexterity(Attributes), -   Intelligence = attributes:get_intelligence(Attributes), -   Mind = attributes:get_mind(Attributes), -   Speed = attributes:get_speed(Attributes), -   Strength = attributes:get_strength(Attributes), +   ActiveWeapon = sh_weapon:from_id(ActiveWeaponID), +   {MinDamage, MaxDamage} = sh_weapon:get_damages(ActiveWeapon), +   Attributes = sh_weapon:apply_to_attributes(BaseAttributes, ActiveWeapon), +   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 diff --git a/src/shared/struct/sh_weapon.erl b/src/shared/struct/sh_weapon.erl new file mode 100644 index 0000000..30943b9 --- /dev/null +++ b/src/shared/struct/sh_weapon.erl @@ -0,0 +1,360 @@ +-module(sh_weapon). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-opaque id() :: non_neg_integer(). + +-type range_type() :: 'ranged' | 'melee'. +-type range_mod() :: 'long' | 'short'. +-type damage_type() :: 'slash' | 'pierce' | 'blunt'. +-type damage_mod() :: 'heavy' | 'light'. + +-record +( +   weapon, +   { +      id :: id(), +      name :: binary(), +      range_type :: range_type(), +      range_mod :: range_mod(), +      damage_type :: damage_type(), +      damage_mod :: damage_mod() +   } +). + +-opaque type() :: #weapon{}. + +-export_type([type/0, id/0]). +-export_type +( +   [ +      range_type/0, +      range_mod/0, +      damage_type/0, +      damage_mod/0 +   ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-export +( +   [ +      get_id/1, +      get_range_type/1, +      get_ranges/1, +      get_damages/1 +   ] +). + +-export +( +   [ +      random_id/0, +      from_id/1, +      can_parry/1, +      apply_to_attributes/2 +   ] +). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec ranges_of_type +   ( +      range_type(), +      range_mod() +   ) +   -> {non_neg_integer(), non_neg_integer()}. +ranges_of_type (ranged, long) -> {2, 6}; +ranges_of_type (ranged, short) -> {1, 4}; +ranges_of_type (melee, long) -> {0, 2}; +ranges_of_type (melee, short) -> {0, 1}. + +-spec damages_of_type +   ( +      range_type(), +      damage_mod() +   ) +   -> {non_neg_integer(), non_neg_integer()}. +damages_of_type (ranged, heavy) -> {10, 25}; +damages_of_type (ranged, light) -> {5, 20}; +damages_of_type (melee, heavy) -> {20, 35}; +damages_of_type (melee, light) -> {15, 30}. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%% Accessors +-spec get_id (type()) -> id(). +get_id (Wp) -> Wp#weapon.id. + +-spec get_range_type (type()) -> range_type(). +get_range_type (Wp) -> Wp#weapon.range_type. + +-spec get_ranges (type()) -> {non_neg_integer(), non_neg_integer()}. +get_ranges (Wp) -> +   ranges_of_type(Wp#weapon.range_type, Wp#weapon.range_mod). + +-spec get_damages (type()) -> {non_neg_integer(), non_neg_integer()}. +get_damages (Wp) -> +   damages_of_type(Wp#weapon.range_type, Wp#weapon.damage_mod). + +-spec can_parry (type()) -> boolean(). +can_parry (Wp) -> (Wp#weapon.range_type == melee). + +-spec from_id (id()) -> type(). +from_id (0) -> +   #weapon{ +      id = 0, +      name = <<"None">>, +      range_type = melee, +      range_mod = short, +      damage_type = blunt, +      damage_mod = light +   }; +from_id (1) -> +   #weapon{ +      id = 1, +      name = <<"Dagger">>, +      range_type = melee, +      range_mod = short, +      damage_type = slash, +      damage_mod = light +   }; +from_id (2) -> +   #weapon{ +      id = 2, +      name = <<"Sword">>, +      range_type = melee, +      range_mod = short, +      damage_type = slash, +      damage_mod = heavy +   }; +from_id (3) -> +   #weapon{ +      id = 3, +      name = <<"Claymore">>, +      range_type = melee, +      range_mod = long, +      damage_type = slash, +      damage_mod = light +   }; +from_id (4) -> +   #weapon{ +      id = 4, +      name = <<"Bardiche">>, +      range_type = melee, +      range_mod = long, +      damage_type = slash, +      damage_mod = heavy +   }; +from_id (5) -> +   #weapon{ +      id = 5, +      name = <<"Stiletto">>, +      range_type = melee, +      range_mod = short, +      damage_type = pierce, +      damage_mod = light +   }; +from_id (6) -> +   #weapon{ +      id = 6, +      name = <<"Pickaxe">>, +      range_type = melee, +      range_mod = short, +      damage_type = pierce, +      damage_mod = heavy +   }; +from_id (7) -> +   #weapon{ +      id = 7, +      name = <<"Rapier">>, +      range_type = melee, +      range_mod = long, +      damage_type = pierce, +      damage_mod = light +   }; +from_id (8) -> +   #weapon{ +      id = 8, +      name = <<"Pike">>, +      range_type = melee, +      range_mod = long, +      damage_type = pierce, +      damage_mod = heavy +   }; +from_id (9) -> +   #weapon{ +      id = 9, +      name = <<"Club">>, +      range_type = melee, +      range_mod = short, +      damage_type = blunt, +      damage_mod = light +   }; +from_id (10) -> +   #weapon{ +      id = 10, +      name = <<"Mace">>, +      range_type = melee, +      range_mod = short, +      damage_type = blunt, +      damage_mod = heavy +   }; +from_id (11) -> +   #weapon{ +      id = 11, +      name = <<"Staff">>, +      range_type = melee, +      range_mod = long, +      damage_type = blunt, +      damage_mod = light +   }; +from_id (12) -> +   #weapon{ +      id = 12, +      name = <<"War Hammer">>, +      range_type = melee, +      range_mod = long, +      damage_type = blunt, +      damage_mod = heavy +   }; +from_id (13) -> +   #weapon{ +      id = 13, +      name = <<"Short Bow (Broadhead)">>, +      range_type = ranged, +      range_mod = short, +      damage_type = slash, +      damage_mod = light +   }; +from_id (14) -> +   #weapon{ +      id = 14, +      name = <<"Short Bow (Blunt)">>, +      range_type = ranged, +      range_mod = short, +      damage_type = blunt, +      damage_mod = light +   }; +from_id (15) -> +   #weapon{ +      id = 15, +      name = <<"Short Bow (Bodkin Point)">>, +      range_type = ranged, +      range_mod = short, +      damage_type = pierce, +      damage_mod = light +   }; +from_id (16) -> +   #weapon{ +      id = 16, +      name = <<"Long Bow (Broadhead)">>, +      range_type = ranged, +      range_mod = long, +      damage_type = slash, +      damage_mod = light +   }; +from_id (17) -> +   #weapon{ +      id = 17, +      name = <<"Long Bow (Blunt)">>, +      range_type = ranged, +      range_mod = long, +      damage_type = blunt, +      damage_mod = light +   }; +from_id (18) -> +   #weapon{ +      id = 18, +      name = <<"Long Bow (Bodkin Point)">>, +      range_type = ranged, +      range_mod = long, +      damage_type = pierce, +      damage_mod = light +   }; +from_id (19) -> +   #weapon{ +      id = 19, +      name = <<"Crossbow (Broadhead)">>, +      range_type = ranged, +      range_mod = short, +      damage_type = slash, +      damage_mod = heavy +   }; +from_id (20) -> +   #weapon{ +      id = 20, +      name = <<"Crossbow (Blunt)">>, +      range_type = ranged, +      range_mod = short, +      damage_type = blunt, +      damage_mod = heavy +   }; +from_id (21) -> +   #weapon{ +      id = 21, +      name = <<"Crossbow (Bodkin Point)">>, +      range_type = ranged, +      range_mod = short, +      damage_type = pierce, +      damage_mod = heavy +   }; +from_id (22) -> +   #weapon{ +      id = 22, +      name = <<"Arbalest (Broadhead)">>, +      range_type = ranged, +      range_mod = long, +      damage_type = slash, +      damage_mod = heavy +   }; +from_id (23) -> +   #weapon{ +      id = 23, +      name = <<"Arbalest (Blunt)">>, +      range_type = ranged, +      range_mod = long, +      damage_type = blunt, +      damage_mod = heavy +   }; +from_id (24) -> +   #weapon{ +      id = 24, +      name = <<"Arbalest (Bodkin Point)">>, +      range_type = ranged, +      range_mod = long, +      damage_type = pierce, +      damage_mod = heavy +   }. + +-spec random_id () -> id(). +random_id () -> sh_roll:between(0, 24). + +-spec apply_to_attributes +   ( +      sh_attributes:type(), +      type() +   ) +   -> sh_attributes:type(). +apply_to_attributes (Attributes, Weapon) -> +   Dexterity = sh_attributes:get_dexterity(Attributes), +   Speed = sh_attributes:get_speed(Attributes), +   RangeModifier = Weapon#weapon.range_mod, +   DamageModifier = Weapon#weapon.damage_mod, +   WithRangeModifier = +      case RangeModifier of +         long -> +            sh_attributes:set_dexterity(max(0, (Dexterity - 20)), Attributes); +         _ -> Attributes +      end, +   case DamageModifier of +      heavy -> sh_attributes:set_speed(max(0, (Speed - 20)), WithRangeModifier); +      _ -> WithRangeModifier +   end. +  | 


