summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-08-18 16:05:23 +0200
committerNathanael Sensfelder <SpamShield0@MultiAgentSystems.org>2019-08-18 16:05:23 +0200
commit5266e24e01611fc8026dfa0498ee87d7fba65e88 (patch)
tree72c73402dc959f5d618ac850b54d8eb724f60145 /src/balancer/struct/blc_weapon.erl
parentdc742fd9190eadd5eed2e45dd36262ea06550172 (diff)
...
Diffstat (limited to 'src/balancer/struct/blc_weapon.erl')
-rw-r--r--src/balancer/struct/blc_weapon.erl414
1 files changed, 414 insertions, 0 deletions
diff --git a/src/balancer/struct/blc_weapon.erl b/src/balancer/struct/blc_weapon.erl
new file mode 100644
index 0000000..0edeb35
--- /dev/null
+++ b/src/balancer/struct/blc_weapon.erl
@@ -0,0 +1,414 @@
+-module(blc_weapon).
+
+-include("tacticians/attributes.hrl").
+
+-define(WEAPON_ATTRIBUTE_RANGE_MIN, 0).
+-define(WEAPON_ATTRIBUTE_RANGE_MAX, 2).
+-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,
+ (
+ (
+ ?ATTRIBUTE_ACCURACY_COST
+ * (?ATTRIBUTE_ACCURACY_DEFAULT - ?ATTRIBUTE_ACCURACY_MIN)
+ )
+ +
+ (
+ ?ATTRIBUTE_CRITICAL_HIT_CHANCE_COST
+ *
+ (
+ ?ATTRIBUTE_CRITICAL_HIT_CHANCE_DEFAULT
+ - ?ATTRIBUTE_CRITICAL_HIT_CHANCE_MIN
+ )
+ )
+ +
+ (
+ ?ATTRIBUTE_DOUBLE_HIT_CHANCE_COST
+ *
+ (
+ ?ATTRIBUTE_DOUBLE_HIT_CHANCE_DEFAULT
+ - ?ATTRIBUTE_DOUBLE_HIT_CHANCE_MIN
+ )
+ )
+ +
+ (
+ ?ATTRIBUTE_ATTACK_SCORE_COST
+ * (?ATTRIBUTE_ATTACK_SCORE_DEFAULT - ?ATTRIBUTE_ATTACK_SCORE_MIN)
+ )
+ +
+ (
+ ?WEAPON_ATTRIBUTE_RANGE_COST
+ * (?WEAPON_ATTRIBUTE_RANGE_DEFAULT - ?WEAPON_ATTRIBUTE_RANGE_MIN)
+ )
+ )
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% TYPES %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-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()),
+ attack_coef :: list(blc_damage_type:coefficient()),
+ attack_score :: non_neg_integer()
+ }
+).
+
+-opaque proto_weapon() :: #proto_weapon{}.
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-export_type([proto_weapon/0]).
+
+-export
+(
+ [
+ increase_range_by/2,
+ increase_type_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_accuracy_for/2,
+ increase_critical_hit_chance_for/2,
+ increase_double_hit_chance_for/2,
+ increase_attack_score_for/2,
+ set_attack_coefficients/2
+ ]
+).
+
+-export
+(
+ [
+ new/1,
+ get_spendable_points/0
+ ]
+).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+-spec increase_accuracy_by
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+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.
+
+-spec increase_range_by
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+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
+ )
+ };
+
+ false ->
+ {
+ Weapon#proto_weapon{ range = NewDamageModifier },
+ (Amount * ?WEAPON_ATTRIBUTE_RANGE_COST)
+ }
+ end.
+
+-spec increase_type_by
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {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)
+ }
+ end.
+
+-spec increase_critical_hit_chance_by
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+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.
+
+-spec increase_double_hit_chance_by
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+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.
+
+
+-spec increase_attack_score_by
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {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
+ {
+ 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
+ )
+ };
+
+ false ->
+ {
+ Weapon#proto_weapon
+ {
+ attack_score = NewAttackScore,
+ attack =
+ blc_damage_type:generate_entries_from_score
+ (
+ NewAttackScore,
+ Weapon#proto_weapon.attack_coef
+ )
+ },
+ (Amount * ?ATTRIBUTE_ATTACK_SCORE_COST)
+ }
+ end.
+
+-spec set_attack_coefficients
+ (
+ list(blc_damage_type:coefficient()),
+ proto_weapon()
+ )
+ -> proto_weapon().
+set_attack_coefficients (Coefficients, Weapon) ->
+ {Result, 0} =
+ increase_attack_score_by
+ (
+ 0,
+ Weapon#proto_weapon
+ {
+ attack_coef = blc_damage_type:sort_entries(Coefficients)
+ }
+ ),
+
+ Result.
+
+-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
+ }
+ ),
+
+ Result.
+
+-spec increase_range_for
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+increase_range_for (GivenPoints, Weapon) ->
+ AmountOfIncrease = trunc(GivenPoints / ?WEAPON_ATTRIBUTE_RANGE_COST),
+ {Result, SpentPoints} = increase_range_by(AmountOfIncrease, Weapon),
+ {Result, (GivenPoints - SpentPoints)}.
+
+-spec increase_type_for
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {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)}.
+
+-spec increase_accuracy_for
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+increase_accuracy_for (GivenPoints, Weapon) ->
+ AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_ACCURACY_COST),
+ {Result, SpentPoints} = increase_accuracy_by(AmountOfIncrease, Weapon),
+ {Result, (GivenPoints - SpentPoints)}.
+
+-spec increase_critical_hit_chance_for
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+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)}.
+
+-spec increase_double_hit_chance_for
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+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)}.
+
+
+-spec increase_attack_score_for
+ (
+ non_neg_integer(),
+ proto_weapon()
+ )
+ -> {proto_weapon(), non_neg_integer()}.
+increase_attack_score_for (GivenPoints, Weapon) ->
+ AmountOfIncrease = trunc(GivenPoints / ?ATTRIBUTE_ATTACK_SCORE_COST),
+ {Result, SpentPoints} = increase_attack_score_by(AmountOfIncrease, Weapon),
+ {Result, (GivenPoints - SpentPoints)}.
+
+
+-spec get_spendable_points () -> non_neg_integer().
+get_spendable_points () -> ?SPENDABLE_WEAPON_POINTS.