summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2019-06-06 11:23:20 +0200
committernsensfel <SpamShield0@noot-noot.org>2019-06-06 11:23:20 +0200
commitbfe469efe993a89f3a8ccbb209b47df1c3e55f2d (patch)
tree6f0435bd1887192c055b8e2ddeb662cb89a27ed3 /src/battle/mechanic
parent1645df02f3f691a6fe4cbb60a65c5c840a99b307 (diff)
[Broken] ...
Diffstat (limited to 'src/battle/mechanic')
-rw-r--r--src/battle/mechanic/action/btl_action_attack.erl560
1 files changed, 336 insertions, 224 deletions
diff --git a/src/battle/mechanic/action/btl_action_attack.erl b/src/battle/mechanic/action/btl_action_attack.erl
index d3ac735..5989ad8 100644
--- a/src/battle/mechanic/action/btl_action_attack.erl
+++ b/src/battle/mechanic/action/btl_action_attack.erl
@@ -74,53 +74,6 @@ roll_parry (DefenderStatistics, DefenderLuck) ->
{IsSuccess, PositiveModifier, NegativeModifier}.
--spec get_damage
- (
- precision(),
- boolean(),
- float(),
- shr_omnimods:type(),
- shr_omnimods:type()
- )
- -> non_neg_integer().
-get_damage
-(
- Precision,
- IsCritical,
- StartingDamageMultiplier,
- AttackerOmnimods,
- DefenderOmnimods
-) ->
- ActualDamageMultiplier =
- (
- StartingDamageMultiplier
- *
- (
- case Precision of
- misses -> 0;
- grazes -> 0.5;
- hits -> 1
- end
- )
- *
- (
- case IsCritical of
- true -> 2;
- _ -> 1
- end
- )
- ),
-
- ActualDamage =
- shr_omnimods:get_attack_damage
- (
- ActualDamageMultiplier,
- AttackerOmnimods,
- DefenderOmnimods
- ),
-
- ActualDamage.
-
-spec get_character_abilities
(
btl_action:type(),
@@ -168,6 +121,119 @@ get_character_abilities (Action, Character, TargetCharacter) ->
)
}.
+-spec compute_luck_changes
+ (
+ integer(),
+ integer(),
+ boolean(),
+ boolean(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer(),
+ integer()
+ )
+ -> {integer(), integer()}.
+compute_luck_changes
+(
+ AttackerLuck,
+ DefenderLuck,
+ ParryIsSuccessful,
+ HitSomething,
+ ParryPositiveLuckMod,
+ ParryNegativeLuckMod,
+ PrecisionPositiveLuckMod,
+ PrecisionNegativeLuckMod,
+ CriticalPositiveLuckMod,
+ CriticalNegativeLuckMod
+) ->
+ case {ParryIsSuccessful, HitSomething} of
+ {true, true} ->
+ {
+ (
+ AttackerLuck
+ % Attacker wasn't the one parrying
+ + ParryNegativeLuckMod
+ % Attacker was the one evading
+ + PrecisionPositiveLuckMod
+ % miss -> no critical hit luck modifier
+ ),
+ (
+ DefenderLuck
+ % Defender was the one parrying
+ + ParryPositiveLuckMod
+ % Defender wasn't the one evading
+ + PrecisionNegativeLuckMod
+ % miss -> no critical hit luck modifier
+ )
+ };
+
+ {true, false} ->
+ {
+ (
+ AttackerLuck
+ % Attacker wasn't the one parrying
+ + ParryNegativeLuckMod
+ % Attacker was the one evading
+ + PrecisionPositiveLuckMod
+ % Attacker wasn't the one doing a critical
+ + CriticalNegativeLuckMod
+ ),
+ (
+ DefenderLuck
+ % Defender was the one parrying
+ + ParryPositiveLuckMod
+ % Defender wasn't the one evading
+ + PrecisionNegativeLuckMod
+ % Defender was the one doing a critical
+ + CriticalPositiveLuckMod
+ )
+ };
+
+ {false, true} ->
+ {
+ (
+ AttackerLuck
+ % Attacker wasn't the one parrying
+ + ParryNegativeLuckMod
+ % Defender was the one evading
+ + PrecisionNegativeLuckMod
+ % miss -> no critical hit luck modifier
+ ),
+ (
+ DefenderLuck
+ % Defender was the one parrying
+ + ParryPositiveLuckMod
+ % Defender was the one evading
+ + PrecisionPositiveLuckMod
+ % miss -> no critical hit luck modifier
+ )
+ };
+
+ {false, false} ->
+ {
+ (
+ AttackerLuck
+ % Attacker wasn't the one parrying
+ + ParryNegativeLuckMod
+ % Attacker wasn't the one evading
+ + PrecisionNegativeLuckMod
+ % Attacker was the one doing a critical
+ + CriticalPositiveLuckMod
+ ),
+ (
+ DefenderLuck
+ % Defender was the one parrying
+ + ParryPositiveLuckMod
+ % Defender was the one evading
+ + PrecisionPositiveLuckMod
+ % Defender wasn't the one doing a critical
+ + CriticalNegativeLuckMod
+ )
+ }
+ end.
+
-spec effect_of_attack
(
btl_attack:category(),
@@ -215,7 +281,7 @@ effect_of_attack
AttackerBaseCharacter = btl_character:get_base_character(Attacker),
AttackerStatistics = shr_character:get_statistics(AttackerBaseCharacter),
- DefenderBaseCharacter = btl_character:get_base_character(Defender),
+ DefenderBaseCharacter = btl_character:get_base_character(S0Defender),
DefenderStatistics = shr_character:get_statistics(DefenderBaseCharacter),
{PrecisionModifier, PrecisionPositiveLuckMod, PrecisionNegativeLuckMod} =
@@ -247,6 +313,7 @@ effect_of_attack
S0AttackerLuck,
S0DefenderLuck,
ParryIsSuccessful,
+ (PrecisionModifier > 0.0),
ParryPositiveLuckMod,
ParryNegativeLuckMod,
PrecisionPositiveLuckMod,
@@ -331,32 +398,49 @@ handle_attack_sequence
Results
)
->
- {
- S1Character,
- S1TargetCharacter,
- S1PlayerLuck,
- S1TargetPlayerLuck,
- Result
- } =
- effect_of_attack
+ case
(
- first,
- S0Character,
- S0TargetCharacter,
- S0PlayerLuck,
- S0TargetPlayerLuck,
- TargetCanParry
- ),
+ (btl_character:get_current_health(S0Character) > 0)
+ and (btl_character:get_current_health(S0Character) > 0)
+ )
+ of
+ true ->
+ {
+ S1Character,
+ S1TargetCharacter,
+ S1PlayerLuck,
+ S1TargetPlayerLuck,
+ Result
+ } =
+ effect_of_attack
+ (
+ first,
+ S0Character,
+ S0TargetCharacter,
+ S0PlayerLuck,
+ S0TargetPlayerLuck,
+ TargetCanParry
+ ),
- handle_attack_sequence
- (
- NextAttacks,
- S1Character,
- S1TargetCharacter,
- S1PlayerLuck,
- S1TargetPlayerLuck,
- [Result|Results]
- );
+ handle_attack_sequence
+ (
+ NextAttacks,
+ S1Character,
+ S1TargetCharacter,
+ S1PlayerLuck,
+ S1TargetPlayerLuck,
+ [Result|Results]
+ );
+
+ false ->
+ {
+ S0Character,
+ S0TargetCharacter,
+ S0PlayerLuck,
+ S0TargetPlayerLuck,
+ lists:reverse(Results)
+ }
+ end;
handle_attack_sequence
(
[{counter, CanParry}|NextAttacks],
@@ -367,32 +451,49 @@ handle_attack_sequence
Results
)
->
- {
- S1TargetCharacter,
- S1Character,
- S1TargetPlayerLuck,
- S1PlayerLuck,
- Result
- } =
- effect_of_attack
+ case
(
- counter,
- S0TargetCharacter,
- S0Character,
- S0TargetPlayerLuck,
- S0PlayerLuck,
- CanParry
- ),
+ (btl_character:get_current_health(S0Character) > 0)
+ and (btl_character:get_current_health(S0Character) > 0)
+ )
+ of
+ true ->
+ {
+ S1TargetCharacter,
+ S1Character,
+ S1TargetPlayerLuck,
+ S1PlayerLuck,
+ Result
+ } =
+ effect_of_attack
+ (
+ counter,
+ S0TargetCharacter,
+ S0Character,
+ S0TargetPlayerLuck,
+ S0PlayerLuck,
+ CanParry
+ ),
- handle_attack_sequence
- (
- NextAttacks,
- S1Character,
- S1TargetCharacter,
- S1PlayerLuck,
- S1TargetPlayerLuck,
- [Result|Results]
- );
+ handle_attack_sequence
+ (
+ NextAttacks,
+ S1Character,
+ S1TargetCharacter,
+ S1PlayerLuck,
+ S1TargetPlayerLuck,
+ [Result|Results]
+ );
+
+ false ->
+ {
+ S0Character,
+ S0TargetCharacter,
+ S0PlayerLuck,
+ S0TargetPlayerLuck,
+ lists:reverse(Results)
+ }
+ end;
handle_attack_sequence
(
[{second, TargetCanParry}|NextAttacks],
@@ -403,53 +504,78 @@ handle_attack_sequence
Results
)
->
- Statistics = shr_character:get_statistics(S0Character),
- DoubleAttackChance = shr_statistics:get_double_hits(Statistics),
- {_Roll, IsSuccessful, PositiveModifier, NegativeModifier} =
- shr_roll:percentage_with_luck(DoubleAttackChance, S0PlayerLuck),
+ case
+ (
+ (btl_character:get_current_health(S0Character) > 0)
+ and (btl_character:get_current_health(S0Character) > 0)
+ )
+ of
+ true ->
+ Statistics = shr_character:get_statistics(S0Character),
+ DoubleAttackChance = shr_statistics:get_double_hits(Statistics),
+ {_Roll, IsSuccessful, PositiveModifier, NegativeModifier} =
+ shr_roll:percentage_with_luck(DoubleAttackChance, S0PlayerLuck),
- S1PlayerLuck = (S0PlayerLuck + PositiveModifier),
- S1TargetPlayerLuck = (S0TargetPlayerLuck + NegativeModifier),
+ S1PlayerLuck = (S0PlayerLuck + PositiveModifier),
+ S1TargetPlayerLuck = (S0TargetPlayerLuck + NegativeModifier),
+
+ case IsSuccessful of
+ false ->
+ handle_attack_sequence
+ (
+ NextAttacks,
+ S0Character,
+ S0TargetCharacter,
+ S1PlayerLuck,
+ S1TargetPlayerLuck,
+ Results
+ );
+
+ true ->
+ {
+ S1Character,
+ S1TargetCharacter,
+ S2PlayerLuck,
+ S2TargetPlayerLuck,
+ Result
+ } =
+ effect_of_attack
+ (
+ second,
+ S0Character,
+ S0TargetCharacter,
+ S1PlayerLuck,
+ S1TargetPlayerLuck,
+ TargetCanParry
+ ),
+
+ handle_attack_sequence
+ (
+ NextAttacks,
+ S1Character,
+ S1TargetCharacter,
+ S2PlayerLuck,
+ S2TargetPlayerLuck,
+ [Result|Results]
+ )
+ end;
- case IsSuccessful of
false ->
- handle_attack_sequence
- (
- NextAttacks,
+ {
S0Character,
S0TargetCharacter,
- S1PlayerLuck,
- S1TargetPlayerLuck,
- Results
- );
-
- true ->
- {
- S1Character,
- S1TargetCharacter,
- S2PlayerLuck,
- S2TargetPlayerLuck,
- Result
- } =
- effect_of_attack
- (
- second,
- S0Character,
- S0TargetCharacter,
- S1PlayerLuck,
- S1TargetPlayerLuck,
- TargetCanParry
- ),
+ S0PlayerLuck,
+ S0TargetPlayerLuck,
+ lists:reverse(Results)
+ }
+ end.
- handle_attack_sequence
- (
- NextAttacks,
- S1Character,
- S1TargetCharacter,
- S2PlayerLuck,
- S2TargetPlayerLuck,
- [Result|Results]
- )
+-spec apply_luck_decay (integer()) -> integer().
+apply_luck_decay (Luck) ->
+ case {(Luck =< -2), (Luck >= 2)} of
+ {true, _} -> (Luck + 2);
+ {_, true} -> (Luck - 2);
+ _ -> 0
end.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -467,16 +593,16 @@ handle (Action, S0Character, S0Update) ->
CharacterIX = btl_action:get_actor_index(Action),
PlayerIX = btl_character:get_player_index(S0Character),
- Player = btl_battle:get_player(PlayerIX, S0Battle),
- S0PlayerLuck = btl_player:get_luck(Player),
+ S0Player = btl_battle:get_player(PlayerIX, S0Battle),
+ S0PlayerLuck = btl_player:get_luck(S0Player),
TargetCharacterIX = btl_action:get_target_index(Action),
{S0TargetCharacter, S1Battle} =
btl_battle:get_resolved_character(TargetCharacterIX, S0Battle),
- TargetPlayerIX = btl_character:get_player_index(TargetCharacter),
- TargetPlayer = btl_battle:get_player(TargetPlayerIX, S1Battle),
- S0TargetPlayerLuck = btl_player:get_luck(TargetPlayer),
+ TargetPlayerIX = btl_character:get_player_index(S0TargetCharacter),
+ S0TargetPlayer = btl_battle:get_player(TargetPlayerIX, S1Battle),
+ S0TargetPlayerLuck = btl_player:get_luck(S0TargetPlayer),
{CanParry, TargetCanParry, TargetCanCounter} =
get_character_abilities(Action, S0Character, S0TargetCharacter),
@@ -486,7 +612,7 @@ handle (Action, S0Character, S0Update) ->
S1TargetCharacter,
S1PlayerLuck,
S1TargetPlayerLuck,
- Results
+ AttackReports
} =
handle_attack_sequence
(
@@ -511,78 +637,69 @@ handle (Action, S0Character, S0Update) ->
[]
),
- S0NewAttackerLuck =
- case {(NewAttackerLuck =< -2), (NewAttackerLuck >= 2)} of
- {true, _} -> (NewAttackerLuck + 2);
- {_, true} -> (NewAttackerLuck - 2);
- _ -> 0
- end,
-
- S0NewDefenderLuck =
- case {(NewDefenderLuck =< -2), (NewDefenderLuck >= 2)} of
- {true, _} -> (NewDefenderLuck + 2);
- {_, true} -> (NewDefenderLuck - 2);
- _ -> 0
- end,
-
- {UpdatedAttackingPlayer, AttackingPlayerAtaxiaUpdate} =
- btl_player:ataxia_set_luck(S0NewAttackerLuck, AttackingPlayer),
+ S2PlayerLuck = apply_luck_decay(S1PlayerLuck),
+ S2TargetPlayerLuck = apply_luck_decay(S1TargetPlayerLuck),
- {UpdatedDefendingPlayer, DefendingPlayerAtaxiaUpdate} =
- btl_player:ataxia_set_luck(S0NewDefenderLuck, DefendingPlayer),
+ CharacterAtaxiaUpdate =
+ ataxic:update_field
+ (
+ btl_character:get_current_health_field(),
+ ataxic:constant(btl_character:get_current_health(S1Character))
+ ),
- {UpdatedCharacter, CharacterAtaxiaUpdate} =
- btl_character:ataxia_set_current_health
+ {S2Battle, BattleAtaxiaUpdate0} =
+ btl_battle:ataxia_set_character
(
- RemainingAttackerHealth,
- Character
+ CharacterIX,
+ S1Character,
+ CharacterAtaxiaUpdate,
+ S1Battle
),
- {UpdatedTargetCharacterRef, TargetCharacterRefAtaxiaUpdate} =
- btl_character:ataxia_set_current_health
+ TargetCharacterAtaxiaUpdate =
+ ataxic:update_field
(
- RemainingDefenderHealth,
- TargetCharacterRef
+ btl_character:get_current_health_field(),
+ ataxic:constant(btl_character:get_current_health(S1Character))
),
- {S0Battle, BattleAtaxiaUpdate0} =
- btl_battle:ataxia_set_player
+ {S3Battle, BattleAtaxiaUpdate1} =
+ btl_battle:ataxia_set_character
(
- AttackingPlayerIX,
- UpdatedAttackingPlayer,
- AttackingPlayerAtaxiaUpdate,
- Battle
+ TargetCharacterIX,
+ S1TargetCharacter,
+ TargetCharacterAtaxiaUpdate,
+ S2Battle
),
- {S1Battle, BattleAtaxiaUpdate1} =
+ {S1Player, PlayerAtaxiaUpdate} =
+ btl_player:ataxia_set_luck(S2PlayerLuck, S0Player),
+
+ {S4Battle, BattleAtaxiaUpdate2} =
btl_battle:ataxia_set_player
(
- DefendingPlayerIX,
- UpdatedDefendingPlayer,
- DefendingPlayerAtaxiaUpdate,
- S0Battle
+ PlayerIX,
+ S1Player,
+ PlayerAtaxiaUpdate,
+ S3Battle
),
- {S2Battle, BattleAtaxiaUpdate2} =
- btl_battle:ataxia_set_character
+ {S1TargetPlayer, TargetPlayerAtaxiaUpdate} =
+ btl_player:ataxia_set_luck(S2TargetPlayerLuck, S0TargetPlayer),
+
+ {S5Battle, BattleAtaxiaUpdate3} =
+ btl_battle:ataxia_set_player
(
- TargetIX,
- UpdatedTargetCharacterRef,
- TargetCharacterRefAtaxiaUpdate,
- S1Battle
+ TargetPlayerIX,
+ S1TargetPlayer,
+ TargetPlayerAtaxiaUpdate,
+ S4Battle
),
- % Potential danger ahead: we're going to update both the 'character' and
- % 'battle' members of a btl_character_turn_update.
- % 'S1Update' is sure to have both up to date (as it's the result of 'get'
- % requests for both) and there is no risk of the 'battle' update influencing
- % 'character', making what follows safe.
-
- S2Update =
+ S1Update =
btl_character_turn_update:ataxia_set_battle
(
- S2Battle,
- false,
+ S5Battle,
ataxic:optimize
(
ataxic:sequence
@@ -590,49 +707,44 @@ handle (Action, S0Character, S0Update) ->
[
BattleAtaxiaUpdate0,
BattleAtaxiaUpdate1,
- BattleAtaxiaUpdate2
+ BattleAtaxiaUpdate2,
+ BattleAtaxiaUpdate3
]
)
),
- S1Update
+ S0Update
),
- S3Update =
- btl_character_turn_update:ataxia_set_character
- (
- UpdatedCharacter,
- CharacterAtaxiaUpdate,
- S2Update
- ),
-
- TimelineItem =
- btl_turn_result:new_character_attacked
+ S2Update =
+ btl_character_turn_update:add_to_timeline
(
- btl_character_turn_update:get_character_ix(S3Update),
- TargetIX,
- AttackEffects,
- S0NewAttackerLuck,
- S0NewDefenderLuck
+ btl_turn_result:new_character_attacked
+ (
+ CharacterIX,
+ TargetCharacterIX,
+ AttackReports,
+ S2PlayerLuck,
+ S2TargetPlayerLuck
+ ),
+ S1Update
),
- S4Update = btl_character_turn_update:add_to_timeline(TimelineItem, S3Update),
-
- S5Update =
- case (RemainingAttackerHealth > 0) of
- true -> S4Update;
+ S3Update =
+ case (btl_character:get_current_health(S1Character) > 0) of
+ true -> S2Update;
false ->
- btl_victory_progression:handle_character_loss(Character, S4Update)
+ btl_victory_progression:handle_character_loss(S1Character, S2Update)
end,
- S6Update =
- case (RemainingDefenderHealth > 0) of
- true -> S5Update;
+ S4Update =
+ case (btl_character:get_current_health(S1TargetCharacter) > 0) of
+ true -> S3Update;
false ->
btl_victory_progression:handle_character_loss
(
- TargetCharacterRef,
- S5Update
+ S1TargetCharacter,
+ S3Update
)
end,
- {ok, S6Update}.
+ {ok, S4Update}.