| 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(). | 


