summaryrefslogtreecommitdiff |
diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/battle/struct/btl_conditions.erl | 524 |
1 files changed, 405 insertions, 119 deletions
diff --git a/src/battle/struct/btl_conditions.erl b/src/battle/struct/btl_conditions.erl index a0150c1..c984437 100644 --- a/src/battle/struct/btl_conditions.erl +++ b/src/battle/struct/btl_conditions.erl @@ -24,7 +24,7 @@ { category :: shr_condition:id(), triggers :: ordsets:ordset(shr_condition:trigger()), - parameters :: tuple(), + parameters :: any(), visibility :: visibility() } ). @@ -67,6 +67,7 @@ get_parameters/1, set_parameters/3, % IX, Value, Conditions ataxia_set_parameters/3, % IX, Value, Conditions + ataxia_set_parameters/4, % IX, Value, Conditions get_triggers/1, set_triggers/3, % IX, Value, Conditions @@ -93,8 +94,7 @@ ( [ apply_to_character/5, - apply_to_battle/4, - update_from_reference/3 + apply_to_battle/4 ] ). @@ -108,36 +108,24 @@ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% LOCAL FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% --spec ataxia_apply_trigger +-spec apply_trigger ( shr_condition:context(_ReadOnlyDataType, VolatileDataType), + fun((non_neg_integer()) -> ref()), btl_character_turn_update:type(), ordsets:ordset(non_neg_integer()), type() ) - -> - { - VolatileDataType, - ataxic:basic(), - btl_character_turn_update:type() - }. -ataxia_apply_trigger (Context, S0Update, RelevantIndices, Conditions) -> + -> {VolatileDataType, btl_character_turn_update:type()}. +apply_trigger (Context, IXtoRef, S0Update, RelevantIndices, Conditions) -> {Trigger, ReadOnlyData, S0VolatileData} = Context, ConditionCollection = Conditions#btl_conds.collection, - {LastVolatileData, LastUpdate, AllUpdateActions} = + {LastVolatileData, LastUpdate} = ordsets:fold ( - fun - ( - IX, - { - CurrentVolatileData, - CurrentUpdate, - UpdateActions - } - ) -> + fun (IX, {CurrentVolatileData, CurrentUpdate}) -> case orddict:find(IX, ConditionCollection) of {ok, Condition} -> Module = @@ -146,7 +134,7 @@ ataxia_apply_trigger (Context, S0Update, RelevantIndices, Conditions) -> shr_condition:from_id(Condition#btl_cond.category) ), - {NextVolatileData, NextUpdate, UpdateAction} = + {NextVolatileData, NextUpdate} = erlang:apply ( Module, @@ -159,33 +147,24 @@ ataxia_apply_trigger (Context, S0Update, RelevantIndices, Conditions) -> % made to itself by previous conditions. % This comes at the cost of an additional Condition % lookup, but whatever. - Condition, + IXtoRef(IX), CurrentUpdate, {Trigger, ReadOnlyData, CurrentVolatileData} ] ), - { - NextVolatileData, - NextUpdate, - case UpdateAction of - none -> UpdateActions; - _ -> [{IX, UpdateAction}|UpdateActions] - end - }; + {NextVolatileData, NextUpdate}; error -> - % TODO: add a 'cleanup' update. - {CurrentVolatileData, CurrentUpdate, UpdateActions} + % TODO: Remove the condition. + {CurrentVolatileData, CurrentUpdate} end end, {S0VolatileData, S0Update, []}, RelevantIndices ), - ConditionsAtaxiaUpdate = updates_to_ataxic_update(AllUpdateActions), - - {LastVolatileData, ConditionsAtaxiaUpdate, LastUpdate}. + {LastVolatileData, LastUpdate}. -spec compute_next_index (type()) -> non_neg_integer(). compute_next_index (Conditions) -> @@ -257,6 +236,335 @@ get_relevant_condition_indices(Trigger, Conditions) -> %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +%%%% Accessors %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +-spec get_condition (ref(), btl_character_turn_update:type()) -> single(). +get_condition ({battle, IX}, Update) -> + orddict:find + ( + IX, + btl_battle:get_conditions(btl_character_turn_update:get_battle(Update)) + ); +get_condition ({char, CharIX, CondIX}, Update) -> + orddict:find + ( + CondIX, + btl_character:get_conditions + ( + btl_battle:get_character + ( + CharIX, + btl_character_turn_update:get_battle(Update) + ) + ) + ). + +%%%%%%%%%%%%%%%%%%%% +%%%% Visibility %%%% +%%%%%%%%%%%%%%%%%%%% +-spec get_visibility (single()) -> visibility(). +get_visibility (Condition) -> Condition#btl_cond.visibility. + +-spec set_visibility (non_neg_integer(), visibility(), type()) -> type(). +set_visibility (IX, NewVisibility, Conditions) -> + Conditions#btl_conds + { + collection = + orddict:update + ( + IX, + fun (Condition) -> + Condition#btl_cond{ visibility = NewVisibility } + end, + Conditions#btl_conds.collection + ) + }. + +-spec ataxia_set_visibility + ( + non_neg_integer(), + visibility(), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_set_visibility (IX, NewVisibility, Conditions) -> + { + set_visibility(IX, NewVisibility, Conditions), + ataxic:update_field + ( + #btl_conds.collection, + ataxic_sugar:update_orddict_element + ( + IX, + ataxic:update_field + ( + #btl_cond.visibility, + ataxic:constant(NewVisibility) + ) + ) + ) + }. + +%%%%%%%%%%%%%%%%%% +%%%% Triggers %%%% +%%%%%%%%%%%%%%%%%% +-spec get_triggers (single()) -> ordsets:ordset(shr_condition:trigger()). +get_triggers (Condition) -> Condition#btl_cond.triggers. + +-spec set_triggers + ( + non_neg_integer(), + ordsets:ordset(shr_condition:trigger()), + type() + ) + -> type(). +set_triggers (IX, NewTriggers, Conditions) -> + CurrentCondition = orddict:fetch(IX, Conditions#btl_conds.collection), + CurrentTriggers = CurrentCondition#btl_cond.triggers, + AddedTriggers = ordsets:substract(NewTriggers, CurrentTriggers), + RemovedTriggers = ordsets:substract(CurrentTriggers, NewTriggers), + + S0FromTrigger = + ordsets:fold + ( + fun (Trigger, FromTrigger) -> + orddict:update + ( + Trigger, + fun (ConditionIXs) -> + ordsets:del_element(IX, ConditionIXs) + end, + FromTrigger + ) + end, + Conditions#btl_conds.from_trigger, + RemovedTriggers + ), + + S1FromTrigger = + ordsets:fold + ( + fun (Trigger, FromTrigger) -> + orddict:update + ( + Trigger, + fun (ConditionIXs) -> + ordsets:add_element(IX, ConditionIXs) + end, + FromTrigger + ) + end, + S0FromTrigger, + AddedTriggers + ), + + Conditions#btl_conds + { + from_trigger = S1FromTrigger, + collection = + orddict:update + ( + IX, + fun (Condition) -> Condition#btl_cond{ triggers = NewTriggers } end, + Conditions#btl_conds.collection + ) + }. + +-spec ataxia_set_triggers + ( + non_neg_integer(), + ordsets:ordset(shr_condition:trigger()), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_set_triggers (IX, NewTriggers, Conditions) -> + CurrentCondition = orddict:fetch(IX, Conditions#btl_conds.collection), + CurrentTriggers = CurrentCondition#btl_cond.triggers, + AddedTriggers = ordsets:substract(NewTriggers, CurrentTriggers), + RemovedTriggers = ordsets:substract(CurrentTriggers, NewTriggers), + AtaxicFromTriggerParams = [ataxic:constant(IX), ataxic:current_value()], + + {S0FromTrigger, S0FromTriggerAtaxicUpdates} = + ordsets:fold + ( + fun (Trigger, {FromTrigger, PrevFromTriggerAtaxicUpdates}) -> + { + orddict:update + ( + Trigger, + fun (ConditionIXs) -> + ordsets:del_element(IX, ConditionIXs) + end, + FromTrigger + ), + [ + ataxic_sugar:update_orddict_element + ( + IX, + ataxic:apply_function + ( + ordsets, + del_element, + AtaxicFromTriggerParams + ) + ) + | PrevFromTriggerAtaxicUpdates + ] + } + end, + {Conditions#btl_conds.from_trigger, []}, + RemovedTriggers + ), + + {S1FromTrigger, S1FromTriggerAtaxicUpdates} = + ordsets:fold + ( + fun (Trigger, {FromTrigger, PrevFromTriggerAtaxicUpdates}) -> + { + orddict:update + ( + Trigger, + fun (ConditionIXs) -> + ordsets:add_element(IX, ConditionIXs) + end, + FromTrigger + ), + [ + ataxic_sugar:update_orddict_element + ( + IX, + ataxic:apply_function + ( + ordsets, + add_element, + AtaxicFromTriggerParams + ) + ) + | PrevFromTriggerAtaxicUpdates + ] + } + end, + {S0FromTrigger, S0FromTriggerAtaxicUpdates}, + AddedTriggers + ), + + { + Conditions#btl_conds + { + from_trigger = S1FromTrigger, + collection = + orddict:update + ( + IX, + fun (Condition) -> + Condition#btl_cond{ triggers = NewTriggers } + end, + Conditions#btl_conds.collection + ) + }, + ataxic:sequence + ( + [ + ataxic:update_field + ( + #btl_conds.collection, + ataxic_sugar:update_orddict_element + ( + IX, + ataxic:update_field + ( + #btl_cond.triggers, + ataxic:sequence + ( + [ + ataxic:apply_function + ( + ordsets, + substract, + [ + ataxic:current_value(), + ataxic:constant(RemovedTriggers) + ] + ), + ataxic:apply_function + ( + ordsets, + union, + [ + ataxic:current_value(), + ataxic:constant(AddedTriggers) + ] + ) + ] + ) + ) + ) + ), + ataxic:update_field + ( + #btl_conds.from_trigger, + ataxic:sequence(S1FromTriggerAtaxicUpdates) + ) + ] + ) + }. + +%%%%%%%%%%%%%%%%%%%% +%%%% Parameters %%%% +%%%%%%%%%%%%%%%%%%%% +-spec get_parameters (single()) -> any(). +get_parameters (Condition) -> Condition#btl_cond.parameters. + +-spec set_parameters (non_neg_integer(), any(), type()) -> type(). +set_parameters (IX, NewValue, Conditions) -> + Conditions#btl_conds + { + collection = + orddict:update + ( + IX, + fun (Condition) -> Condition#btl_cond{ parameters = NewValue } end, + Conditions#btl_conds.collection + ) + }. + +-spec ataxia_set_parameters + ( + non_neg_integer(), + any(), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_set_parameters (IX, NewValue, Conditions) -> + ataxia_set_parameters(IX, NewValue, ataxic:constant(NewValue), Conditions). + +-spec ataxia_set_parameters + ( + non_neg_integer(), + any(), + ataxic:basic(), + type() + ) + -> {type(), ataxic:basic()}. +ataxia_set_parameters (IX, NewValue, ParamsAtaxicUpdate, Conditions) -> + { + set_parameters(IX, NewValue, Conditions), + ataxic:update_field + ( + #btl_conds.collection, + ataxic_sugar:update_orddict_element + ( + IX, + ataxic:update_field + ( + #btl_cond.parameters, + ParamsAtaxicUpdate + ) + ) + ) + }. + +%%%% Apply %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec apply_to_character ( non_neg_integer(), @@ -283,57 +591,18 @@ apply_to_character get_relevant_condition_indices(Trigger, CharacterConditions), case ordsets:is_empty(MatchingConditionIndices) of - true -> {S0VolatileData, btl_character_turn_update:type()}; + true -> {S0VolatileData, S1Update}; false -> - { - S1VolatileContext, - ActorConditionsAtaxicUpdate, - S2Update - } = - ataxia_apply_trigger + {S1VolatileContext, S2Update} = + apply_trigger ( {Trigger, ReadOnlyData, S0VolatileData}, + fun (IX) -> {char, ActorIX, IX} end, S1Update, CharacterConditions, MatchingConditionIndices ), - %%%%% 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:apply_basic_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} end. @@ -361,59 +630,29 @@ apply_to_battle case ordsets:is_empty(MatchingConditionIndices) of true -> {S0VolatileData, S0Update}; false -> - { - S1VolatileContext, - BattleConditionsAtaxicUpdate, - S1Update - } = - ataxia_apply_trigger + {S1VolatileContext, S1Update} = + apply_trigger ( {Trigger, ReadOnlyData, S0VolatileData}, + fun (IX) -> {battle, IX} end, S0Update, MatchingConditionIndices, BattleConditions ), - %%%% Battle may have been modified (and very likely has) %%%%%%%%%%%%%% - S1Battle = btl_character_turn_update:get_battle(S1Update), - UpdatedBattleConditions = - ataxic:apply_basic_to - ( - BattleConditionsAtaxicUpdate, - btl_battle:get_conditions(S1Battle) - ), - - {S2Battle, BattleAtaxicUpdate} = - btl_battle:ataxia_set_conditions(UpdatedBattleConditions, S1Battle), - - S1Update = - btl_character_turn_update:ataxia_set_battle - ( - S2Battle, - BattleAtaxicUpdate, - S1Update - ), - {S1VolatileContext, S1Update} end. --spec update_from_reference - ( - ref(), - update(), - btl_character_turn_update:type() - ) - -> btl_character_turn_update:type(). -update_from_reference ({battle, _CondIX}, _UpdateAction, Update) -> - Update; % TODO -update_from_reference ({char, _CharIX, _CondIX}, _UpdateAction, Update) -> - Update. % TODO +%%%% Add/Remove Elements %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%%%%%%%%%%%%% +%%%% Add %%%% +%%%%%%%%%%%%% -spec add ( shr_condition:id(), ordsets:ordset(shr_condition:trigger()), - tuple(), + any(), visibility(), type() ) @@ -466,7 +705,7 @@ add (CondID, Triggers, Params, Visibility, Conditions) -> ( shr_condition:id(), ordsets:ordset(shr_condition:trigger()), - tuple(), + any(), visibility(), type() ) @@ -532,7 +771,7 @@ ataxia_add (CondID, Triggers, Params, Visibility, Conditions) -> Trigger, SetAtaxicUpdate ) - |FromTriggerUpdates + | FromTriggerUpdates ] } end, @@ -564,6 +803,53 @@ ataxia_add (CondID, Triggers, Params, Visibility, Conditions) -> ) }. +%%%%%%%%%%%%%%%% +%%%% Remove %%%% +%%%%%%%%%%%%%%%% +-spec remove (non_neg_integer(), type()) -> type(). +remove (IX, S0Conditions) -> + S1Conditions = set_triggers(IX, ordsets:new(), S0Conditions), + S2Conditions = + S1Conditions#btl_conds + { + collection = orddict:erase(IX, S1Conditions#btl_conds.collection) + }, + + S2Conditions. + +-spec ataxia_remove (non_neg_integer(), type()) -> {type(), ataxic:basic()}. +ataxia_remove (IX, S0Conditions) -> + {S1Conditions, ConditionsAtaxicUpdate1} = + ataxia_set_triggers(IX, ordsets:new(), S0Conditions), + + S2Conditions = + S1Conditions#btl_conds + { + collection = orddict:erase(IX, S1Conditions#btl_conds.collection) + }, + + { + S2Conditions, + ataxic:sequence + ( + ConditionsAtaxicUpdate1, + ataxic:update_field + ( + #btl_conds.collection, + ataxic:apply_function + ( + orddict, + erase, + [ + ataxic:constant(IX), + ataxic:current_value() + ] + ) + ) + ) + }. + +%%%% Other %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -spec new () -> type(). new () -> #btl_conds |