summaryrefslogtreecommitdiff |
diff options
author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-08-18 18:56:54 +0200 |
---|---|---|
committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-08-18 18:56:54 +0200 |
commit | 7a1686695e70b68b2d4ad49c0f5bc967fa6d1013 (patch) | |
tree | 0422b802a88953b3c938f573be5dc7bd9c8cb8d7 /src/balancer/struct | |
parent | 5266e24e01611fc8026dfa0498ee87d7fba65e88 (diff) |
Use blc_error in blc_{armor,weapon}.
Dialyzer confuses me:
shr_omnimods.erl:90: Overloaded contract for shr_omnimods:apply_coefficient_to_mods/2 has overlapping domains; such contracts are currently unsupported and are simply ignored
shr_omnimods.erl:96: Overloaded contract for shr_omnimods:merge_mods/2 has overlapping domains; such contracts are currently unsupported and are simply ignored
This seems to imply that shr_omnimods:damage_type_mods() and
shr_omnimods:attribute_mods() overlap, which is not supposed to be the
case.
Diffstat (limited to 'src/balancer/struct')
-rw-r--r-- | src/balancer/struct/blc_armor.erl | 320 | ||||
-rw-r--r-- | src/balancer/struct/blc_glyph.erl | 18 | ||||
-rw-r--r-- | src/balancer/struct/blc_weapon.erl | 422 |
3 files changed, 355 insertions, 405 deletions
diff --git a/src/balancer/struct/blc_armor.erl b/src/balancer/struct/blc_armor.erl index 9677f88..cc23415 100644 --- a/src/balancer/struct/blc_armor.erl +++ b/src/balancer/struct/blc_armor.erl @@ -40,22 +40,19 @@ ( proto_armor, { - health :: non_neg_integer(), - damage_modifier :: non_neg_integer(), - dodge :: non_neg_integer(), - mvt_points :: non_neg_integer(), - defense :: list(blc_damage_type:entry()), + omnimods :: shr_omnimods:type(), defense_coef :: list(blc_damage_type:coefficient()), - defense_score :: non_neg_integer() + defense_score :: non_neg_integer(), + remaining_points :: non_neg_integer() } ). --opaque proto_armor() :: #proto_armor{}. +-opaque type() :: #proto_armor{}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([proto_armor/0]). +-export_type([type/0]). -export ( @@ -78,13 +75,54 @@ ( [ new/1, - get_spendable_points/0 + get_remaining_points/1 ] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec increase_attribute_by + ( + shr_attributes:enum(), + non_neg_integer(), + type() + ) + -> ({ok, type()} | blc_error:type()). +increase_attribute_by (Attribute, S0Amount, Armor) -> + CurrentOmnimods = Armor#proto_armor.omnimods, + CurrentValue = + shr_omnimods:get_attribute_modifier(Attribute, CurrentOmnimods), + + {_AttMin, _AttDef, AttMax, AttCost} = blc_attribute:get_info(Attribute), + + S1Amount = + case ((CurrentValue + S0Amount) > AttMax) of + true -> (AttMax - CurrentValue); + false -> S0Amount + end, + + Cost = (S1Amount * AttCost), + RemainingPoints = Armor#proto_armor.remaining_points, + + case (Cost > RemainingPoints) of + true -> {error, balance, RemainingPoints, Cost}; + false -> + { + ok, + Armor#proto_armor + { + remaining_points = (RemainingPoints - Cost), + omnimods = + shr_omnimods:mod_attribute_modifier + ( + Attribute, + S1Amount, + Armor#proto_armor.omnimods + ) + } + } + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -92,246 +130,186 @@ -spec increase_health_by ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_health_by (Amount, Armor) -> - NewHealth = (Armor#proto_armor.health + Amount), - case (NewHealth > ?ATTRIBUTE_HEALTH_MAX) of - true -> - { - Armor#proto_armor{ health = ?ATTRIBUTE_HEALTH_MAX }, - ( - (?ATTRIBUTE_HEALTH_MAX - Armor#proto_armor.health) - * ?ATTRIBUTE_HEALTH_COST - ) - }; - - false -> - { - Armor#proto_armor{ health = NewHealth }, - (Amount * ?ATTRIBUTE_HEALTH_COST) - } - end. + increase_attribute_by(?ATTRIBUTE_HEALTH, Amount, Armor). -spec increase_damage_modifier_by ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_damage_modifier_by (Amount, Armor) -> - NewDamageModifier = (Armor#proto_armor.damage_modifier + Amount), - case (NewDamageModifier > ?ATTRIBUTE_DAMAGE_MODIFIER_MAX) of - true -> - { - Armor#proto_armor - { - damage_modifier = ?ATTRIBUTE_DAMAGE_MODIFIER_MAX - }, - ( - ( - ?ATTRIBUTE_DAMAGE_MODIFIER_MAX - - Armor#proto_armor.damage_modifier - ) - * ?ATTRIBUTE_DAMAGE_MODIFIER_COST - ) - }; - - false -> - { - Armor#proto_armor{ damage_modifier = NewDamageModifier }, - (Amount * ?ATTRIBUTE_DAMAGE_MODIFIER_COST) - } - end. + increase_attribute_by(?ATTRIBUTE_DAMAGE_MODIFIER, Amount, Armor). -spec increase_dodge_chance_by ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_dodge_chance_by (Amount, Armor) -> - NewDodgeChance = (Armor#proto_armor.dodge + Amount), - case (NewDodgeChance > ?ATTRIBUTE_DODGE_CHANCE_MAX) of - true -> - { - Armor#proto_armor{ dodge = ?ATTRIBUTE_DODGE_CHANCE_MAX }, - ( - (?ATTRIBUTE_DODGE_CHANCE_MAX - Armor#proto_armor.dodge) - * ?ATTRIBUTE_DODGE_CHANCE_COST - ) - }; - - false -> - { - Armor#proto_armor{ dodge = NewDodgeChance }, - (Amount * ?ATTRIBUTE_DODGE_CHANCE_COST) - } - end. + increase_attribute_by(?ATTRIBUTE_DODGE_CHANCE, Amount, Armor). -spec increase_movement_points_by ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_movement_points_by (Amount, Armor) -> - NewMvtPoints = (Armor#proto_armor.mvt_points + Amount), - case (NewMvtPoints > ?ATTRIBUTE_MOVEMENT_POINTS_MAX) of - true -> - { - Armor#proto_armor{ mvt_points = ?ATTRIBUTE_MOVEMENT_POINTS_MAX }, - ( - (?ATTRIBUTE_MOVEMENT_POINTS_MAX - Armor#proto_armor.mvt_points) - * ?ATTRIBUTE_MOVEMENT_POINTS_COST - ) - }; - - false -> - { - Armor#proto_armor{ mvt_points = NewMvtPoints }, - (Amount * ?ATTRIBUTE_MOVEMENT_POINTS_COST) - } - end. + increase_attribute_by(?ATTRIBUTE_MOVEMENT_POINTS, Amount, Armor). -spec increase_defense_score_by ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. -increase_defense_score_by (Amount, Armor) -> - NewDefenseScore = (Armor#proto_armor.defense_score + Amount), - case (NewDefenseScore > ?ATTRIBUTE_DEFENSE_SCORE_MAX) of - true -> - { - Armor#proto_armor + -> ({ok, type()} | blc_error:type()). +increase_defense_score_by (S0Amount, Armor) -> + CurrentValue = Armor#proto_armor.defense_score, + S0NewValue = CurrentValue + S0Amount, + {S1Amount, S1NewValue} = + case (S0NewValue > ?ATTRIBUTE_DEFENSE_SCORE_MAX) of + false -> {S0Amount, S0NewValue}; + true -> { - defense_score = ?ATTRIBUTE_DEFENSE_SCORE_MAX, - defense = - blc_damage_type:generate_entries_from_score - ( - NewDefenseScore, - Armor#proto_armor.defense_coef - ) - }, - ( - (?ATTRIBUTE_DEFENSE_SCORE_MAX - Armor#proto_armor.defense_score) - * Amount - ) - }; + (?ATTRIBUTE_DEFENSE_SCORE_MAX - CurrentValue), + ?ATTRIBUTE_DEFENSE_SCORE_MAX + } + end, + + Cost = (S1Amount * ?ATTRIBUTE_DEFENSE_SCORE_COST), + RemainingPoints = Armor#proto_armor.remaining_points, + case (Cost > RemainingPoints) of + true -> {error, balance, RemainingPoints, Cost}; false -> { + ok, Armor#proto_armor { - defense_score = NewDefenseScore, - defense = - blc_damage_type:generate_entries_from_score + remaining_points = (RemainingPoints - Cost), + defense_score = S1NewValue, + omnimods = + shr_omnimods:set_defense_modifiers ( - NewDefenseScore, - Armor#proto_armor.defense_coef + blc_damage_type:generate_entries_from_score + ( + S1NewValue, + Armor#proto_armor.defense_coef + ), + Armor#proto_armor.omnimods ) - }, - (Amount * ?ATTRIBUTE_DEFENSE_SCORE_COST) + } } end. -spec set_defense_coefficients ( list(blc_damage_type:coefficient()), - proto_armor() + type() ) - -> proto_armor(). + -> type(). set_defense_coefficients (Coefficients, Armor) -> - {Result, 0} = - increase_defense_score_by - ( - 0, - Armor#proto_armor - { - defense_coef = blc_damage_type:sort_entries(Coefficients) - } - ), + NewCoefs = blc_damage_type:sort_entries(Coefficients), + + Armor#proto_armor + { + defense_coef = NewCoefs, + omnimods = + shr_omnimods:set_defense_modifiers + ( + blc_damage_type:generate_entries_from_score + ( + Armor#proto_armor.defense_score, + NewCoefs + ), + Armor#proto_armor.omnimods + ) + }. - Result. --spec new (list(blc_damage_type:coefficient())) -> proto_armor(). +-spec new (list(blc_damage_type:coefficient())) -> type(). new (Coefficients) -> - {Result, _DefenseScoreIncreaseCost} = - increase_defense_score_by - ( - ?ATTRIBUTE_DEFENSE_SCORE_MIN, - #proto_armor - { - health = ?ATTRIBUTE_HEALTH_MIN, - damage_modifier = ?ATTRIBUTE_DAMAGE_MODIFIER_MIN, - dodge = ?ATTRIBUTE_DODGE_CHANCE_MIN, - mvt_points = ?ATTRIBUTE_MOVEMENT_POINTS_MIN, - defense = [], - defense_coef = blc_damage_type:sort_entries(Coefficients), - defense_score = 0 - } - ), + SortedCoefficients = blc_damage_type:sort_entries(Coefficients), + + #proto_armor + { + omnimods = + shr_omnimods:new + ( + [ + {?ATTRIBUTE_HEALTH, ?ATTRIBUTE_HEALTH_MIN}, + {?ATTRIBUTE_DAMAGE_MODIFIER, ?ATTRIBUTE_DAMAGE_MODIFIER_MIN}, + {?ATTRIBUTE_DODGE_CHANCE, ?ATTRIBUTE_DODGE_CHANCE_MIN}, + {?ATTRIBUTE_MOVEMENT_POINTS, ?ATTRIBUTE_MOVEMENT_POINTS_MIN} + ], + [], + blc_damage_type:generate_entries_from_score + ( + ?ATTRIBUTE_DEFENSE_SCORE_MIN, + SortedCoefficients + ) + ), - Result. + defense_coef = SortedCoefficients, + defense_score = ?ATTRIBUTE_DEFENSE_SCORE_MIN, + remaining_points = ?SPENDABLE_ARMOR_POINTS + }. -spec increase_health_for ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_health_for (GivenPoints, Armor) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_HEALTH_COST), - {Result, SpentPoints} = increase_health_by(AmountOfIncrease, Armor), - {Result, (GivenPoints - SpentPoints)}. + increase_health_by(AmountOfIncrease, Armor). -spec increase_damage_modifier_for ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_damage_modifier_for (GivenPoints, Armor) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_DAMAGE_MODIFIER_COST), - {Result, SpentPoints} = increase_damage_modifier_by(AmountOfIncrease, Armor), - {Result, (GivenPoints - SpentPoints)}. + increase_damage_modifier_by(AmountOfIncrease, Armor). -spec increase_dodge_chance_for ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_dodge_chance_for (GivenPoints, Armor) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_DODGE_CHANCE_COST), - {Result, SpentPoints} = increase_dodge_chance_by(AmountOfIncrease, Armor), - {Result, (GivenPoints - SpentPoints)}. + increase_dodge_chance_by(AmountOfIncrease, Armor). -spec increase_movement_points_for ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_movement_points_for (GivenPoints, Armor) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_MOVEMENT_POINTS_COST), - {Result, SpentPoints} = increase_movement_points_by(AmountOfIncrease, Armor), - {Result, (GivenPoints - SpentPoints)}. + increase_movement_points_by(AmountOfIncrease, Armor). -spec increase_defense_score_for ( non_neg_integer(), - proto_armor() + type() ) - -> {proto_armor(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_defense_score_for (GivenPoints, Armor) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_DEFENSE_SCORE_COST), - {Result, SpentPoints} = increase_defense_score_by(AmountOfIncrease, Armor), - {Result, (GivenPoints - SpentPoints)}. - + increase_defense_score_by(AmountOfIncrease, Armor). --spec get_spendable_points () -> non_neg_integer(). -get_spendable_points () -> ?SPENDABLE_ARMOR_POINTS. +-spec get_remaining_points (type()) -> non_neg_integer(). +get_remaining_points (Armor) -> Armor#proto_armor.remaining_points. diff --git a/src/balancer/struct/blc_glyph.erl b/src/balancer/struct/blc_glyph.erl index 9b43f88..894dd9f 100644 --- a/src/balancer/struct/blc_glyph.erl +++ b/src/balancer/struct/blc_glyph.erl @@ -16,8 +16,8 @@ remaining_positive_points :: non_neg_integer(), points_balance :: integer(), omnimods :: shr_omnimods:type(), - defense_coef :: blc_damage_type:coefficient(), - attack_coef :: blc_damage_type:coefficient(), + defense_coef :: list(blc_damage_type:coefficient()), + attack_coef :: list(blc_damage_type:coefficient()), defense_score :: non_neg_integer(), defense_sign :: integer(), attack_score :: non_neg_integer(), @@ -156,7 +156,8 @@ increase_attribute_by (?ATTRIBUTE_DEFENSE_SCORE, S0Amount, Glyph) -> increase_attribute_by (Attribute, S0Amount, Glyph) -> {_AttMin, _AttDef, AttMax, AttCost} = blc_attribute:get_info(Attribute), CurrentOmnimods = Glyph#proto_glyph.omnimods, - CurrentValue = shr_omnimods:get_attribute(Attribute, CurrentOmnimods), + CurrentValue = + shr_omnimods:get_attribute_modifier(Attribute, CurrentOmnimods), S1Amount = case ((CurrentValue + S0Amount) > AttMax) of @@ -177,7 +178,7 @@ increase_attribute_by (Attribute, S0Amount, Glyph) -> Glyph#proto_glyph { omnimods = - shr_omnimods:mod_attribute + shr_omnimods:mod_attribute_modifier ( Attribute, S1Amount, @@ -274,9 +275,10 @@ decrease_attribute_by (?ATTRIBUTE_DEFENSE_SCORE, Amount, Glyph) -> decrease_attribute_by (Attribute, Amount, Glyph) -> {_AttMin, _AttDef, _AttMax, AttCost} = blc_attribute:get_info(Attribute), CurrentOmnimods = Glyph#proto_glyph.omnimods, - CurrentValue = shr_omnimods:get_attribute(Attribute, CurrentOmnimods), + CurrentValue = + shr_omnimods:get_attribute_modifier(Attribute, CurrentOmnimods), - Cost = ((Amount * AttCost) * ?NEGATIVE_POINTS_MULTIPLIER), + Cost = trunc((Amount * AttCost) * ?NEGATIVE_POINTS_MULTIPLIER), if (CurrentValue > 0) -> {error, incompatible}; @@ -287,7 +289,7 @@ decrease_attribute_by (Attribute, Amount, Glyph) -> Glyph#proto_glyph { omnimods = - shr_omnimods:mod_attribute + shr_omnimods:mod_attribute_modifier ( Attribute, (-1 * Amount), @@ -407,7 +409,7 @@ new (AttackCoefficients, DefenseCoefficients) -> { remaining_positive_points = ?SPENDABLE_GLYPH_POINTS, points_balance = 0, - omnimods = omnimods:new(), + omnimods = shr_omnimods:new(), attack_coef = blc_damage_type:sort_entries(AttackCoefficients), attack_score = 0, attack_sign = 0, diff --git a/src/balancer/struct/blc_weapon.erl b/src/balancer/struct/blc_weapon.erl index 0edeb35..970c4e5 100644 --- a/src/balancer/struct/blc_weapon.erl +++ b/src/balancer/struct/blc_weapon.erl @@ -7,15 +7,9 @@ -define(WEAPON_ATTRIBUTE_RANGE_DEFAULT, 0). -define(WEAPON_ATTRIBUTE_RANGE_COST, 1). --define(WEAPON_ATTRIBUTE_TYPE_MIN, 0). --define(WEAPON_ATTRIBUTE_TYPE_MAX, 1). --define(WEAPON_ATTRIBUTE_TYPE_DEFAULT, 0). --define(WEAPON_ATTRIBUTE_TYPE_COST, 100). - - -define ( - SPENDABLE_WEAPON_POINTS, + BASE_SPENDABLE_WEAPON_POINTS, ( ( ?ATTRIBUTE_ACCURACY_COST @@ -52,42 +46,57 @@ ) ). +-define +( + MELEE_SPENDABLE_WEAPON_POINTS, + ( + ?BASE_SPENDABLE_WEAPON_POINTS + + + ( + ?ATTRIBUTE_PARRY_CHANCE_COST + * (?ATTRIBUTE_PARRY_CHANCE_DEFAULT - ?ATTRIBUTE_PARRY_CHANCE_MIN) + ) + ) +). + +-define(RANGED_SPENDABLE_WEAPON_POINTS, ?BASE_SPENDABLE_WEAPON_POINTS). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-type range_type() :: (melee | ranged). + -record ( proto_weapon, { range :: non_neg_integer(), - type :: non_neg_integer(), - accuracy :: non_neg_integer(), - critical_hit_chance :: non_neg_integer(), - double_hit_chance :: non_neg_integer(), - attack :: list(blc_damage_type:entry()), + range_type :: range_type(), + omnimods :: shr_omnimods:type(), attack_coef :: list(blc_damage_type:coefficient()), - attack_score :: non_neg_integer() + attack_score :: non_neg_integer(), + remaining_points :: non_neg_integer() } ). --opaque proto_weapon() :: #proto_weapon{}. +-opaque type() :: #proto_weapon{}. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --export_type([proto_weapon/0]). +-export_type([type/0,range_type/0]). -export ( [ increase_range_by/2, - increase_type_by/2, + increase_parry_chance_by/2, increase_accuracy_by/2, increase_critical_hit_chance_by/2, increase_double_hit_chance_by/2, increase_attack_score_by/2, increase_range_for/2, - increase_type_for/2, + increase_parry_chance_for/2, increase_accuracy_for/2, increase_critical_hit_chance_for/2, increase_double_hit_chance_for/2, @@ -99,14 +108,55 @@ -export ( [ - new/1, - get_spendable_points/0 + new/2, + get_remaining_points/1 ] ). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec increase_attribute_by + ( + shr_attributes:enum(), + non_neg_integer(), + type() + ) + -> ({ok, type()} | blc_error:type()). +increase_attribute_by (Attribute, S0Amount, Weapon) -> + CurrentOmnimods = Weapon#proto_weapon.omnimods, + CurrentValue = + shr_omnimods:get_attribute_modifier(Attribute, CurrentOmnimods), + + {_AttMin, _AttDef, AttMax, AttCost} = blc_attribute:get_info(Attribute), + + S1Amount = + case ((CurrentValue + S0Amount) > AttMax) of + true -> (AttMax - CurrentValue); + false -> S0Amount + end, + + Cost = (S1Amount * AttCost), + RemainingPoints = Weapon#proto_weapon.remaining_points, + + case (Cost > RemainingPoints) of + true -> {error, balance, RemainingPoints, Cost}; + false -> + { + ok, + Weapon#proto_weapon + { + remaining_points = (RemainingPoints - Cost), + omnimods = + shr_omnimods:mod_attribute_modifier + ( + Attribute, + S1Amount, + Weapon#proto_weapon.omnimods + ) + } + } + end. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -114,301 +164,221 @@ -spec increase_accuracy_by ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_accuracy_by (Amount, Weapon) -> - NewAccuracy = (Weapon#proto_weapon.accuracy + Amount), - case (NewAccuracy > ?ATTRIBUTE_ACCURACY_MAX) of - true -> - { - Weapon#proto_weapon{ accuracy = ?ATTRIBUTE_ACCURACY_MAX }, - ( - (?ATTRIBUTE_ACCURACY_MAX - Weapon#proto_weapon.accuracy) - * ?ATTRIBUTE_ACCURACY_COST - ) - }; - - false -> - { - Weapon#proto_weapon{ accuracy = NewAccuracy }, - (Amount * ?ATTRIBUTE_ACCURACY_COST) - } - end. + increase_attribute_by(?ATTRIBUTE_ACCURACY, Amount, Weapon). -spec increase_range_by ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_range_by (Amount, Weapon) -> - NewDamageModifier = Weapon#proto_weapon.range + Amount, - case (NewDamageModifier > ?WEAPON_ATTRIBUTE_RANGE_MAX) of - true -> - { - Weapon#proto_weapon - { - range = ?WEAPON_ATTRIBUTE_RANGE_MAX - }, - ( - ( - ?WEAPON_ATTRIBUTE_RANGE_MAX - - Weapon#proto_weapon.range - ) - * ?WEAPON_ATTRIBUTE_RANGE_COST - ) - }; + increase_attribute_by(?ATTRIBUTE_ACCURACY, Amount, Weapon). - false -> - { - Weapon#proto_weapon{ range = NewDamageModifier }, - (Amount * ?WEAPON_ATTRIBUTE_RANGE_COST) - } - end. - --spec increase_type_by +-spec increase_parry_chance_by ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. -increase_type_by (Amount, Weapon) -> - NewType = Weapon#proto_weapon.type + Amount, - case (NewType > ?WEAPON_ATTRIBUTE_TYPE_MAX) of - true -> - { - Weapon#proto_weapon { type = ?WEAPON_ATTRIBUTE_TYPE_MAX }, - ( - (?WEAPON_ATTRIBUTE_TYPE_MAX - Weapon#proto_weapon.type) - * ?WEAPON_ATTRIBUTE_TYPE_COST - ) - }; - - false -> - { - Weapon#proto_weapon{ type = NewType }, - (Amount * ?WEAPON_ATTRIBUTE_TYPE_COST) - } + -> ({ok, type()} | blc_error:type()). +increase_parry_chance_by (Amount, Weapon) -> + case (Weapon#proto_weapon.range_type) of + ranged -> {error, incompatible}; + _ -> increase_attribute_by(?ATTRIBUTE_PARRY_CHANCE, Amount, Weapon) end. -spec increase_critical_hit_chance_by ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_critical_hit_chance_by (Amount, Weapon) -> - NewCriticalHitChance = (Weapon#proto_weapon.critical_hit_chance + Amount), - case (NewCriticalHitChance > ?ATTRIBUTE_CRITICAL_HIT_CHANCE_MAX) of - true -> - { - Weapon#proto_weapon - { - critical_hit_chance = ?ATTRIBUTE_CRITICAL_HIT_CHANCE_MAX - }, - ( - ( - ?ATTRIBUTE_CRITICAL_HIT_CHANCE_MAX - - Weapon#proto_weapon.critical_hit_chance - ) - * ?ATTRIBUTE_CRITICAL_HIT_CHANCE_COST - ) - }; - - false -> - { - Weapon#proto_weapon{ critical_hit_chance = NewCriticalHitChance }, - (Amount * ?ATTRIBUTE_CRITICAL_HIT_CHANCE_COST) - } - end. + increase_attribute_by(?ATTRIBUTE_CRITICAL_HIT_CHANCE, Amount, Weapon). -spec increase_double_hit_chance_by ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_double_hit_chance_by (Amount, Weapon) -> - NewDoubleHitChance = Weapon#proto_weapon.double_hit_chance + Amount, - case (NewDoubleHitChance > ?ATTRIBUTE_DOUBLE_HIT_CHANCE_MAX) of - true -> - { - Weapon#proto_weapon - { - double_hit_chance = ?ATTRIBUTE_DOUBLE_HIT_CHANCE_MAX - }, - ( - ( - ?ATTRIBUTE_DOUBLE_HIT_CHANCE_MAX - - Weapon#proto_weapon.double_hit_chance - ) - * ?ATTRIBUTE_DOUBLE_HIT_CHANCE_COST - ) - }; - - false -> - { - Weapon#proto_weapon{ double_hit_chance = NewDoubleHitChance }, - (Amount * ?ATTRIBUTE_DOUBLE_HIT_CHANCE_COST) - } - end. - + increase_attribute_by(?ATTRIBUTE_DOUBLE_HIT_CHANCE, Amount, Weapon). -spec increase_attack_score_by ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. -increase_attack_score_by (Amount, Weapon) -> - NewAttackScore = (Weapon#proto_weapon.attack_score + Amount), - case (NewAttackScore > ?ATTRIBUTE_ATTACK_SCORE_MAX) of - true -> - { - Weapon#proto_weapon + -> ({ok, type()} | blc_error:type()). +increase_attack_score_by (S0Amount, Weapon) -> + CurrentValue = Weapon#proto_weapon.attack_score, + S0NewValue = CurrentValue + S0Amount, + {S1Amount, S1NewValue} = + case (S0NewValue > ?ATTRIBUTE_ATTACK_SCORE_MAX) of + false -> {S0Amount, S0NewValue}; + true -> { - attack_score = ?ATTRIBUTE_ATTACK_SCORE_MAX, - attack = - blc_damage_type:generate_entries_from_score - ( - NewAttackScore, - Weapon#proto_weapon.attack_coef - ) - }, - ( - (?ATTRIBUTE_ATTACK_SCORE_MAX - Weapon#proto_weapon.attack_score) - * Amount - ) - }; + (?ATTRIBUTE_ATTACK_SCORE_MAX - CurrentValue), + ?ATTRIBUTE_ATTACK_SCORE_MAX + } + end, + Cost = (S1Amount * ?ATTRIBUTE_ATTACK_SCORE_COST), + RemainingPoints = Weapon#proto_weapon.remaining_points, + + case (Cost > RemainingPoints) of + true -> {error, balance, RemainingPoints, Cost}; false -> { + ok, Weapon#proto_weapon { - attack_score = NewAttackScore, - attack = - blc_damage_type:generate_entries_from_score + remaining_points = (RemainingPoints - Cost), + attack_score = S1NewValue, + omnimods = + shr_omnimods:set_attack_modifiers ( - NewAttackScore, - Weapon#proto_weapon.attack_coef + blc_damage_type:generate_entries_from_score + ( + S1NewValue, + Weapon#proto_weapon.attack_coef + ), + Weapon#proto_weapon.omnimods ) - }, - (Amount * ?ATTRIBUTE_ATTACK_SCORE_COST) + } } end. -spec set_attack_coefficients ( list(blc_damage_type:coefficient()), - proto_weapon() + type() ) - -> proto_weapon(). + -> type(). set_attack_coefficients (Coefficients, Weapon) -> - {Result, 0} = - increase_attack_score_by - ( - 0, - Weapon#proto_weapon - { - attack_coef = blc_damage_type:sort_entries(Coefficients) - } - ), + NewCoefs = blc_damage_type:sort_entries(Coefficients), - Result. + Weapon#proto_weapon + { + attack_coef = NewCoefs, + omnimods = + shr_omnimods:set_attack_modifiers + ( + blc_damage_type:generate_entries_from_score + ( + Weapon#proto_weapon.attack_score, + NewCoefs + ), + Weapon#proto_weapon.omnimods + ) + }. --spec new (list(blc_damage_type:coefficient())) -> proto_weapon(). -new (Coefficients) -> - {Result, _AttackScoreIncreaseCost} = - increase_attack_score_by - ( - ?ATTRIBUTE_ATTACK_SCORE_MIN, - #proto_weapon - { - range = ?WEAPON_ATTRIBUTE_RANGE_MIN, - type = ?WEAPON_ATTRIBUTE_TYPE_MIN, - accuracy = ?ATTRIBUTE_ACCURACY_MIN, - critical_hit_chance = ?ATTRIBUTE_CRITICAL_HIT_CHANCE_MIN, - double_hit_chance = ?ATTRIBUTE_DOUBLE_HIT_CHANCE_MIN, - attack = [], - attack_coef = blc_damage_type:sort_entries(Coefficients), - attack_score = 0 - } - ), +-spec new (range_type(), list(blc_damage_type:coefficient())) -> type(). +new (RangeType, Coefficients) -> + SortedCoefficients = blc_damage_type:sort_entries(Coefficients), - Result. + #proto_weapon + { + range = ?WEAPON_ATTRIBUTE_RANGE_MIN, + range_type = RangeType, + omnimods = + shr_omnimods:new + ( + [ + {?ATTRIBUTE_ACCURACY, ?ATTRIBUTE_ACCURACY_MIN}, + {?ATTRIBUTE_PARRY_CHANCE, ?ATTRIBUTE_PARRY_CHANCE_MIN}, + { + ?ATTRIBUTE_CRITICAL_HIT_CHANCE, + ?ATTRIBUTE_CRITICAL_HIT_CHANCE_MIN + }, + { + ?ATTRIBUTE_DOUBLE_HIT_CHANCE, + ?ATTRIBUTE_DOUBLE_HIT_CHANCE_MIN + } + ], + blc_damage_type:generate_entries_from_score + ( + ?ATTRIBUTE_ATTACK_SCORE_MIN, + SortedCoefficients + ), + [] + ), + + attack_coef = SortedCoefficients, + attack_score = ?ATTRIBUTE_ATTACK_SCORE_MIN, + remaining_points = + case RangeType of + melee -> ?MELEE_SPENDABLE_WEAPON_POINTS; + ranged -> ?RANGED_SPENDABLE_WEAPON_POINTS + end + }. -spec increase_range_for ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_range_for (GivenPoints, Weapon) -> AmountOfIncrease = trunc(GivenPoints / ?WEAPON_ATTRIBUTE_RANGE_COST), - {Result, SpentPoints} = increase_range_by(AmountOfIncrease, Weapon), - {Result, (GivenPoints - SpentPoints)}. + increase_range_by(AmountOfIncrease, Weapon). --spec increase_type_for +-spec increase_parry_chance_for ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. -increase_type_for (GivenPoints, Weapon) -> - AmountOfIncrease = trunc(GivenPoints / ?WEAPON_ATTRIBUTE_TYPE_COST), - {Result, SpentPoints} = increase_type_by(AmountOfIncrease, Weapon), - {Result, (GivenPoints - SpentPoints)}. + -> ({ok, type()} | blc_error:type()). +increase_parry_chance_for (GivenPoints, Weapon) -> + AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_PARRY_CHANCE_COST), + increase_parry_chance_by(AmountOfIncrease, Weapon). -spec increase_accuracy_for ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_accuracy_for (GivenPoints, Weapon) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_ACCURACY_COST), - {Result, SpentPoints} = increase_accuracy_by(AmountOfIncrease, Weapon), - {Result, (GivenPoints - SpentPoints)}. + increase_accuracy_by(AmountOfIncrease, Weapon). -spec increase_critical_hit_chance_for ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_critical_hit_chance_for (GivenPoints, Weapon) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_CRITICAL_HIT_CHANCE_COST), - {Result, SpentPoints} = - increase_critical_hit_chance_by(AmountOfIncrease, Weapon), - - {Result, (GivenPoints - SpentPoints)}. + increase_critical_hit_chance_by(AmountOfIncrease, Weapon). -spec increase_double_hit_chance_for ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_double_hit_chance_for (GivenPoints, Weapon) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_DOUBLE_HIT_CHANCE_COST), - {Result, SpentPoints} = - increase_double_hit_chance_by(AmountOfIncrease, Weapon), - - {Result, (GivenPoints - SpentPoints)}. + increase_double_hit_chance_by(AmountOfIncrease, Weapon). -spec increase_attack_score_for ( non_neg_integer(), - proto_weapon() + type() ) - -> {proto_weapon(), non_neg_integer()}. + -> ({ok, type()} | blc_error:type()). increase_attack_score_for (GivenPoints, Weapon) -> AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_ATTACK_SCORE_COST), - {Result, SpentPoints} = increase_attack_score_by(AmountOfIncrease, Weapon), - {Result, (GivenPoints - SpentPoints)}. + increase_attack_score_by(AmountOfIncrease, Weapon). --spec get_spendable_points () -> non_neg_integer(). -get_spendable_points () -> ?SPENDABLE_WEAPON_POINTS. +-spec get_remaining_points (type()) -> non_neg_integer(). +get_remaining_points (Weapon) -> Weapon#proto_weapon.remaining_points. |