summaryrefslogtreecommitdiff |
diff options
-rw-r--r-- | include/tacticians/attributes.hrl.m4 | 20 | ||||
-rw-r--r-- | src/balancer/blc_distribution.erl | 2 | ||||
-rw-r--r-- | src/balancer/struct/blc_weapon.erl | 324 | ||||
-rw-r--r-- | src/shared/struct/inventory/shr_armor.erl.m4 | 2 | ||||
-rw-r--r-- | src/shared/struct/inventory/shr_weapon.erl.m4 | 3 |
5 files changed, 333 insertions, 18 deletions
diff --git a/include/tacticians/attributes.hrl.m4 b/include/tacticians/attributes.hrl.m4 index 3c0e731..7acfc25 100644 --- a/include/tacticians/attributes.hrl.m4 +++ b/include/tacticians/attributes.hrl.m4 @@ -4,58 +4,58 @@ m4_include(__MAKEFILE_DATA_DIR/names.m4.conf) -define(ATTRIBUTE_DAMAGE_MODIFIER_MIN, 0). -define(ATTRIBUTE_DAMAGE_MODIFIER_MAX, 300). -define(ATTRIBUTE_DAMAGE_MODIFIER_DEFAULT, 100). --define(ATTRIBUTE_DAMAGE_MODIFIER_COST, 1). +-define(ATTRIBUTE_DAMAGE_MODIFIER_COST, 10). -define(ATTRIBUTE_MOVEMENT_POINTS, __SN_MOVEMENT_POINTS). -define(ATTRIBUTE_MOVEMENT_POINTS_MIN, 8). -define(ATTRIBUTE_MOVEMENT_POINTS_MAX, 200). -define(ATTRIBUTE_MOVEMENT_POINTS_DEFAULT, 32). --define(ATTRIBUTE_MOVEMENT_POINTS_COST, 1). +-define(ATTRIBUTE_MOVEMENT_POINTS_COST, 10). -define(ATTRIBUTE_HEALTH, __SN_MAX_HEALTH). -define(ATTRIBUTE_HEALTH_MIN, 1). -define(ATTRIBUTE_HEALTH_MAX, 500). -define(ATTRIBUTE_HEALTH_DEFAULT, 100). --define(ATTRIBUTE_HEALTH_COST, 1). +-define(ATTRIBUTE_HEALTH_COST, 10). -define(ATTRIBUTE_DODGE_CHANCE, __SN_DODGE). -define(ATTRIBUTE_DODGE_CHANCE_MIN, 0). -define(ATTRIBUTE_DODGE_CHANCE_MAX, 175). -define(ATTRIBUTE_DODGE_CHANCE_DEFAULT, 50). --define(ATTRIBUTE_DODGE_CHANCE_COST, 1). +-define(ATTRIBUTE_DODGE_CHANCE_COST, 10). -define(ATTRIBUTE_PARRY_CHANCE, __SN_PARRY). -define(ATTRIBUTE_PARRY_CHANCE_MIN, 0). -define(ATTRIBUTE_PARRY_CHANCE_MAX, 100). -define(ATTRIBUTE_PARRY_CHANCE_DEFAULT, 5). --define(ATTRIBUTE_PARRY_CHANCE_COST, 1). +-define(ATTRIBUTE_PARRY_CHANCE_COST, 10). -define(ATTRIBUTE_ACCURACY, __SN_ACCURACY). -define(ATTRIBUTE_ACCURACY_MIN, 0). -define(ATTRIBUTE_ACCURACY_MAX, 100). -define(ATTRIBUTE_ACCURACY_DEFAULT, 50). --define(ATTRIBUTE_ACCURACY_COST, 1). +-define(ATTRIBUTE_ACCURACY_COST, 10). -define(ATTRIBUTE_DOUBLE_HIT_CHANCE, __SN_DOUBLE_HITS). -define(ATTRIBUTE_DOUBLE_HIT_CHANCE_MIN, 0). -define(ATTRIBUTE_DOUBLE_HIT_CHANCE_MAX, 100). -define(ATTRIBUTE_DOUBLE_HIT_CHANCE_DEFAULT, 5). --define(ATTRIBUTE_DOUBLE_HIT_CHANCE_COST, 1). +-define(ATTRIBUTE_DOUBLE_HIT_CHANCE_COST, 10). -define(ATTRIBUTE_CRITICAL_HIT_CHANCE, __SN_CRITICAL_HIT). -define(ATTRIBUTE_CRITICAL_HIT_CHANCE_MIN, 0). -define(ATTRIBUTE_CRITICAL_HIT_CHANCE_MAX, 100). -define(ATTRIBUTE_CRITICAL_HIT_CHANCE_DEFAULT, 10). --define(ATTRIBUTE_CRITICAL_HIT_CHANCE_COST, 1). +-define(ATTRIBUTE_CRITICAL_HIT_CHANCE_COST, 10). -define(ATTRIBUTE_DEFENSE_SCORE, def_score). -define(ATTRIBUTE_DEFENSE_SCORE_MIN, 0). -define(ATTRIBUTE_DEFENSE_SCORE_MAX, 300). -define(ATTRIBUTE_DEFENSE_SCORE_DEFAULT, 50). --define(ATTRIBUTE_DEFENSE_SCORE_COST, 1). +-define(ATTRIBUTE_DEFENSE_SCORE_COST, 10). -define(ATTRIBUTE_ATTACK_SCORE, atk_score). -define(ATTRIBUTE_ATTACK_SCORE_MIN, 0). -define(ATTRIBUTE_ATTACK_SCORE_MAX, 300). -define(ATTRIBUTE_ATTACK_SCORE_DEFAULT, 50). --define(ATTRIBUTE_ATTACK_SCORE_COST, 1). +-define(ATTRIBUTE_ATTACK_SCORE_COST, 10). diff --git a/src/balancer/blc_distribution.erl b/src/balancer/blc_distribution.erl index a305dd4..3e114f4 100644 --- a/src/balancer/blc_distribution.erl +++ b/src/balancer/blc_distribution.erl @@ -25,7 +25,7 @@ ) -> list(list(0..100)). generate_internals (0, CurrentResult, _Sequence) -> - CurrentResult; + lists:filter(fun (E) -> (lists:sum(E) == 100) end, CurrentResult); generate_internals (N, CurrentResult, Sequence) -> generate_internals ( diff --git a/src/balancer/struct/blc_weapon.erl b/src/balancer/struct/blc_weapon.erl index 970c4e5..84d0383 100644 --- a/src/balancer/struct/blc_weapon.erl +++ b/src/balancer/struct/blc_weapon.erl @@ -1,11 +1,15 @@ -module(blc_weapon). -include("tacticians/attributes.hrl"). +-include("tacticians/damage_types.hrl"). +-define(WEAPON_ATTRIBUTE_RANGE, rnge). -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_RANGE_COST, 200). + +-define(WEAPON_RANGED_DEFENSE_RANGE, 1). -define ( @@ -109,7 +113,10 @@ ( [ new/2, - get_remaining_points/1 + get_remaining_points/1, + generate/4, + export/1, + finalize/1 ] ). @@ -118,11 +125,35 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec increase_attribute_by ( - shr_attributes:enum(), + (shr_attributes:enum() | ?WEAPON_ATTRIBUTE_RANGE), non_neg_integer(), type() ) -> ({ok, type()} | blc_error:type()). +increase_attribute_by (?WEAPON_ATTRIBUTE_RANGE, S0Amount, Weapon) -> + CurrentValue = Weapon#proto_weapon.range, + + S1Amount = + case ((CurrentValue + S0Amount) > ?WEAPON_ATTRIBUTE_RANGE_MAX) of + true -> (?WEAPON_ATTRIBUTE_RANGE_MAX - CurrentValue); + false -> S0Amount + end, + + Cost = (S1Amount * ?WEAPON_ATTRIBUTE_RANGE_COST), + RemainingPoints = Weapon#proto_weapon.remaining_points, + + case (Cost > RemainingPoints) of + true -> {error, balance, RemainingPoints, Cost}; + false -> + { + ok, + Weapon#proto_weapon + { + remaining_points = (RemainingPoints - Cost), + range = (CurrentValue + S1Amount) + } + } + end; increase_attribute_by (Attribute, S0Amount, Weapon) -> CurrentOmnimods = Weapon#proto_weapon.omnimods, CurrentValue = @@ -158,6 +189,34 @@ increase_attribute_by (Attribute, S0Amount, Weapon) -> } end. +-spec get_max_attribute_ratio + ( + non_neg_integer(), + shr_attributes:meta_enum() + | ?WEAPON_ATTRIBUTE_RANGE + ) + -> float(). +get_max_attribute_ratio (SpendablePoints, ?WEAPON_ATTRIBUTE_RANGE) -> + Contrib = + ( + ?WEAPON_ATTRIBUTE_RANGE_COST + * (?WEAPON_ATTRIBUTE_RANGE_MAX - ?WEAPON_ATTRIBUTE_RANGE_MIN) + ), + + case (Contrib == 0) of + true -> 0.0; + false -> (SpendablePoints / Contrib) * 100.0 + end; +get_max_attribute_ratio (SpendablePoints, Attribute) -> + {AttMin, _AttDef, AttMax, AttCost} = blc_attribute:get_info(Attribute), + + Contrib = (AttCost * (AttMax - AttMin)), + + case (Contrib == 0) of + true -> 0.0; + false -> (SpendablePoints / Contrib) * 100.0 + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -177,7 +236,7 @@ increase_accuracy_by (Amount, Weapon) -> ) -> ({ok, type()} | blc_error:type()). increase_range_by (Amount, Weapon) -> - increase_attribute_by(?ATTRIBUTE_ACCURACY, Amount, Weapon). + increase_attribute_by(?WEAPON_ATTRIBUTE_RANGE, Amount, Weapon). -spec increase_parry_chance_by ( @@ -187,7 +246,12 @@ increase_range_by (Amount, Weapon) -> -> ({ok, type()} | blc_error:type()). increase_parry_chance_by (Amount, Weapon) -> case (Weapon#proto_weapon.range_type) of - ranged -> {error, incompatible}; + ranged -> + if + (Amount == 0) -> {ok, Weapon}; + true -> {error, incompatible} + end; + _ -> increase_attribute_by(?ATTRIBUTE_PARRY_CHANCE, Amount, Weapon) end. @@ -382,3 +446,253 @@ increase_attack_score_for (GivenPoints, Weapon) -> -spec get_remaining_points (type()) -> non_neg_integer(). get_remaining_points (Weapon) -> Weapon#proto_weapon.remaining_points. + +-spec generate (range_type(), 0..100, 0..100, 0..100) -> list(type()). +generate (RangeType, AttributeMin, AttributeStep, ElementStep) -> + BasePoints = + case RangeType of + ranged -> ?RANGED_SPENDABLE_WEAPON_POINTS; + melee -> ?MELEE_SPENDABLE_WEAPON_POINTS + end, + + MaxAccuracy = get_max_attribute_ratio(BasePoints, ?ATTRIBUTE_ACCURACY), + MaxCriticalHitChance = + get_max_attribute_ratio(BasePoints, ?ATTRIBUTE_CRITICAL_HIT_CHANCE), + MaxDoubleHitChance = + get_max_attribute_ratio(BasePoints, ?ATTRIBUTE_DOUBLE_HIT_CHANCE), + MaxRange = get_max_attribute_ratio(BasePoints, ?WEAPON_ATTRIBUTE_RANGE), + MaxParryChance = + get_max_attribute_ratio(BasePoints, ?ATTRIBUTE_PARRY_CHANCE), + MaxAttackScore = + get_max_attribute_ratio(BasePoints, ?ATTRIBUTE_ATTACK_SCORE), + + AttributeCount = + case RangeType of + melee -> 6; + _ -> 5 + end, + + Distributions = + blc_distribution:generate(AttributeCount, AttributeMin, AttributeStep), + + ValidDistributions = + lists:filtermap + ( + fun (Input) -> + [ + Accuracy, + CriticalHitChance, + DoubleHitChance, + Range, + AttackScore + | MaybeParryChance + ] + = Input, + ParryChance = + case MaybeParryChance of + [] -> 0; + [E] -> E + end, + if + (Accuracy > MaxAccuracy) -> false; + (CriticalHitChance > MaxCriticalHitChance) -> false; + (DoubleHitChance > MaxDoubleHitChance) -> false; + (Range > MaxRange) -> false; + (ParryChance > MaxParryChance) -> false; + (AttackScore > MaxAttackScore) -> false; + true -> + { + true, + [ + {?ATTRIBUTE_ACCURACY, Accuracy}, + {?ATTRIBUTE_CRITICAL_HIT_CHANCE, CriticalHitChance}, + {?ATTRIBUTE_DOUBLE_HIT_CHANCE, DoubleHitChance}, + {?WEAPON_ATTRIBUTE_RANGE, Range}, + {?ATTRIBUTE_ATTACK_SCORE, AttackScore}, + {?ATTRIBUTE_PARRY_CHANCE, ParryChance}%, + ] + } + end + end, + Distributions + ), + + BaseWeaponsCoefs = [{?DAMAGE_TYPE_SLASH, 100}], + + + BaseWeapon = new(RangeType, BaseWeaponsCoefs), + + BaseWeapons = + lists:map + ( + fun (Distribution) -> + PointsUsed = + lists:map + ( + fun ({Attribute, Percent}) -> + { + Attribute, + trunc((BasePoints * Percent) / 100) + } + end, + Distribution + ), + + FinalWeapon = + lists:foldl + ( + fun ({Attribute, Points}, Weapon) -> + case Attribute of + ?ATTRIBUTE_ATTACK_SCORE -> + {ok, NewWeapon} = + increase_attack_score_for(Points, Weapon), + NewWeapon; + + ?ATTRIBUTE_CRITICAL_HIT_CHANCE -> + {ok, NewWeapon} = + increase_critical_hit_chance_for(Points, Weapon), + NewWeapon; + + ?WEAPON_ATTRIBUTE_RANGE -> + {ok, NewWeapon} = + increase_range_for(Points, Weapon), + NewWeapon; + + ?ATTRIBUTE_ACCURACY -> + {ok, NewWeapon} = + increase_accuracy_for(Points, Weapon), + NewWeapon; + + ?ATTRIBUTE_PARRY_CHANCE -> + {ok, NewWeapon} = + increase_parry_chance_for(Points, Weapon), + NewWeapon; + + ?ATTRIBUTE_DOUBLE_HIT_CHANCE -> + {ok, NewWeapon} = + increase_double_hit_chance_for(Points, Weapon), + NewWeapon + end + end, + BaseWeapon, + PointsUsed + ), + + lists:foldl + ( + fun ({Attribute, _}, Weapon) -> + NewWeapon = + case Attribute of + ?ATTRIBUTE_ATTACK_SCORE -> + increase_attack_score_for + ( + Weapon#proto_weapon.remaining_points, + Weapon + ); + + ?WEAPON_ATTRIBUTE_RANGE-> + increase_range_for + ( + Weapon#proto_weapon.remaining_points, + Weapon + ); + + _ -> increase_attribute_by(Attribute, 1, Weapon) + end, + + case NewWeapon of + {ok, NextWeapon} -> NextWeapon; + _ -> Weapon + end + end, + FinalWeapon, + lists:sort + ( + fun ({_AttributeA, ScoreA}, {_AttributeB, ScoreB}) -> + (ScoreA > ScoreB) + end, + lists:map + ( + fun (Attribute) -> + case Attribute of + ?ATTRIBUTE_ATTACK_SCORE -> + { + ?ATTRIBUTE_ATTACK_SCORE, + FinalWeapon#proto_weapon.attack_score + }; + + _ -> + { + Attribute, + shr_omnimods:get_attribute_modifier + ( + Attribute, + FinalWeapon#proto_weapon.omnimods + ) + } + end + end, + [ + ?ATTRIBUTE_ATTACK_SCORE, + ?ATTRIBUTE_CRITICAL_HIT_CHANCE, + ?WEAPON_ATTRIBUTE_RANGE, + ?ATTRIBUTE_ACCURACY, + ?ATTRIBUTE_DOUBLE_HIT_CHANCE + ] + ) + ) + ) + end, + ValidDistributions + ), + + shr_lists_util:product + ( + fun (Weapon, ElementDistribution) -> + set_attack_coefficients(ElementDistribution, Weapon) + end, + BaseWeapons, + lists:map + ( + fun ([A, B, C]) -> + [ + {?DAMAGE_TYPE_SLASH, A}, + {?DAMAGE_TYPE_PIERCE, B}, + {?DAMAGE_TYPE_BLUNT, C} + ] + end, + blc_distribution:generate(3, ElementStep) + ) + ). + +-spec export (type()) -> list(). +export (Weapon) -> + Range = Weapon#proto_weapon.range, + {DefenseRange, AttackRange} = + case Weapon#proto_weapon.range_type of + melee -> {0, (Range + 1)}; + ranged -> + { + (?WEAPON_RANGED_DEFENSE_RANGE + Range), + (?WEAPON_RANGED_DEFENSE_RANGE + Range + 2) + } + end, + ( + io_lib:format(" ~B,~n ~B,~n", [DefenseRange, AttackRange]) + ++ shr_omnimods:export(Weapon#proto_weapon.omnimods) + ). + +-spec finalize (type()) -> + { + range_type(), + non_neg_integer(), + shr_omnimods:type(), + non_neg_integer() + }. +finalize (Weapon) -> + { + Weapon#proto_weapon.range_type, + Weapon#proto_weapon.range, + Weapon#proto_weapon.omnimods, + Weapon#proto_weapon.remaining_points + }. diff --git a/src/shared/struct/inventory/shr_armor.erl.m4 b/src/shared/struct/inventory/shr_armor.erl.m4 index bdcd249..adbb20b 100644 --- a/src/shared/struct/inventory/shr_armor.erl.m4 +++ b/src/shared/struct/inventory/shr_armor.erl.m4 @@ -61,7 +61,7 @@ get_omnimods (Ar) -> Ar#armor.omnimods. -spec from_id (id()) -> type(). m4_include(__MAKEFILE_DATA_DIR/armor/global.m4.conf)m4_dnl -m4_include(__MAKEFILE_DATA_DIR/armor/20_20_20.m4d)m4_dnl +m4_include(__MAKEFILE_DATA_DIR/armor/10_25_25.m4d)m4_dnl from_id(_) -> default(). diff --git a/src/shared/struct/inventory/shr_weapon.erl.m4 b/src/shared/struct/inventory/shr_weapon.erl.m4 index b2c6734..8492189 100644 --- a/src/shared/struct/inventory/shr_weapon.erl.m4 +++ b/src/shared/struct/inventory/shr_weapon.erl.m4 @@ -75,7 +75,8 @@ get_omnimods (Wp) -> Wp#weapon.omnimods. -spec from_id (id()) -> type(). m4_include(__MAKEFILE_DATA_DIR/weapon/global.m4.conf)m4_dnl -m4_include(__MAKEFILE_DATA_DIR/weapon/basic.m4d)m4_dnl +m4_include(__MAKEFILE_DATA_DIR/weapon/primary_melee_10_20_25.m4d)m4_dnl +m4_include(__MAKEFILE_DATA_DIR/weapon/primary_ranged_5_25_25.m4d)m4_dnl m4_include(__MAKEFILE_DATA_DIR/weapon/secondary.m4d)m4_dnl from_id (_) -> default(). |