summaryrefslogtreecommitdiff |
diff options
author | nsensfel <SpamShield0@noot-noot.org> | 2019-06-06 11:23:20 +0200 |
---|---|---|
committer | nsensfel <SpamShield0@noot-noot.org> | 2019-06-06 11:23:20 +0200 |
commit | bfe469efe993a89f3a8ccbb209b47df1c3e55f2d (patch) | |
tree | 6f0435bd1887192c055b8e2ddeb662cb89a27ed3 /src | |
parent | 1645df02f3f691a6fe4cbb60a65c5c840a99b307 (diff) |
[Broken] ...
Diffstat (limited to 'src')
-rw-r--r-- | src/battle/mechanic/action/btl_action_attack.erl | 560 |
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}. |