summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/tacticians/conditions.hrl11
-rw-r--r--src/battle/mechanic/action/btl_action_attack.erl374
-rw-r--r--src/battle/struct/btl_character.erl40
-rw-r--r--src/battle/struct/btl_condition.erl188
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()
}
).
@@ -98,13 +98,6 @@
-export
(
[
- get_conditions_on/2
- ]
-).
-
--export
-(
- [
new/5,
resolve/2,
is_unresolved/1,
@@ -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