summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornsensfel <SpamShield0@noot-noot.org>2018-02-23 21:22:37 +0100
committernsensfel <SpamShield0@noot-noot.org>2018-02-23 21:22:37 +0100
commit959b994bced0863d4b8a984f38f5ac61aa3620e0 (patch)
treea9dbce8e22dd818f60e7cb70557dddad70c85ca9 /src/query/character_turn
parentf512cb83df8dea9fb39bd98540b0616fe7607f6d (diff)
Still working on character_turn queries...
Diffstat (limited to 'src/query/character_turn')
-rw-r--r--src/query/character_turn/handle_character_attacking_2.erl59
-rw-r--r--src/query/character_turn/handle_character_instance_attacking_2.erl358
2 files changed, 358 insertions, 59 deletions
diff --git a/src/query/character_turn/handle_character_attacking_2.erl b/src/query/character_turn/handle_character_attacking_2.erl
deleted file mode 100644
index 3fd2687..0000000
--- a/src/query/character_turn/handle_character_attacking_2.erl
+++ /dev/null
@@ -1,59 +0,0 @@
-roll_hits (AttackerStatistics, DefenderStatistics) ->
- MissChance =
- max
- (
- 0,
- (
- statistics:get_dodges(DefenderStatistics)
- -
- statistics:get_accuracy(AttackerStatistics)
- )
- ),
- case roll:percentage() of
- X when (X < MissChance) -> misses;
- X when (X < (MissChance * 2)) -> grazes;
- _ -> hits
- end.
-
-roll_damage (AttackerStatistics, _DefenderStatistics) ->
- {MinimumDamage, MaximumDamage} = statistics:get_damages(AttackerStatistics),
- MaximumRoll = max(1, MaximumDamage - MinimumDamage),
- MinimumDamage + (rand:uniform(MaximumRoll) - 1).
-
-handle_character_attacking (QueryState, Input) ->
- BattlemapInstance = QueryState#query_state.battlemap_instance,
- ControlledCharacterInstance = QueryState#query_state.character_instance,
- ControlledCharacter =
- character_instance:get_character(ControlledCharacterInstance),
- ControlledCharacterStatistics =
- character:get_statistics(ControlledCharacter),
- TargettedCharacterInstance =
- array:get
- (
- Input#input.target_id,
- battlemap_instance:get_characters(BattlemapInstance)
- ),
- TargettedCharacter =
- character_instance:get_character(TargettedCharacterInstance),
- TargettedCharacterStatistics = character:get_statistics(TargettedCharacter),
- RequiredRange =
- movement:steps_between
- (
- character_instance:get_location(ControlledCharacterInstance),
- character_instance:get_location(TargettedCharacterInstance)
- ),
- {AttackingWeaponID, _} = character:get_weapon_ids(ControlledCharacter),
- AttackingWeapon = weapon:from_id(AttackingWeaponID),
- {_, AttackingWeaponRange} = weapon:get_ranges(AttackingWeapon),
- {DefendingWeaponID, _} = character:get_weapon_ids(TargettedCharacter),
- DefendingWeapon = weapon:from_id(DefendingWeaponID),
- {DefendingWeaponRange, _} = weapon:get_ranges(DefendingWeapon),
-
- true = (RequiredRange =< AttackingWeaponRange),
-
- {Rolls, HealthMod} =
- handle_attack
- (
- ControlledCharacterStatistics,
- TargettedCharacterStatistics
- ).
diff --git a/src/query/character_turn/handle_character_instance_attacking_2.erl b/src/query/character_turn/handle_character_instance_attacking_2.erl
new file mode 100644
index 0000000..be2ac99
--- /dev/null
+++ b/src/query/character_turn/handle_character_instance_attacking_2.erl
@@ -0,0 +1,358 @@
+roll_hits (AttackerStatistics, DefenderStatistics) ->
+ MissChance =
+ max
+ (
+ 0,
+ (
+ statistics:get_dodges(DefenderStatistics)
+ -
+ statistics:get_accuracy(AttackerStatistics)
+ )
+ ),
+ case roll:percentage() of
+ X when (X =< MissChance) -> misses;
+ X when (X =< (MissChance * 2)) -> grazes;
+ _ -> hits
+ end.
+
+roll_damage (AttackerStatistics, _DefenderStatistics) ->
+ {MinimumDamage, MaximumDamage} = statistics:get_damages(AttackerStatistics),
+ MaximumRoll = max(1, MaximumDamage - MinimumDamage),
+ BaseDamage = MinimumDamage + (rand:uniform(MaximumRoll) - 1),
+ CriticalHitChance = statistics:get_critical_hits(AttackerStatistics),
+ case roll:percentage() of
+ X when (X =< CriticalHitChance) ->
+ {critical, (BaseDamage * 2)};
+ _ ->
+ {basic, BaseDamage}
+ end.
+
+handle_attack (AttackerStatistics, DefenderStatistics) ->
+ Hits = roll_hits(AttackerStatistics, DefenderStatistics),
+ {Critical, Damage} = roll_damage(AttackerStatistics, DefenderStatistics),
+ case Hits of
+ misses ->
+ {Hits, Critical, 0};
+
+ grazes ->
+ {
+ Hits,
+ Critical,
+ trunc(Damage / 2)
+ };
+
+ _ ->
+ {
+ Hits,
+ Critical,
+ Damage
+ }
+ end.
+
+handle_parry (AttackerStatistics, DefenderStatistics) ->
+ ParryChance = statistics:get_parries(DefenderStatistics),
+ case roll:percentage() of
+ X when (X =< ParryChance) ->
+ [{parry, handle_attack(DefenderStatistics, AttackerStatistics)}];
+ _ ->
+ []
+ end.
+
+handle_attacks ([], _AttackerStatistics, _DefenderStatistics, Results) ->
+ Results;
+handle_attacks
+(
+ [nothing|Next],
+ AttackerStatistics,
+ DefenderStatistics,
+ Results
+) ->
+ handle_attacks
+ (
+ Next,
+ AttackerStatistics,
+ DefenderStatistics,
+ Results
+ );
+handle_attacks
+(
+ [first|Next],
+ AttackerStatistics,
+ DefenderStatistics,
+ Results
+) ->
+ handle_attacks
+ (
+ Next,
+ AttackerStatistics,
+ DefenderStatistics,
+ [
+ {
+ first,
+ handle_attack(AttackerStatistics, DefenderStatistics)
+ }
+ |
+ Results
+ ]
+ );
+handle_attacks
+(
+ [second|Next],
+ AttackerStatistics,
+ DefenderStatistics,
+ Results
+) ->
+ handle_attacks
+ (
+ Next,
+ AttackerStatistics,
+ DefenderStatistics,
+ [
+ {
+ second,
+ handle_attack(AttackerStatistics, DefenderStatistics)
+ }
+ |
+ Results
+ ]
+ );
+handle_attacks
+(
+ [parry|Next],
+ AttackerStatistics,
+ DefenderStatistics,
+ Results
+) ->
+ handle_attacks
+ (
+ Next,
+ AttackerStatistics,
+ DefenderStatistics,
+ (
+ handle_parry(AttackerStatistics, DefenderStatistics)
+ ++
+ Results
+ )
+ );
+handle_attacks
+(
+ [counter|Next],
+ AttackerStatistics,
+ DefenderStatistics,
+ Results
+) ->
+ handle_attacks
+ (
+ Next,
+ AttackerStatistics,
+ DefenderStatistics,
+ [
+ {
+ counter,
+ handle_attack(DefenderStatistics, AttackerStatistics)
+ }
+ |
+ Results
+ ]
+ ).
+
+apply_attacks_to_healths ([], AttackerHealth, DefenderHealth, ValidEffects) ->
+ {ValidEffects, AttackerHealth, DefenderHealth};
+apply_attacks_to_healths
+(
+ [{first, Effect}|Next],
+ AttackerHealth,
+ DefenderHealth,
+ ValidEffects
+) ->
+ {_Hit, _Critical, Damage} = Effect,
+ case (AttackerHealth > 0) of
+ true ->
+ apply_attacks_to_healths
+ (
+ Next,
+ AttackerHealth,
+ max(0, (DefenderHealth - Damage)),
+ [{first, Effect}|ValidEffects]
+ );
+ false ->
+ ValidEffects
+ end;
+apply_attacks_to_healths
+(
+ [{second, Effect}|Next],
+ AttackerHealth,
+ DefenderHealth,
+ ValidEffects
+) ->
+ {_Hit, _Critical, Damage} = Effect,
+ case (AttackerHealth > 0) of
+ true ->
+ apply_attacks_to_healths
+ (
+ Next,
+ AttackerHealth,
+ max(0, (DefenderHealth - Damage)),
+ [{second, Effect}|ValidEffects]
+ );
+ false ->
+ ValidEffects
+ end;
+apply_attacks_to_healths
+(
+ [{counter, Effect}|Next],
+ AttackerHealth,
+ DefenderHealth,
+ ValidEffects
+) ->
+ {_Hit, _Critical, Damage} = Effect,
+ case (DefenderHealth > 0) of
+ true ->
+ apply_attacks_to_healths
+ (
+ Next,
+ max(0, (AttackerHealth - Damage)),
+ DefenderHealth,
+ [{counter, Effect}|ValidEffects]
+ );
+ false ->
+ ValidEffects
+ end;
+apply_attacks_to_healths
+(
+ [{parry, Effect}|Next],
+ AttackerHealth,
+ DefenderHealth,
+ ValidEffects
+) ->
+ {_Hit, _Critical, Damage} = Effect,
+ case (DefenderHealth > 0) of
+ true ->
+ apply_attacks_to_healths
+ (
+ Next,
+ max(0, (AttackerHealth - Damage)),
+ DefenderHealth,
+ [{parry, Effect}|ValidEffects]
+ );
+ false ->
+ ValidEffects
+ end.
+
+set_new_healths_in_query_state
+(
+ RemainingAttackerHealth,
+ RemainingDefenderHealth,
+ QueryState,
+ Input
+) ->
+ BattlemapInstance = QueryState#query_state.battlemap_instance,
+ ControlledCharacterInstance = QueryState#query_state.character_instance,
+ CharacterInstances =
+ battlemap_instance:get_character_instances(BattlemapInstance),
+ TargettedCharacterInstanceIX = Input#input.target_ix,
+ TargettedCharacterInstance =
+ array:get
+ (
+ TargettedCharacterInstanceIX,
+ CharacterInstances
+ ),
+
+ QueryState#query_state
+ {
+ battlemap_instance =
+ battlemap_instance:set_character_instances
+ (
+ array:set
+ (
+ TargettedCharacterInstanceIX,
+ character_instance:set_current_health
+ (
+ TargettedCharacterInstance,
+ RemainingDefenderHealth
+ )
+ )
+ ),
+ character_instance =
+ character_instance:set_current_health
+ (
+ ControlledCharacterInstance,
+ RemainingAttackerHealth
+ )
+ }.
+
+handle_character_instance_attacking (QueryState, Input) ->
+ BattlemapInstance = QueryState#query_state.battlemap_instance,
+ ControlledCharacterInstance = QueryState#query_state.character_instance,
+ ControlledCharacter =
+ character_instance:get_character(ControlledCharacterInstance),
+ ControlledCharacterStatistics =
+ character:get_statistics(ControlledCharacter),
+ TargettedCharacterInstance =
+ array:get
+ (
+ Input#input.target_ix,
+ battlemap_instance:get_character_instances(BattlemapInstance)
+ ),
+ TargettedCharacter =
+ character_instance:get_character(TargettedCharacterInstance),
+ TargettedCharacterStatistics = character:get_statistics(TargettedCharacter),
+ RequiredRange =
+ movement:steps_between
+ (
+ character_instance:get_location(ControlledCharacterInstance),
+ character_instance:get_location(TargettedCharacterInstance)
+ ),
+ {AttackingWeaponID, _} = character:get_weapon_ids(ControlledCharacter),
+ AttackingWeapon = weapon:from_id(AttackingWeaponID),
+ {_, AttackingWeaponRange} = weapon:get_ranges(AttackingWeapon),
+ {DefendingWeaponID, _} = character:get_weapon_ids(TargettedCharacter),
+ DefendingWeapon = weapon:from_id(DefendingWeaponID),
+ {DefendingWeaponDefRange, DefendingWeaponAtkRange} =
+ weapon:get_ranges(DefendingWeapon),
+
+ true = (RequiredRange =< AttackingWeaponRange),
+
+ CanDefend =
+ (
+ (RequiredRange > DefendingWeaponDefRange)
+ and
+ (RequiredRange =< DefendingWeaponAtkRange)
+ ),
+ CanParry = (weapon:get_range_type(DefendingWeapon) == melee),
+ Actions =
+ case {CanDefend, CanParry} of
+ {true, true} ->
+ [second, counter, parry, first];
+ {true, false} ->
+ [second, counter, first];
+ {false, _} ->
+ [second, first]
+ end,
+ Effects =
+ handle_attacks
+ (
+ Actions,
+ ControlledCharacterStatistics,
+ TargettedCharacterStatistics,
+ []
+ ),
+ {RemainingEffects, RemainingAttackerHealth, RemainingDefenderHealth} =
+ apply_attacks_to_healths
+ (
+ Effects,
+ character_instance:get_current_health(ControlledCharacterInstance),
+ character_instance:get_current_health(TargettedCharacterInstance),
+ []
+ ),
+
+ {
+ RemainingEffects,
+ set_new_healths_in_query_state
+ (
+ QueryState,
+ RemainingAttackerHealth,
+ RemainingDefenderHealth,
+ Input
+ )
+ }.