summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-08-18 18:56:54 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-08-18 18:56:54 +0200
commit7a1686695e70b68b2d4ad49c0f5bc967fa6d1013 (patch)
tree0422b802a88953b3c938f573be5dc7bd9c8cb8d7 /src/balancer/struct/blc_weapon.erl
parent5266e24e01611fc8026dfa0498ee87d7fba65e88 (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/blc_weapon.erl')
-rw-r--r--src/balancer/struct/blc_weapon.erl422
1 files changed, 196 insertions, 226 deletions
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.