From cdb5923969af99911840eec19373c7f55e5ebf6a Mon Sep 17 00:00:00 2001 From: Nathanael Sensfelder Date: Sat, 12 Oct 2019 22:27:44 +0200 Subject: ... --- include/tacticians/conditions.hrl | 11 +- src/battle/mechanic/action/btl_action_attack.erl | 374 +++++++++++------------ src/battle/struct/btl_character.erl | 40 +-- src/battle/struct/btl_condition.erl | 188 +++++------- 4 files changed, 281 insertions(+), 332 deletions(-) diff --git a/include/tacticians/conditions.hrl b/include/tacticians/conditions.hrl index be0f98e..5c0f82a 100644 --- a/include/tacticians/conditions.hrl +++ b/include/tacticians/conditions.hrl @@ -1,26 +1,35 @@ -define(CONDITION_TRIGGER_START_OF_OWN_ATTACK, soowa). -define(CONDITION_TRIGGER_START_OF_OTHER_ATTACK, soota). +-define(CONDITION_TRIGGER_START_OF_ANY_ATTACK, soana). -define(CONDITION_TRIGGER_END_OF_OWN_ATTACK, eoowa). -define(CONDITION_TRIGGER_END_OF_OTHER_ATTACK, eoota). +-define(CONDITION_TRIGGER_END_OF_ANY_ATTACK, eoana). -define(CONDITION_TRIGGER_COMPUTED_OWN_ATTACK_DAMAGE, cowad). --define(CONDITION_TRIGGER_COMPUTER_OTHER_ATTACK_DAMAGE, cotad). +-define(CONDITION_TRIGGER_COMPUTED_OTHER_ATTACK_DAMAGE, cotad). +-define(CONDITION_TRIGGER_COMPUTED_ANY_ATTACK_DAMAGE, canad). -define(CONDITION_TRIGGER_END_OF_OWN_HIT, eoowh). -define(CONDITION_TRIGGER_END_OF_OTHER_HIT, eooth). +-define(CONDITION_TRIGGER_END_OF_ANY_HIT, eoanh). -define(CONDITION_TRIGGER_ROLLED_FOR_OWN_CRITICAL_HITS, rfowch). -define(CONDITION_TRIGGER_ROLLED_FOR_OTHER_CRITICAL_HITS, rfotch). +-define(CONDITION_TRIGGER_ROLLED_FOR_ANY_CRITICAL_HITS, rfanch). -define(CONDITION_TRIGGER_ROLLED_FOR_OWN_PRECISION, rfowpr). -define(CONDITION_TRIGGER_ROLLED_FOR_OTHER_PRECISION, rfotpr). +-define(CONDITION_TRIGGER_ROLLED_FOR_ANY_PRECISION, rfanpr). -define(CONDITION_TRIGGER_ROLLED_FOR_OWN_PARRY, rfowpa). -define(CONDITION_TRIGGER_ROLLED_FOR_OTHER_PARRY, rfotpa). +-define(CONDITION_TRIGGER_ROLLED_FOR_ANY_PARRY, rfanpa). -define(CONDITION_TRIGGER_ROLLED_FOR_OWN_DOUBLE_HITS, rfowdh). -define(CONDITION_TRIGGER_ROLLED_FOR_OTHER_DOUBLE_HITS, rfotdh). +-define(CONDITION_TRIGGER_ROLLED_FOR_ANY_DOUBLE_HITS, rfandh). -define(CONDITION_TRIGGER_DEFINED_ACTORS_FOR_OWN_HIT, dafowh). -define(CONDITION_TRIGGER_DEFINED_ACTORS_FOR_OTHER_HIT, dafoth). +-define(CONDITION_TRIGGER_DEFINED_ACTORS_FOR_ANY_HIT, dafanh). diff --git a/src/battle/mechanic/action/btl_action_attack.erl b/src/battle/mechanic/action/btl_action_attack.erl index 0cc0718..f4f3c3f 100644 --- a/src/battle/mechanic/action/btl_action_attack.erl +++ b/src/battle/mechanic/action/btl_action_attack.erl @@ -18,46 +18,172 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec apply_conditions +-spec should_reverse_roles (boolean(), btl_attack:category()) -> boolean(). +should_reverse_roles (IsParry, AttackCategory) -> ( - shr_condition:context(A, B), - btl_character:type(), + ((AttackCategory == counter) and (IsParry == false)) + or ((AttackCategory =/= counter) and (IsParry == true)) + ). + +-spec apply_condition_to_character + ( + non_neg_integer(), + shr_condition:trigger(), + any(), + VolatileDataType, btl_character_turn_update:type() ) - -> + -> {VolatileDataType, btl_character_turn_update:type()}. +apply_condition_to_character +( + ActorIX, + Trigger, + ReadOnlyData, + S0VolatileData, + S0Update +) -> + S0Battle = btl_character_turn_update:get_battle(S0Update), + {S0Actor, S1Battle} = btl_battle:get_resolved_character(ActorIX, S0Battle), + S1Update = btl_character_turn_update:set_battle(S1Battle, S0Update), + { - shr_condition:context(A, B), - btl_character:type(), - ataxic:basic(), + S1VolatileContext, + ActorConditionsAtaxicUpdate, + S2Update + } = + btl_condition:ataxia_apply_trigger + ( + {Trigger, ReadOnlyData, S0VolatileData}, + S1Update, + btl_character:get_conditions(S0Actor) + ), + + %%%%% Actor and Battle may have been modified %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + S1Battle = btl_character_turn_update:get_battle(S2Update), + {S1Actor, S2Battle} = btl_battle:get_resolved_character(ActorIX, S1Battle), + S0Conditions = btl_character:get_conditions(S1Actor), + + S1Conditions = + ataxic:basic_apply_to(ActorConditionsAtaxicUpdate, S0Conditions), + + {S2Actor, ActorAtaxicUpdate} = + btl_character:ataxia_set_conditions + ( + S1Conditions, + ActorConditionsAtaxicUpdate, + S1Actor + ), + + {S3Battle, BattleAtaxicUpdate} = + btl_battle:ataxia_set_character + ( + ActorIX, + S2Actor, + ActorAtaxicUpdate, + S2Battle + ), + + S2Update = + btl_character_turn_update:ataxia_set_battle + ( + S3Battle, + BattleAtaxicUpdate, + S1Update + ), + + {S1VolatileContext, S2Update}. + +-spec apply_mirror_conditions + ( + boolean(), + shr_condition:trigger(), + shr_condition:trigger(), + shr_condition:trigger(), + btl_action:type(), + {any(), VolatileDataType}, btl_character_turn_update:type() - }. -apply_conditions + ) + -> {VolatileDataType, btl_character_turn_update:type()}. +apply_mirror_conditions ( - Context = {Trigger, _ReadOnlyContext, _VolatileContext}, - S0Actor, + ReverseRoles, + OwnTriggerName, + OtherTriggerName, + GlobalTriggerName, + Action, + {ReadOnlyContext, S0VolatileContext}, S0Update ) -> - {LastContext, S1Update, ConditionUpdates} = - btl_condition:recursive_apply + {ActorIX, TargetIX} = + case ReverseRoles of + false -> + { + btl_action:get_actor_index(Action), + btl_action:get_target_index(Action) + }; + true -> + { + btl_action:get_target_index(Action), + btl_action:get_actor_index(Action) + } + end, + + {S1VolatileContext, S1Update} = + apply_condition_to_character ( - btl_character:get_conditions_on(Trigger, S0Actor), - Context, + ActorIX, + OwnTriggerName, + ReadOnlyContext, + S0VolatileContext, S0Update ), - S0AllConditions = btl_character:get_conditions(S0Actor), - {S1AllConditions, AllConditionsAtaxiaUpdate} = - btl_condition:ataxia_apply_updates(ConditionUpdates, S0AllConditions), + {S2VolatileContext, S2Update} = + apply_condition_to_character + ( + TargetIX, + OtherTriggerName, + ReadOnlyContext, + S1VolatileContext, + S1Update + ), + + S0Battle = btl_character_turn_update:get_battle(S2Update), - {S1Actor, ActorAtaxiaUpdate} = - btl_character:ataxia_set_conditions + { + S3VolatileContext, + BattleConditionsAtaxicUpdate, + S5Update + } = + btl_condition:ataxia_apply_trigger ( - S1AllConditions, - AllConditionsAtaxiaUpdate, - S0Actor + {GlobalTriggerName, ReadOnlyContext, S2VolatileContext}, + S2Update, + btl_battle:get_conditions(S0Battle) ), - {LastContext, S1Actor, ActorAtaxiaUpdate, S1Update}. + %%%% Battle may have been modified (and very likely has) %%%%%%%%%%%%%%%%%%%% + S1Battle = btl_character_turn_update:get_battle(S2Update), + UpdatedBattleConditions = + ataxic:basic_apply_to + ( + btl_battle:get_conditions(S1Battle), + BattleConditionsAtaxicUpdate + ), + + {S2Battle, BattleAtaxicUpdate} = + btl_battle:ataxia_set_conditions(UpdatedBattleConditions, S1Battle), + + S5Update = + btl_character_turn_update:ataxia_set_battle + ( + S2Battle, + BattleAtaxicUpdate, + S2Update + ), + + {S3VolatileContext, S2Update}. -spec roll_for_precision ( @@ -214,154 +340,6 @@ can_perform_hit (Actor, Target) -> (btl_character:get_is_alive(Actor) and btl_character:get_is_alive(Target)) }. --spec apply_mirror_conditions - ( - boolean(), - shr_condition:trigger(), - shr_condition:trigger(), - btl_action:type(), - {any(), VolatileContext}, - btl_character_turn_update:type() - ) - -> {VolatileContext, btl_character_turn_update:type()}. -apply_mirror_conditions -( - false, - OwnTriggerName, - OtherTriggerName, - Action, - {ReadOnlyContext, S0VolatileContext}, - S0Update -) -> - ActorIX = btl_action:get_actor_index(Action), - S0Battle = btl_character_turn_update:get_battle(S0Update), - {S0Actor, S1Battle} = btl_battle:get_resolved_character(ActorIX, S0Battle), - S1Update = btl_character_turn_update:set_battle(S1Battle, S0Update), - - { - {_TriggerName, _ReadOnlyContext, S1VolatileContext}, - S1Actor, - ActorAtaxiaUpdate, - S2Update - } = - apply_conditions - ( - {OwnTriggerName, ReadOnlyContext, S0VolatileContext}, - S0Actor, - S1Update - ), - - TargetIX = btl_action:get_target_index(Action), - S2Battle = btl_character_turn_update:get_battle(S2Update), - S3Battle = - btl_battle:ataxia_set_character - ( - ActorIX, - S1Actor, - ActorAtaxiaUpdate, - S2Battle - ), - - {Target, S4Battle} = btl_battle:get_resolved_character(TargetIX, S3Battle), - S3Update = btl_character_turn_update:set_battle(S4Battle, S2Update), - - { - {_TriggerName, _ReadOnlyContext, S2VolatileContext}, - S1Target, - TargetAtaxiaUpdate, - S4Update - } = - apply_conditions - ( - {OtherTriggerName, ReadOnlyContext, S1VolatileContext}, - Target, - S3Update - ), - - S5Battle = btl_character_turn_update:get_battle(S4Update), - S6Battle = - btl_battle:ataxia_set_character - ( - TargetIX, - S1Target, - TargetAtaxiaUpdate, - S5Battle - ), - - S5Update = btl_character_turn_update:set_battle(S6Battle, S4Update), - - {S2VolatileContext, S5Update}; -apply_mirror_conditions -( - true, - OwnTriggerName, - OtherTriggerName, - Action, - {ReadOnlyContext, S0VolatileContext}, - S0Update -) -> - TargetIX = btl_action:get_target_index(Action), - S0Battle = btl_character_turn_update:get_battle(S0Update), - - {S0Target, S1Battle} = - btl_battle:get_resolved_character(TargetIX, S0Battle), - - S1Update = btl_character_turn_update:set_battle(S1Battle, S0Update), - - { - {_TriggerName, _ReadOnlyContext, S1VolatileContext}, - S1Target, - TargetAtaxiaUpdate, - S2Update - } = - apply_conditions - ( - {OwnTriggerName, ReadOnlyContext, S0VolatileContext}, - S0Target, - S1Update - ), - - ActorIX = btl_action:get_actor_index(Action), - S2Battle = btl_character_turn_update:get_battle(S2Update), - {S0Actor, S3Battle} = btl_battle:get_resolved_character(ActorIX, S2Battle), - - S4Battle = - btl_battle:ataxia_set_character - ( - TargetIX, - S1Target, - TargetAtaxiaUpdate, - S3Battle - ), - - S3Update = btl_character_turn_update:set_battle(S4Battle, S2Update), - - { - {_TriggerName, _ReadOnlyContext, S2VolatileContext}, - S1Actor, - ActorAtaxiaUpdate, - S4Update - } = - apply_conditions - ( - {OtherTriggerName, ReadOnlyContext, S1VolatileContext}, - S0Actor, - S3Update - ), - - S5Battle = btl_character_turn_update:get_battle(S4Update), - S6Battle = - btl_battle:ataxia_set_character - ( - ActorIX, - S1Actor, - ActorAtaxiaUpdate, - S5Battle - ), - - S5Update = btl_character_turn_update:set_battle(S6Battle, S4Update), - - {S2VolatileContext, S5Update}. -spec handle_start_of_attack ( @@ -389,6 +367,7 @@ handle_start_of_attack (S0AttackSequence, Action, S0Update) -> false, ?CONDITION_TRIGGER_START_OF_OWN_ATTACK, ?CONDITION_TRIGGER_START_OF_OTHER_ATTACK, + ?CONDITION_TRIGGER_START_OF_ANY_ATTACK, Action, {Action, S0AttackSequence}, S1Update @@ -409,6 +388,7 @@ handle_end_of_attack (Action, S0Update) -> false, ?CONDITION_TRIGGER_END_OF_OWN_ATTACK, ?CONDITION_TRIGGER_END_OF_OTHER_ATTACK, + ?CONDITION_TRIGGER_END_OF_ANY_ATTACK, Action, {Action, none}, S0Update @@ -428,15 +408,15 @@ commit_luck_change (Character, NewLuck, S0Update) -> S0Battle = btl_character_turn_update:get_battle(S0Update), S0Player = btl_battle:get_player(PlayerIX, S0Battle), - {S1Player, PlayerAtaxiaUpdate} = + {S1Player, PlayerAtaxicUpdate} = btl_player:ataxia_set_luck(NewLuck, S0Player), - {S1Battle, BattleAtaxiaUpdate} = + {S1Battle, BattleAtaxicUpdate} = btl_battle:set_player ( PlayerIX, S1Player, - PlayerAtaxiaUpdate, + PlayerAtaxicUpdate, S0Battle ), @@ -444,7 +424,7 @@ commit_luck_change (Character, NewLuck, S0Update) -> btl_character_turn_update:set_battle ( S1Battle, - BattleAtaxiaUpdate, + BattleAtaxicUpdate, S0Update ), @@ -515,14 +495,14 @@ get_actors (_Category, Action, Update) -> -spec commit_hit ( + boolean(), + btl_battle:precision(), + boolean(), btl_character:type(), btl_character:type(), list(btl_attack:category()), btl_attack:category(), btl_action:type(), - boolean(), - btl_battle:precision(), - boolean(), btl_character_turn_update:type() ) -> {list(btl_attack:category()), btl_character_turn_update:type()}. @@ -539,12 +519,7 @@ commit_hit S0Update ) -> {ActorIX, TargetIX} = - case - ( - ((AttackCategory == counter) and (IsParry == false)) - or ((AttackCategory =/= counter) and (IsParry == true)) - ) - of + case should_reverse_roles(IsParry, AttackCategory) of true -> { btl_action:get_target_index(Action), @@ -591,9 +566,10 @@ commit_hit } = apply_mirror_conditions ( - IsParry, + should_reverse_roles(IsParry, AttackCategory), ?CONDITION_TRIGGER_COMPUTED_OWN_ATTACK_DAMAGE, - ?CONDITION_TRIGGER_COMPUTER_OTHER_ATTACK_DAMAGE, + ?CONDITION_TRIGGER_COMPUTED_OTHER_ATTACK_DAMAGE, + ?CONDITION_TRIGGER_COMPUTED_ANY_ATTACK_DAMAGE, Action, { { @@ -612,19 +588,19 @@ commit_hit S0Battle = btl_character_turn_update:get_battle(S1Update), {S0Target, S1Battle} = btl_battle:get_resolved_character(TargetIX, S0Battle), - {S1Target, TargetAtaxiaUpdate} = + {S1Target, TargetAtaxicUpdate} = btl_character:ataxia_set_current_health ( (btl_character:get_current_health(S0Target) - S1AttackDamage), S0Target ), - {S1Battle, BattleAtaxiaUpdate} = + {S1Battle, BattleAtaxicUpdate1} = btl_battle:set_character ( TargetIX, S1Target, - TargetAtaxiaUpdate, + TargetAtaxicUpdate, S0Battle ), @@ -632,7 +608,7 @@ commit_hit btl_character_turn_update:ataxia_set_battle ( S1Battle, - BattleAtaxiaUpdate, + BattleAtaxicUpdate1, S1Update ), @@ -660,9 +636,10 @@ commit_hit } = apply_mirror_conditions ( - IsParry, + should_reverse_roles(IsParry, AttackCategory), ?CONDITION_TRIGGER_END_OF_OWN_HIT, ?CONDITION_TRIGGER_END_OF_OTHER_HIT, + ?CONDITION_TRIGGER_END_OF_ANY_HIT, Action, { { @@ -733,9 +710,10 @@ handle_critical_hit } = apply_mirror_conditions ( - IsParry, + should_reverse_roles(IsParry, AttackCategory), ?CONDITION_TRIGGER_ROLLED_FOR_OWN_CRITICAL_HITS, ?CONDITION_TRIGGER_ROLLED_FOR_OTHER_CRITICAL_HITS, + ?CONDITION_TRIGGER_ROLLED_FOR_ANY_CRITICAL_HITS, Action, { {Action, AttackCategory, IsParry, Precision}, @@ -821,9 +799,10 @@ handle_precision } = apply_mirror_conditions ( - IsParry, + should_reverse_roles(IsParry, AttackCategory), ?CONDITION_TRIGGER_ROLLED_FOR_OWN_PRECISION, ?CONDITION_TRIGGER_ROLLED_FOR_OTHER_PRECISION, + ?CONDITION_TRIGGER_ROLLED_FOR_ANY_PRECISION, Action, { {Action, AttackCategory, IsParry}, @@ -906,9 +885,10 @@ handle_parry } = apply_mirror_conditions ( - false, + should_reverse_roles(false, AttackCategory), ?CONDITION_TRIGGER_ROLLED_FOR_OTHER_PARRY, ?CONDITION_TRIGGER_ROLLED_FOR_OWN_PARRY, + ?CONDITION_TRIGGER_ROLLED_FOR_ANY_PARRY, Action, { {Action, AttackCategory}, @@ -987,6 +967,7 @@ handle_double_hits false, ?CONDITION_TRIGGER_ROLLED_FOR_OWN_DOUBLE_HITS, ?CONDITION_TRIGGER_ROLLED_FOR_OTHER_DOUBLE_HITS, + ?CONDITION_TRIGGER_ROLLED_FOR_ANY_DOUBLE_HITS, Action, { Action, @@ -1034,9 +1015,10 @@ handle_hit (AttackCategory, S0Sequence, Action, S0Update) -> {{S0ModdedActor, S0ModdedTarget, S1Sequence}, S2Update} = apply_mirror_conditions ( - false, + should_reverse_roles(false, AttackCategory), ?CONDITION_TRIGGER_DEFINED_ACTORS_FOR_OWN_HIT, ?CONDITION_TRIGGER_DEFINED_ACTORS_FOR_OTHER_HIT, + ?CONDITION_TRIGGER_DEFINED_ACTORS_FOR_ANY_HIT, Action, {{Action, AttackCategory}, {BaseActor, BaseTarget, S0Sequence}}, S1Update diff --git a/src/battle/struct/btl_character.erl b/src/battle/struct/btl_character.erl index 7771b1a..bbf94bb 100644 --- a/src/battle/struct/btl_character.erl +++ b/src/battle/struct/btl_character.erl @@ -25,7 +25,7 @@ is_active :: boolean(), is_defeated :: boolean(), base :: shr_character:unresolved(), - conditions :: orddict:orddict(non_neg_integer(), btl_condition:type()) + conditions :: btl_condition:collection() } ). @@ -40,7 +40,7 @@ is_active :: boolean(), is_defeated :: boolean(), base :: shr_character:type(), - conditions :: orddict:orddict(non_neg_integer(), btl_condition:type()) + conditions :: btl_condition:collection() } ). @@ -95,13 +95,6 @@ ] ). --export -( - [ - get_conditions_on/2 - ] -). - -export ( [ @@ -194,26 +187,11 @@ get_base_character (#btl_char{ base = R }) -> R; get_base_character (#btl_char_ref{ base = R }) -> R. -spec get_conditions - (type()) -> orddict:orddict(non_neg_integer(), btl_condition:type()); + (type()) -> btl_condition:collection(); (unresolved()) -> orddict:orddict(non_neg_integer(), btl_conditions:type()). get_conditions (#btl_char{ conditions = R }) -> R; get_conditions (#btl_char_ref{ conditions = R }) -> R. --spec get_conditions_on - ( - shr_condition:trigger(), - either() - ) - -> orddict:orddict(non_neg_integer(), btl_condition:type()). -get_conditions_on (Trigger, Char) -> - orddict:filter - ( - fun (_IX, Condition) -> - btl_condition:triggers_on(Trigger, Condition) - end, - get_conditions(Char) - ). - -spec set_rank (rank(), type()) -> type(); (rank(), unresolved()) -> unresolved(). @@ -449,12 +427,12 @@ ataxia_set_base_character (NewBaseCharacter, Char) -> -spec set_conditions ( - orddict:orddict(non_neg_integer(), btl_condition:type()), + btl_condition:collection(), type() ) -> type(); ( - orddict:orddict(non_neg_integer(), btl_condition:type()), + btl_condition:collection(), unresolved() ) -> unresolved(). @@ -466,13 +444,13 @@ set_conditions (Conditions, Char) when is_record(Char, btl_char_ref) -> -spec ataxia_set_conditions ( - orddict:orddict(non_neg_integer(), btl_condition:type()), + btl_condition:collection(), ataxic:basic(), type() ) -> {type(), ataxic:basic()}; ( - orddict:orddict(non_neg_integer(), btl_condition:type()), + btl_condition:collection(), ataxic:basic(), unresolved() ) -> {unresolved(), ataxic:basic()}. @@ -488,12 +466,12 @@ ataxia_set_conditions (Conditions, Update, Char) -> -spec ataxia_set_conditions ( - orddict:orddict(non_neg_integer(), btl_condition:type()), + btl_condition:collection(), type() ) -> {type(), ataxic:basic()}; ( - orddict:orddict(non_neg_integer(), btl_condition:type()), + btl_condition:collection(), unresolved() ) -> {unresolved(), ataxic:basic()}. diff --git a/src/battle/struct/btl_condition.erl b/src/battle/struct/btl_condition.erl index fee7279..13d6387 100644 --- a/src/battle/struct/btl_condition.erl +++ b/src/battle/struct/btl_condition.erl @@ -9,7 +9,7 @@ ( none | remove - | {update, type(), ataxic:basic()} + | {update, ataxic:basic()} ). -record @@ -25,8 +25,9 @@ ). -opaque type() :: #btl_cond{}. +-opaque collection() :: orddict:orddict(non_neg_integer(), type()). --export_type([type/0, update_action/0]). +-export_type([type/0, collection/0, update_action/0]). %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -64,11 +65,7 @@ -export ( [ - triggers_on/2, - apply/3, - recursive_apply/3, - apply_updates/2, - ataxia_apply_updates/2 + ataxia_apply_trigger/3 ] ). @@ -89,6 +86,42 @@ -> {list({binary(), any()})}. encode_parameters (_Category, _Parameters) -> {[]}. % TODO. +-spec update_actions_to_ataxic_update + ( + list({non_neg_integer(), update_action()}) + ) + -> ataxic:basic(). +update_actions_to_ataxic_update (Updates) -> + AtaxicSequence = + lists:foldl + ( + fun ({IX, Update}, AtaxicUpdates) -> + case Update of + none -> AtaxicUpdates; + remove -> + [ + ataxic:apply_function + ( + orddict, + erase, + [ataxic:constant(IX), ataxic:current_value()] + ) + |AtaxicUpdates + ]; + + {update, Ataxic} -> + [ + ataxic_sugar:update_orddict_element(IX, Ataxic) + |AtaxicUpdates + ] + end + end, + [], + Updates + ), + + ataxic:sequence(AtaxicSequence). + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -235,123 +268,70 @@ get_duration_field () -> #btl_cond.duration. -spec get_parameters_field () -> non_neg_integer(). get_parameters_field () -> #btl_cond.parameters. --spec apply +-spec ataxia_apply_trigger ( - type(), - shr_condition:context(), - btl_character_turn_update:type() + shr_condition:context(_ReadOnlyDataType, VolatileDataType), + btl_character_turn_update:type(), + collection() ) -> { - shr_condition:context(), - btl_character_turn_update:type(), - update_action() + VolatileDataType, + ataxic:basic(), + btl_character_turn_update:type() }. -apply (Condition, S0Context, S0Update) -> - Module = shr_condition_selector:get_module(get_category(Condition)), - - {S1Context, S1Update, UpdateAction} = - erlang:apply(Module, apply, [S0Context, Condition, S0Update]), - - {S1Context, S1Update, UpdateAction}. +ataxia_apply_trigger (Context, S0Update, Conditions) -> + {Trigger, ReadOnlyData, S0VolatileData} = Context, + RelevantConditions = + orddict:filter + ( + fun (_IX, Condition) -> triggers_on(Trigger, Condition) end, + Conditions + ), --spec recursive_apply - ( - orddict:orddict(IndexType, type()), - shr_condition:context(), - btl_character_turn_update:type() - ) - -> - { - shr_condition:context(), - btl_character_turn_update:type(), - list({IndexType, update_action()}) - }. -recursive_apply (Conditions, S0Context, S0Update) -> - {[LastContext, LastUpdate], AllUpdateActions} = + {LastVolatileData, LastUpdate, AllUpdateActions} = orddict:fold ( - fun (IX, Condition, {Parameters, UpdateActions}) -> - {NextContext, NextUpdate, UpdateAction} = - erlang:apply(btl_condition, apply, [Condition|Parameters]), + fun + ( + IX, + Condition, + { + CurrentVolatileData, + CurrentUpdate, + UpdateActions + } + ) -> + Module = shr_condition_selector:get_module(get_category(Condition)), + {NextVolatileData, NextUpdate, UpdateAction} = + erlang:apply + ( + Module, + apply, + [ + Condition, + CurrentUpdate, + {Trigger, ReadOnlyData, CurrentVolatileData} + ] + ), { - [NextContext, NextUpdate], + NextVolatileData, + NextUpdate, case UpdateAction of none -> UpdateActions; _ -> [{IX, UpdateAction}|UpdateActions] end } end, - [S0Context, S0Update, []], - Conditions + {S0VolatileData, S0Update, []}, + RelevantConditions ), - {LastContext, LastUpdate, AllUpdateActions}. - --spec apply_updates - ( - list({IndexType, update_action()}), - orddict:orddict(IndexType, type()) - ) - -> orddict:orddict(IndexType, type()). -apply_updates (Updates, Conditions) -> - lists:foldl - ( - fun ({IX, Update}, CurrentConditions) -> - case Update of - none -> CurrentConditions; - remove -> orddict:erase(IX, CurrentConditions); - {update, Val, _Ataxic} -> orddict:store(IX, Val, CurrentConditions) - end - end, - Conditions, - Updates - ). - --spec ataxia_apply_updates - ( - list({IndexType, update_action()}), - orddict:orddict(IndexType, type()) - ) - -> {orddict:orddict(IndexType, type()), ataxic:basic()}. -ataxia_apply_updates (Updates, Conditions) -> - {FinalConditions, AtaxicSequence} = - lists:foldl - ( - fun ({IX, Update}, {CurrentConditions, AtaxicUpdates}) -> - case Update of - none -> {CurrentConditions, AtaxicUpdates}; - remove -> - { - orddict:erase(IX, CurrentConditions), - [ - ataxic:apply_function - ( - orddict, - erase, - [ataxic:constant(IX), ataxic:current_value()] - ) - |AtaxicUpdates - ] - }; - - {update, Val, Ataxic} -> - { - orddict:store(IX, Val, CurrentConditions), - [ - ataxic_sugar:update_orddict_element(IX, Ataxic) - |AtaxicUpdates - ] - } - end - end, - Conditions, - Updates - ), + ConditionsAtaxiaUpdate = update_actions_to_ataxic_update(AllUpdateActions), - {FinalConditions, ataxic:sequence(AtaxicSequence)}. + {LastVolatileData, ConditionsAtaxiaUpdate, LastUpdate}. -spec encode (type()) -> {list({binary(), any()})}. encode (Condition) -> {[]}. % TODO -- cgit v1.2.3-70-g09d2