summaryrefslogtreecommitdiff |
diff options
author | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-08-18 16:05:23 +0200 |
---|---|---|
committer | Nathanael Sensfelder <SpamShield0@MultiAgentSystems.org> | 2019-08-18 16:05:23 +0200 |
commit | 5266e24e01611fc8026dfa0498ee87d7fba65e88 (patch) | |
tree | 72c73402dc959f5d618ac850b54d8eb724f60145 /src/balancer/struct/blc_weapon.erl | |
parent | dc742fd9190eadd5eed2e45dd36262ea06550172 (diff) |
...
Diffstat (limited to 'src/balancer/struct/blc_weapon.erl')
-rw-r--r-- | src/balancer/struct/blc_weapon.erl | 414 |
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. |