| summaryrefslogtreecommitdiff | 
diff options
| author | nsensfel <SpamShield0@noot-noot.org> | 2019-10-10 18:01:19 +0200 | 
|---|---|---|
| committer | nsensfel <SpamShield0@noot-noot.org> | 2019-10-10 18:01:19 +0200 | 
| commit | 0ba5f0743083e88c7edb9bfa4a5093b3aef30157 (patch) | |
| tree | 89852054b4e13ff29245d6808ebd2d0af45ad4c1 | |
| parent | ab4bcc69e713c9cc8d6d5577cc2d85e5f36eb26a (diff) | |
...
| -rw-r--r-- | src/battle/mechanic/action/btl_action_attack.erl | 265 | ||||
| -rw-r--r-- | src/battle/struct/btl_condition.erl | 106 | ||||
| -rw-r--r-- | src/shared/struct/shr_condition.erl | 3 | 
3 files changed, 176 insertions, 198 deletions
| diff --git a/src/battle/mechanic/action/btl_action_attack.erl b/src/battle/mechanic/action/btl_action_attack.erl index 863ddb4..219c3cd 100644 --- a/src/battle/mechanic/action/btl_action_attack.erl +++ b/src/battle/mechanic/action/btl_action_attack.erl @@ -20,87 +20,123 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -spec apply_conditions     ( -      shr_condition:trigger(), -      ParameterType, +      shr_condition:context(A, B), +      btl_character:type(),        btl_character_turn_update:type()     ) -   -> {ParameterType, btl_character_turn_update:type()}. +   -> {shr_condition:context(A, B), btl_character_turn_update:type()}.  apply_conditions  ( -   TriggerName, -   S0Parameter, +   Context = {Trigger, _ReadOnlyContext, _VolatileContext},     Actor,     S0Update  ) -> -   { -      {TriggerName, S1Parameter}, -      S1Update -   } = +   {LastContext, S1Update} =        btl_condition:recursive_apply        ( -         btl_character:get_conditions_on(TriggerName, Actor), -         {TriggerName, S0Parameter}, +         btl_character:get_conditions_on(Trigger, Actor), +         Context,           S0Update        ), -   {S1Parameter, S1Update}. --spec roll_precision_modifier +   {LastContext, S1Update}. + +-spec roll_for_precision     ( -      shr_attributes:type(), -      shr_attributes:type(), +      btl_character:type(), +      integer(), +      btl_character:type(),        integer()     ) -   -> {float(), integer(), integer()}. -roll_precision_modifier (Attributes, TargetAttributes, TargetLuck) -> -   TargetDodges = shr_attributes:get_dodge_chance(TargetAttributes), -   Accuracy = shr_attributes:get_accuracy(Attributes), -   MissChance = max(0, (TargetDodges - Accuracy)), +   -> {btl_attack:precision(), integer(), integer()}. +roll_for_precision (Actor, ActorLuck, Target, TargetLuck) -> +   TargetDodgeChance = +      shr_attributes:get_dodge_chance +      ( +         shr_character:get_attributes +         ( +            btl_character:get_base_character(Target) +         ) +      ), +   ActorAccuracy = +      shr_attributes:get_accuracy +      ( +         shr_character:get_attributes +         ( +            btl_character:get_base_character(Actor) +         ) +      ), + +   MissChance = max(0, (TargetDodgeChance - ActorAccuracy)),     {Roll, _IsSuccess, PositiveModifier, NegativeModifier} =        shr_roll:percentage_with_luck(MissChance, TargetLuck),     { -      case Roll of -         X when (X =< MissChance) -> 0.0; -         X when (X =< (MissChance * 2)) -> 0.5; -         _ -> 1.0 -      end, -      PositiveModifier, -      NegativeModifier +      ( +         if +            (Roll =< MissChance) -> misses; +            (Roll =< (MissChance * 2)) -> grazes; +            true -> hits +         end +      ), +      (ActorLuck + NegativeModifier), % Negative effects are for Actor. +      (TargetLuck + PositiveModifier) % Positive effects are for Target.     }. --spec roll_critical_modifier +-spec roll_for_critical_hit     ( -      shr_attributes:type(), +      btl_character:type(), +      integer(), +      btl_character:type(),        integer()     ) -   -> {float(), integer(), integer()}. -roll_critical_modifier (Attributes, Luck) -> -   CriticalHitChance = shr_attributes:get_critical_hit_chance(Attributes), +   -> {boolean(), integer(), integer()}. +roll_for_critical_hit (Actor, ActorLuck, _Target, TargetLuck) -> +   ActorCriticalHitChance = +      shr_attributes:get_critical_hit_chance +      ( +         shr_character:get_attributes +         ( +            btl_character:get_base_character(Actor) +         ) +      ), +     {_Roll, IsSuccess, PositiveModifier, NegativeModifier} = -      shr_roll:percentage_with_luck(CriticalHitChance, Luck), +      shr_roll:percentage_with_luck(ActorCriticalHitChance, ActorLuck),     { -      case IsSuccess of -         true -> 2.0; % [TODO][FUTURE]: variable critical multiplier? -         false -> 1.0 -      end, -      PositiveModifier, -      NegativeModifier +      IsSuccess, +      (ActorLuck + PositiveModifier), % Positive effects are for Actor +      (TargetLuck + NegativeModifier) % Negative effects are for Target     }. --spec roll_parry +-spec roll_for_parry     ( -      shr_attributes:type(), +      btl_character:type(), +      integer(), +      btl_character:type(),        integer()     )     -> {boolean(), integer(), integer()}. -roll_parry (DefenderAttributes, DefenderLuck) -> -   DefenderParryChance = shr_attributes:get_parry_chance(DefenderAttributes), +roll_for_parry (_Actor, ActorLuck, Target, TargetLuck) -> +   TargetParryChance = +      shr_attributes:get_critical_hit_chance +      ( +         shr_character:get_attributes +         ( +            btl_character:get_base_character(Target) +         ) +      ), +     {_Roll, IsSuccess, PositiveModifier, NegativeModifier} = -      shr_roll:percentage_with_luck(DefenderParryChance, DefenderLuck), +      shr_roll:percentage_with_luck(TargetParryChance, TargetLuck), -   {IsSuccess, PositiveModifier, NegativeModifier}. +   { +      IsSuccess, +      (ActorLuck + NegativeModifier), % Negative effects are for Actor +      (TargetLuck + PositiveModifier) % Positive effects are for Target +   }.  -spec get_character_abilities     ( @@ -619,50 +655,51 @@ apply_luck_decay (Luck) ->     (        shr_condition:trigger(),        shr_condition:trigger(), -      {btl_action:type(), OtherData}, +      btl_action:type(), +      {any(), VolatileContext},        btl_character_turn_update:type()     ) -   -> {{btl_action:type(), OtherData}, btl_character_turn_update:type()}. +   -> {VolatileContext, btl_character_turn_update:type()}.  apply_mirror_conditions  (     OwnTriggerName,     OtherTriggerName, -   {S0Action, S0Data}, +   Action, +   {ReadOnlyContext, S0VolatileContext},     S0Update  ) -> -   CharacterIX = btl_action:get_actor_index(S0Action), +   CharacterIX = btl_action:get_actor_index(Action),     S0Battle = btl_character_turn_update:get_battle(S0Update),     {Character, S1Battle} =        btl_battle:get_resolved_character(CharacterIX, S0Battle),     S1Update = btl_character_turn_update:set_battle(S1Battle, S0Update), -   {{S1Action, S1Data}, S2Update} = +   {{_TriggerName, _ReadOnlyContext, S1VolatileContext}, S2Update} =        apply_conditions        ( -         OwnTriggerName, -         {S0Action, S0Data}, +         {OwnTriggerName, ReadOnlyContext, S0VolatileContext},           Character,           S1Update        ), -   TargetCharacterIX = btl_action:get_target_index(S1Action), +   TargetCharacterIX = btl_action:get_target_index(Action),     S2Battle = btl_character_turn_update:get_battle(S2Update), +     {TargetCharacter, S3Battle} =        btl_battle:get_resolved_character(TargetCharacterIX, S2Battle),     S3Update = btl_character_turn_update:set_battle(S3Battle, S2Update), -   {{S2Action, S2Data}, S4Update} = +   {{_TriggerName, _ReadOnlyContext, S2VolatileContext}, S4Update} =        apply_conditions        ( -         OtherTriggerName, -         {S1Action, S1Data}, +         {OtherTriggerName, ReadOnlyContext, S1VolatileContext},           TargetCharacter,           S3Update        ), -   {{S2Action, S2Data}, S4Update}. +   {S2VolatileContext, S4Update}.  -spec handle_start_of_attack     ( @@ -671,70 +708,92 @@ apply_mirror_conditions        btl_character_turn_update:type()     )     -> -   { -      list(btl_attack:category()), -      btl_action:type(), -      btl_character_turn_update:type() -   }. -handle_start_of_attack (S0AttackSequence, S0Action, S0Update) -> -   S1Update = add_targeting_event(S0Action, S0Update), +   {list(btl_attack:category()), btl_character_turn_update:type() }. +handle_start_of_attack (S0AttackSequence, Action, S0Update) -> +   S1Update = add_targeting_event(Action, S0Update), -   {{S1Action, S1AttackSequence}, S2Update} = +   {S1AttackSequence, S2Update} =        apply_mirror_conditions        (           ?CONDITION_TRIGGER_START_OF_OWN_ATTACK,           ?CONDITION_TRIGGER_START_OF_OTHER_ATTACK, -         {S0Action, S0AttackSequence}, +         Action, +         {Action, S0AttackSequence},           S1Update        ), -   {S1AttackSequence, S1Action, S2Update}. +   {S1AttackSequence, S2Update}.  -spec handle_end_of_attack     (        btl_action:type(),        btl_character_turn_update:type()     ) -   -> {btl_action:type(), btl_character_turn_update:type()}. -handle_end_of_attack (S0Action, S0Update) -> -   {{S1Action, _PlaceHolder}, S1Update} = +   -> btl_character_turn_update:type(). +handle_end_of_attack (Action, S0Update) -> +   {_None, S1Update} =        apply_mirror_conditions        (           ?CONDITION_TRIGGER_END_OF_OWN_ATTACK,           ?CONDITION_TRIGGER_END_OF_OTHER_ATTACK, -         {S0Action, ok}, +         Action, +         {Action, none},           S0Update        ), -   {S1Action, S1Update}. +   S1Update. --spec handle_first_hit +-spec handle_hit     ( +      btl_attack:category(),        list(btl_attack:category()),        btl_action:type(),        btl_character_turn_update:type()     ) -   -> -   { -      list(btl_attack:category()), -      btl_action:type(), -      btl_character_turn_update:type() -   }. -handle_first_hit (S0Sequence, S0Action, S0Update) -> -   {BaseActor, BaseTarget, S1Update} = get_actors(S0Action, S0Update), -   {{_S1Action, {ModdedActor, ModdedTarget}}, S2Update} = +   -> {list(btl_attack:category()), btl_character_turn_update:type()}. +handle_hit (AttackCategory, S0Sequence, Action, S0Update) -> +   {BaseActor, S0ActorLuck, BaseTarget, S0TargetLuck, S1Update} = +      get_actors_and_lucks(AttackCategory, S0Action, S0Update), + +   {{S0ModdedActor, S0ModdedTarget, S1Sequence}, S2Update} =        apply_mirror_conditions        ( -         ?CONDITION_TRIGGER_INITIAL_DATA_FOR_OWN_HIT, -         ?CONDITION_TRIGGER_INITIAL_DATA_FOR_OTHER_HIT, -         {S0Action, {BaseActor, BaseTarget}}, +         ?CONDITION_TRIGGER_ACTORS_DEFINITION_FOR_OWN_HIT, +         ?CONDITION_TRIGGER_ACTORS_DEFINITION_FOR_OTHER_HIT, +         Action, +         {{Action, AttackCategory}, {BaseActor, BaseTarget, S0Sequence}},           S1Update        ), -   case can_perform(ModdedActor, ModdedTarget) of -      false -> {S0Sequence, S0Action, S2Update}; +   case can_perform_attack(S0ModdedActor, S0ModdedTarget) of +      false -> {S1Sequence, S2Update};        true -> -         {HitData, S1Update} = get_hit_data(S0Action, S0Update), +         {S0IsParry, S1ActorLuck, S1TargetLuck} = +            roll_for_parry +            ( +               S0ModdedActor, +               S0ActorLuck, +               S0ModdedTarget, +               S0TargetLuck +            ), +         { +            {S1IsParry, S1ModdedActor, S1ModdedTarget, S2Sequence}, +            S3Update +         } = +            apply_mirror_conditions +            ( +               ?CONDITION_TRIGGER_ACTORS_DEFINITION_FOR_OTHER_PARRY, +               ?CONDITION_TRIGGER_ACTORS_DEFINITION_FOR_OWN_PARRY, +               Action, +               { +                  {Action, AttackCategory}, +                  {S0IsParry, S0ModdedActor, S0ModdedTarget, S1Sequence} +               }, +               S2Update +            ), + +         % TODO +         {S2Sequence, S3Update}     end.  -spec handle_attack_sequence @@ -743,21 +802,13 @@ handle_first_hit (S0Sequence, S0Action, S0Update) ->        btl_action:type(),        btl_character_turn_update:type()     ) -   -> {btl_action:type(), btl_character_turn_update:type()}. +   -> btl_character_turn_update:type().  handle_attack_sequence ([], Action, Update) ->     {Action, Update}; -handle_attack_sequence ([first|S0NextElements], S0Action, S0Update) -> -   {S1NextElements, S1Action, S1Update} = -      handle_first_hit(S0NextElements, S0Action, S0Update), -   handle_attack_sequence(S1NextElements, S1Action, S1Update); -handle_attack_sequence ([second|S0NextElements], S0Action, S0Update) -> -   {S1NextElements, S1Action, S1Update} = -      handle_second_hit(S0NextElements, S0Action, S0Update), -   handle_attack_sequence(S1NextElements, S1Action, S1Update); -handle_attack_sequence ([counter|S0NextElements], S0Action, S0Update) -> -   {S1NextElements, S1Action, S1Update} = -      handle_counter_hit(S0NextElements, S0Action, S0Update), -   handle_attack_sequence(S1NextElements, S1Action, S1Update). +handle_attack_sequence ([AttackCategory|S0NextElements], Action, S0Update) -> +   {S1NextElements, S1Update} = +      handle_hit(AttackCategory, S0NextElements, Action, S0Update), +   handle_attack_sequence(S1NextElements, Action, S1Update).  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -768,16 +819,14 @@ handle_attack_sequence ([counter|S0NextElements], S0Action, S0Update) ->        btl_character_turn_update:type()     )     -> btl_character_turn_update:type(). -handle (S0Action, S0Update) -> +handle (Action, S0Update) ->     S0Sequence = [first, counter, second], -   {S1Sequence, S1Action, S1Update} = -      handle_start_of_attack(S0Sequence, S0Action, S0Update), - -   {S2Action, S2Update} = -      handle_attack_sequence(S1Sequence, S1Action, S1Update), +   {S1Sequence, S1Update} = +      handle_start_of_attack(S0Sequence, Action, S0Update), -   {_S3Action, S3Update} = handle_end_of_attack(S2Action, S2Update), +   S2Update = handle_attack_sequence(S1Sequence, Action, S1Update), +   S3Update = handle_end_of_attack(S2Action, S2Update),     S3Update. diff --git a/src/battle/struct/btl_condition.erl b/src/battle/struct/btl_condition.erl index 2954c13..24ef084 100644 --- a/src/battle/struct/btl_condition.erl +++ b/src/battle/struct/btl_condition.erl @@ -5,78 +5,6 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -include("tacticians/conditions.hrl"). --type trigger() :: -   ( -      { -         ( -            ?CONDITION_TRIGGER_START_OF_PLAYER_TURN -            | ?CONDITION_TRIGGER_END_OF_PLAYER_TURN -         ), -         non_neg_integer() -      } - -      | -         { -            ( -               ?CONDITION_TRIGGER_START_OF_CHARACTER_TURN -               | ?CONDITION_TRIGGER_END_OF_CHARACTER_TURN -               | ?CONDITION_WEAPON_SWITCH -               | ?CONDITION_TRIGGER_SKILL_USE -               | ?CONDITION_TRIGGER_DEATH -            ), -            non_neg_integer() -         } - -      | -         { -            ( -               ?CONDITION_TRIGGER_START_OF_OWN_ATTACK -               | ?CONDITION_TRIGGER_END_OF_OWN_ATTACK -               | ?CONDITION_TRIGGER_START_OF_OWN_HIT -               | ?CONDITION_TRIGGER_END_OF_OWN_HIT -               | ?CONDITION_TRIGGER_OWN_DODGE -               | ?CONDITION_TRIGGER_OWN_CRITICAL -               | ?CONDITION_TRIGGER_OWN_DOUBLE_HIT -               | ?CONDITION_TRIGGER_OWN_DAMAGE -               | ?CONDITION_TRIGGER_START_OF_TARGET_ATTACK -               | ?CONDITION_TRIGGER_END_OF_TARGET_ATTACK -               | ?CONDITION_TRIGGER_START_OF_TARGET_HIT -               | ?CONDITION_TRIGGER_END_OF_TARGET_HIT -               | ?CONDITION_TRIGGER_TARGET_DODGE -               | ?CONDITION_TRIGGER_TARGET_CRITICAL -               | ?CONDITION_TRIGGER_TARGET_DOUBLE_HIT -               | ?CONDITION_TRIGGER_TARGET_DAMAGE -            ), -            { -               non_neg_integer(), -               btl_character:type(), -               non_neg_integer(), -               btl_character:type() -            } -         } - -      | -         { -            ( -               ?CONDITION_TRIGGER_START_OF_MOVEMENT -               | ?CONDITION_TRIGGER_END_OF_MOVEMENT -            ), -            { -               non_neg_integer(), -               list(shr_direction:type()) -            } -         } - -      | -         { -            ( -               ?CONDITION_TRIGGER_START_OF_BATTLE -               | ?CONDITION_TRIGGER_END_OF_BATTLE -            ), -            none -         } -   ). -  -type update_action() :: (none, remove, {update, ataxic:basic()}).  -record @@ -93,7 +21,7 @@  -opaque type() :: #btl_cond{}. --export_type([type/0, trigger/0, update_action/0]). +-export_type([type/0, update_action/0]).  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -303,50 +231,50 @@ get_parameters_field () -> #btl_cond.parameters.  -spec apply     (        type(), -      trigger(), +      shr_condition:context(),        btl_character_turn_update:type()     ) -   -> {trigger(), btl_character_turn_update:type()}. -apply (S0Condition, S0Trigger, S0Update) -> +   -> {shr_condition:context(), btl_character_turn_update:type()}. +apply (S0Condition, S0Context, S0Update) ->     Module = shr_condition_selector:get_module(get_category(S0Condition)), -   {S1Condition, UpdateAction, S1Trigger, S1Update} = -      erlang:apply(Module, apply, [S0Trigger, S0Condition, S0Update]), +   {S1Condition, UpdateAction, S1Context, S1Update} = +      erlang:apply(Module, apply, [S0Context, S0Condition, S0Update]),     case UpdateAction of -      none -> {S1Trigger, S1Update}; +      none -> {S1Context, S1Update};        remove ->           % TODO -         {S1Trigger, S1Update}; +         {S1Context, S1Update};        {update, ConditionUpdate} ->           % TODO -         {S1Trigger, S1Update} +         {S1Context, S1Update}     end.  -spec recursive_apply     (        list(type()), -      trigger(), +      shr_condition:context(),        btl_character_turn_update:type()     ) -   -> {trigger(), btl_character_turn_update:type()}. -recursive_apply (Conditions, S0Trigger, S0Update) -> -   [LastTrigger, LastUpdate] = +   -> {shr_condition:context(), btl_character_turn_update:type()}. +recursive_apply (Conditions, S0Context, S0Update) -> +   [LastContext, LastUpdate] =        lists:foldl        (           fun (Condition, Parameters) -> -            {NextTrigger, NextUpdate} = +            {NextContext, NextUpdate} =                 erlang:apply(btl_condition, apply, [Condition|Parameters]), -            [NextTrigger, NextUpdate] +            [NextContext, NextUpdate]           end, -         [S0Trigger, S0Update], +         [S0Context, S0Update],           Conditions        ), -   {LastTrigger, LastUpdate}. +   {LastContext, LastUpdate}.  -spec encode (type()) -> {list({binary(), any()})}.  encode (Condition) -> {[]} % TODO. diff --git a/src/shared/struct/shr_condition.erl b/src/shared/struct/shr_condition.erl index 6d75167..13c3426 100644 --- a/src/shared/struct/shr_condition.erl +++ b/src/shared/struct/shr_condition.erl @@ -5,6 +5,7 @@  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  -type id() :: ataxia_id:type().  -type trigger() :: atom(). +-type context(ReadOnly, Volatile) :: {trigger(), ReadOnly, Volatile}.  -record  ( @@ -20,7 +21,7 @@  -opaque type() :: #condition{}. --export_type([id/0, type/0, trigger/0]). +-export_type([id/0, type/0, trigger/0, context/2]).  %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | 


