From cc4e39960d3c56fceb2e31c01bf286dccc73615c Mon Sep 17 00:00:00 2001 From: nsensfel Date: Fri, 15 Nov 2019 18:30:00 +0100 Subject: ... --- src/battle/mechanic/condition/btl_cond_heal.erl | 146 +++++++++++++++++++++++- src/battle/struct/btl_character.erl | 10 +- src/battle/struct/btl_condition_parameters.erl | 27 ----- src/shared/shr_roll.erl | 4 +- 4 files changed, 149 insertions(+), 38 deletions(-) diff --git a/src/battle/mechanic/condition/btl_cond_heal.erl b/src/battle/mechanic/condition/btl_cond_heal.erl index e60d1ac..04806ba 100644 --- a/src/battle/mechanic/condition/btl_cond_heal.erl +++ b/src/battle/mechanic/condition/btl_cond_heal.erl @@ -11,8 +11,8 @@ -export ( [ - encode/1, - get_turn_result_encoding/1, +% encode/1, +% get_turn_result_encoding/1, apply/3 ] ). @@ -65,6 +65,136 @@ heal_character (ActorIX, S0Actor, S0HealingAmount) -> } end. +-spec perform_on_target + ( + non_neg_integer(), + non_neg_integer(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +perform_on_target (TargetIX, Power, S0Update) -> + S0Battle = btl_character_turn_update:get_battle(S0Update), + {S0Target, S1Battle} = btl_battle:get_resolved_character(TargetIX, S0Battle), + + case heal_character(TargetIX, S0Target, Power) of + none -> + S1Update = btl_character_turn_update:set_battle(S1Battle, S0Update), + S1Update; + + { + _HealingAmount, + S1Target, + TurnResult, + TargetAtaxicUpdate + } + -> + {S2Battle, BattleAtaxicUpdate} = + btl_battle:ataxic_set_character + ( + TargetIX, + S1Target, + TargetAtaxicUpdate, + S1Battle + ), + + S1Update = + btl_character_turn_update:ataxic_set_battle + ( + S2Battle, + BattleAtaxicUpdate, + S0Update + ), + + S2Update = + btl_character_turn_update:add_to_timeline(TurnResult, S1Update), + + S2Update + end. + +-spec perform_on_location + ( + shr_location:type(), + non_neg_integer(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +perform_on_location (Location, Power, Update) -> + Battle = btl_character_turn_update:get_battle(Update), + Characters = btl_battle:get_characters(Battle), + + MaybeResultIX = + orddict:foldl + ( + fun (IX, Char, CurrentResult) -> + case CurrentResult of + none -> + case (btl_character:get_location(Char) == Location) of + false -> none; + true -> IX + end; + + _ -> CurrentResult + end + end, + none, + Characters + ), + + case MaybeResultIX of + none -> Update; + _ -> perform_on_target(MaybeResultIX, Power, Update) + end. + + +-spec standard_perform + ( + btl_conditions:single(), + btl_character_turn_update:type() + ) + -> btl_character_turn_update:type(). +standard_perform (Condition, S0Update) -> + Parameters = btl_conditions:get_parameters(Condition), + Power = + case btl_condition_parameters:get_other(Condition) of + N when (is_integer(N) and (N >= 0)) -> N; + Other -> + error({param, other, Other}), + 0 + end, + + Chance = btl_condition_parameters:get_chance(Parameters), + Perform = + case Chance of + -1 -> true; + _ -> (Chance =< shr_roll:percentage()) + end, + + case Perform of + false -> S0Update; + true -> + S1Update = + lists:foldl + ( + fun (Location, CurrentUpdate) -> + perform_on_location(Location, Power, CurrentUpdate) + end, + S0Update, + btl_condition_parameters:get_locations(Parameters) + ), + + S2Update = + lists:foldl + ( + fun (TargetIX, CurrentUpdate) -> + perform_on_target(TargetIX, Power, CurrentUpdate) + end, + S1Update, + btl_condition_parameters:get_targets(Parameters) + ), + + S2Update + end. + %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %% EXPORTED FUNCTIONS %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -72,10 +202,18 @@ heal_character (ActorIX, S0Actor, S0HealingAmount) -> ( btl_conditions:ref(), btl_character_turn_update:type(), - shr_condition:context(any(), VolatileDataType), + shr_condition:context(any(), VolatileDataType) ) -> {VolatileDataType, btl_character_turn_update:type()}. apply (SelfRef, S0Update, S0Context) -> {_Trigger, _ReadOnlyData, VolatileData} = S0Context, - {VolatileData, S0Update}. + case btl_conditions:get_condition(SelfRef, S0Update) of + none -> {VolatileData, S0Update}; + {ok, S0Condition} -> + % TODO: handle cases where the Volatile Data contains characters that + % might have to be healed. + S1Update = standard_perform(S0Condition, S0Update), + + {VolatileData, S1Update} + end. diff --git a/src/battle/struct/btl_character.erl b/src/battle/struct/btl_character.erl index fa1fcde..9769f8f 100644 --- a/src/battle/struct/btl_character.erl +++ b/src/battle/struct/btl_character.erl @@ -21,7 +21,7 @@ { player_ix :: non_neg_integer(), rank :: rank(), - location :: {non_neg_integer(), non_neg_integer()}, + location :: shr_location:type(), current_health :: integer(), %% Negative integers let us reverse attacks. skill_points :: integer(), %% Negative integers let us reverse skill uses. is_active :: boolean(), @@ -37,7 +37,7 @@ { player_ix :: non_neg_integer(), rank :: rank(), - location :: {non_neg_integer(), non_neg_integer()}, + location :: shr_location:type(), current_health :: integer(), %% Negative integers let us reverse attacks. skill_points :: integer(), %% Negative integers let us reverse skill uses. is_active :: boolean(), @@ -156,7 +156,7 @@ get_player_index (#btl_char_ref{ player_ix = R }) -> R. get_rank (#btl_char{ rank = R }) -> R; get_rank (#btl_char_ref{ rank = R }) -> R. --spec get_location (either()) -> {non_neg_integer(), non_neg_integer()}. +-spec get_location (either()) -> shr_location:type(). get_location (#btl_char{ location = R }) -> R; get_location (#btl_char_ref{ location = R }) -> R. @@ -225,7 +225,7 @@ ataxia_set_rank (Rank, Char) -> -spec set_location ( - {non_neg_integer(), non_neg_integer()}, + shr_location:type(), shr_omnimods:type(), type() ) @@ -261,7 +261,7 @@ set_location (Location, LocOmnimods, Char) -> -spec ataxia_set_location ( - {non_neg_integer(), non_neg_integer()}, + shr_location:type(), shr_omnimods:type(), type() ) diff --git a/src/battle/struct/btl_condition_parameters.erl b/src/battle/struct/btl_condition_parameters.erl index 280e37c..eb78245 100644 --- a/src/battle/struct/btl_condition_parameters.erl +++ b/src/battle/struct/btl_condition_parameters.erl @@ -10,7 +10,6 @@ targets :: list(non_neg_integer()), locations :: list(shr_location:type()), uses :: (non_neg_integer() | -1), - duration :: (non_neg_integer() | -1), chance :: (0..100 | -1), other :: any() } @@ -40,10 +39,6 @@ set_uses/2, ataxia_set_uses/2, - get_duration/1, - set_duration/2, - ataxia_set_duration/2, - get_chance/1, set_chance/2, ataxia_set_chance/2, @@ -115,28 +110,6 @@ ataxia_set_uses (Uses, Params) -> ataxic:update_field(#btl_cond_params.uses, ataxic:constant(Uses)) }. -%%%%%%%%%%%%%%%%%% -%%%% Duration %%%% -%%%%%%%%%%%%%%%%%% --spec get_duration (type(_)) -> (non_neg_integer() | -1). -get_duration (Params) -> Params#btl_cond_params.duration. - --spec set_duration ((non_neg_integer() | -1), type(ODT)) -> type(ODT). -set_duration (Duration, Params) -> - Params#btl_cond_params{ duration = Duration }. - --spec ataxia_set_duration - ( - (non_neg_integer() | -1), - type(ODT) - ) - -> {type(ODT), ataxic:basic()}. -ataxia_set_duration (Duration, Params) -> - { - set_duration(Duration, Params), - ataxic:update_field(#btl_cond_params.duration, ataxic:constant(Duration)) - }. - %%%%%%%%%%%%%%%% %%%% Chance %%%% %%%%%%%%%%%%%%%% diff --git a/src/shared/shr_roll.erl b/src/shared/shr_roll.erl index eb0f21e..2c75ca6 100644 --- a/src/shared/shr_roll.erl +++ b/src/shared/shr_roll.erl @@ -45,9 +45,9 @@ between (Min, Max) -> Diff = (Max - Min), (Min + (rand:uniform(Diff + 1) - 1)). --spec percentage () -> 0..100. +-spec percentage () -> 1..100. percentage () -> - between(0, 100). + between(1, 100). -spec percentage_with_luck ( -- cgit v1.2.3-70-g09d2