diff --git a/Assets/Battle/BattleController.cs b/Assets/Battle/BattleController.cs index 44957b0..bda5be6 100644 --- a/Assets/Battle/BattleController.cs +++ b/Assets/Battle/BattleController.cs @@ -103,6 +103,8 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe private void StartHeroTurn() { this.heroTurn = true; + + this.damageTriggers.RemoveAll(t => t.Expiration == TriggerExpiration.StartOfNextHeroTurn); this.energy = this.maxEnergy; foreach (BattleHero hero in this.heroes) { @@ -126,7 +128,7 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe monster.ResetBlock(); } - heroes[this.enemyTarget].DealDamage(2); + this.Apply(new DealDamageEffect(heroes[this.enemyTarget], 2)); DecideEnemyTarget(); StartHeroTurn(); @@ -196,6 +198,10 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe this.maxEnergy += delta; } + public void IncreaseMaxHP(IncreaseMaxHPEffect effect) { + effect.Target.IncreaseMaxHP(effect.Amount); + } + public void AcquireHeroCards(CardId[] cardIds, BattleZone zone, BattleHero owner) { foreach (CardId cardId in cardIds) { BaseCard acquiredCard = CardDatabase.CreateCard(cardId, owner); @@ -213,11 +219,38 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe } } - public void DealDamage(BattleParticipant target, int amount) { - target.DealDamage(amount); + private List activatedTriggers = new List(); + private List damageTriggers = new List(); + + public void DealDamage(DealDamageEffect effect) { + effect.Target.DealDamage(effect.Amount); + foreach (DamageTrigger dt in this.damageTriggers) { + if (dt.IsTriggeredBy(effect)) { + EnqueueActivatedTrigger(dt); + } + } + RunActivatedTriggers(); } public void AddBlock(BattleParticipant target, int amount) { target.AddBlock(amount); } + + public void ArmDamageTrigger(DamageTrigger damageTrigger) { + this.damageTriggers.Add(damageTrigger); + } + + private void EnqueueActivatedTrigger(Trigger trigger) { + this.activatedTriggers.Add(trigger); + } + + private void RunActivatedTriggers() { + foreach (Trigger t in this.activatedTriggers) { + t.Run(this); + } + this.activatedTriggers.Clear(); + + // Cleanup expired triggers + this.damageTriggers.RemoveAll(t => t.Expired); + } } diff --git a/Assets/Battle/BattleParticipant.cs b/Assets/Battle/BattleParticipant.cs index 1fa8956..dc4b19b 100644 --- a/Assets/Battle/BattleParticipant.cs +++ b/Assets/Battle/BattleParticipant.cs @@ -56,4 +56,11 @@ public class BattleParticipant public bool IsHero() { return this.isHero; } + + public void IncreaseMaxHP(int amount) { + this.maxHP += amount; + if (this.hp > 0) { + this.hp += amount; + } + } } diff --git a/Assets/Battle/CardDatabase.cs b/Assets/Battle/CardDatabase.cs index 7f75d08..5638cff 100644 --- a/Assets/Battle/CardDatabase.cs +++ b/Assets/Battle/CardDatabase.cs @@ -6,6 +6,7 @@ public enum CardId { CrashingPunch, Cover, LightningStrike, + Scarring, Thunderstorm, } @@ -15,6 +16,7 @@ public class CardDatabase {CardId.CrashingPunch, HeroId.Brute}, {CardId.Cover, HeroId.Brute}, {CardId.LightningStrike, HeroId.Shaman}, + {CardId.Scarring, HeroId.Brute}, {CardId.Thunderstorm, HeroId.Shaman}, }; @@ -27,6 +29,8 @@ public class CardDatabase return new CardCover(owner); case CardId.LightningStrike: return new CardLightningStrike(owner); + case CardId.Scarring: + return new CardScarring(owner); case CardId.Thunderstorm: return new CardThunderstorm(owner); default: diff --git a/Assets/Battle/Cards/CardScarring.cs b/Assets/Battle/Cards/CardScarring.cs new file mode 100644 index 0000000..39bbe9c --- /dev/null +++ b/Assets/Battle/Cards/CardScarring.cs @@ -0,0 +1,29 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class CardScarring : BaseCard +{ + public CardScarring(BattleParticipant owner) + : base(owner, CardId.Scarring, "Scarring", 2, CardType.Skill, + "Block 4 damage. The next time damage is taken until next turn, gain 1 Max HP.") { + } + + public override IEnumerator Use(IBattleEffectApplier effectApplier, BattlePlayerControls playerControls) { + effectApplier.Apply(new BlockEffect(this.owner, 4)); + // TODO: Trigger only until end of turn. + DamageTrigger trigger = new DamageTrigger( + new List() {this.owner}, + this.NotifyDamageDealt, + TriggerExpiration.StartOfNextHeroTurn, + TriggerRepetition.Once); + effectApplier.Apply(new ArmDamageTriggerEffect(trigger)); + yield break; + } + + public void NotifyDamageDealt(IBattleEffectApplier effectApplier) { + Debug.Log("NotifyDamageDealt "); + IncreaseMaxHPEffect effect = new IncreaseMaxHPEffect(this.owner, 1); + effectApplier.Apply(effect); + } +} diff --git a/Assets/Battle/Cards/CardScarring.cs.meta b/Assets/Battle/Cards/CardScarring.cs.meta new file mode 100644 index 0000000..922681d --- /dev/null +++ b/Assets/Battle/Cards/CardScarring.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6fe7304b59bb0af4281311fce96c1218 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/Effects/ArmDamageTriggerEffect.cs b/Assets/Battle/Effects/ArmDamageTriggerEffect.cs new file mode 100644 index 0000000..a69c48a --- /dev/null +++ b/Assets/Battle/Effects/ArmDamageTriggerEffect.cs @@ -0,0 +1,16 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class ArmDamageTriggerEffect : IBattleEffect +{ + private DamageTrigger damageTrigger; + + public ArmDamageTriggerEffect(DamageTrigger damageTrigger) { + this.damageTrigger = damageTrigger; + } + + public void Apply(IBattleEffectResolver resolver) { + resolver.ArmDamageTrigger(this.damageTrigger); + } +} diff --git a/Assets/Battle/Effects/ArmDamageTriggerEffect.cs.meta b/Assets/Battle/Effects/ArmDamageTriggerEffect.cs.meta new file mode 100644 index 0000000..59b7387 --- /dev/null +++ b/Assets/Battle/Effects/ArmDamageTriggerEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: f7658a09c682e8545a141aa3ac050649 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/Effects/DealDamageEffect.cs b/Assets/Battle/Effects/DealDamageEffect.cs index 05fdba6..8613a86 100644 --- a/Assets/Battle/Effects/DealDamageEffect.cs +++ b/Assets/Battle/Effects/DealDamageEffect.cs @@ -13,6 +13,9 @@ public class DealDamageEffect : IBattleEffect } public void Apply(IBattleEffectResolver resolver) { - resolver.DealDamage(this.target, this.amount); + resolver.DealDamage(this); } + + public BattleParticipant Target {get => this.target;} + public int Amount {get => this.amount;} } diff --git a/Assets/Battle/Effects/IncreaseMaxHPEffect.cs b/Assets/Battle/Effects/IncreaseMaxHPEffect.cs new file mode 100644 index 0000000..108b7ca --- /dev/null +++ b/Assets/Battle/Effects/IncreaseMaxHPEffect.cs @@ -0,0 +1,21 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class IncreaseMaxHPEffect : IBattleEffect +{ + private BattleParticipant target; + private int amount; + + public IncreaseMaxHPEffect(BattleParticipant target, int amount) { + this.target = target; + this.amount = amount; + } + + public void Apply(IBattleEffectResolver resolver) { + resolver.IncreaseMaxHP(this); + } + + public BattleParticipant Target {get => this.target;} + public int Amount {get => this.amount;} +} diff --git a/Assets/Battle/Effects/IncreaseMaxHPEffect.cs.meta b/Assets/Battle/Effects/IncreaseMaxHPEffect.cs.meta new file mode 100644 index 0000000..e1df1aa --- /dev/null +++ b/Assets/Battle/Effects/IncreaseMaxHPEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: e1dd7732e862a6e40b5221f85a09b56d +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/IBattleEffectResolver.cs b/Assets/Battle/IBattleEffectResolver.cs index 7d9ba1f..ddfbf4d 100644 --- a/Assets/Battle/IBattleEffectResolver.cs +++ b/Assets/Battle/IBattleEffectResolver.cs @@ -3,8 +3,10 @@ using System.Collections.Generic; using UnityEngine; public interface IBattleEffectResolver { - void DealDamage(BattleParticipant target, int amount); + void DealDamage(DealDamageEffect effect); void AddBlock(BattleParticipant target, int amount); void IncreaseHeroMaxEnergy(int delta); + void IncreaseMaxHP(IncreaseMaxHPEffect effect); void AcquireHeroCards(CardId[] cardIds, BattleZone zone, BattleHero owner); + void ArmDamageTrigger(DamageTrigger damageTrigger); } diff --git a/Assets/Battle/Trigger.cs b/Assets/Battle/Trigger.cs new file mode 100644 index 0000000..3ba9341 --- /dev/null +++ b/Assets/Battle/Trigger.cs @@ -0,0 +1,36 @@ +public enum TriggerExpiration { + Never, + StartOfNextHeroTurn, +} + +public enum TriggerRepetition { + Once, + Multiple, +} + +public class Trigger { + + private TriggeredEffect callback; + private TriggerExpiration expiration; + private TriggerRepetition repetition; + private bool expired; + + public Trigger(TriggeredEffect callback, TriggerExpiration expiration, + TriggerRepetition repetition) { + this.callback = callback; + this.expiration = expiration; + this.repetition = repetition; + } + + public void Run(IBattleEffectApplier effectApplier) { + if (this.expired) return; + callback(effectApplier); + if (this.repetition == TriggerRepetition.Once) { + this.expired = true; + } + } + + public bool Expired {get => this.expired;} + public TriggerExpiration Expiration {get => this.expiration;} + public TriggerRepetition Repetition {get => this.repetition;} +} \ No newline at end of file diff --git a/Assets/Battle/Trigger.cs.meta b/Assets/Battle/Trigger.cs.meta new file mode 100644 index 0000000..d4e70a5 --- /dev/null +++ b/Assets/Battle/Trigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 67697df27ab54e043aca7550c896b6fd +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/TriggeredEffect.cs b/Assets/Battle/TriggeredEffect.cs new file mode 100644 index 0000000..c6d55c3 --- /dev/null +++ b/Assets/Battle/TriggeredEffect.cs @@ -0,0 +1 @@ +public delegate void TriggeredEffect(IBattleEffectApplier effectApplier); \ No newline at end of file diff --git a/Assets/Battle/TriggeredEffect.cs.meta b/Assets/Battle/TriggeredEffect.cs.meta new file mode 100644 index 0000000..fcab96d --- /dev/null +++ b/Assets/Battle/TriggeredEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 727217e2ab0988d46b1d4532964b0cf7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/Triggers.meta b/Assets/Battle/Triggers.meta new file mode 100644 index 0000000..4781b7a --- /dev/null +++ b/Assets/Battle/Triggers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: 5bf11c7ef8a0e044fbc4bf500c4d3770 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/Triggers/DamageTrigger.cs b/Assets/Battle/Triggers/DamageTrigger.cs new file mode 100644 index 0000000..8f2b14b --- /dev/null +++ b/Assets/Battle/Triggers/DamageTrigger.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +public class DamageTrigger : Trigger { + + private List observedParticipants; + + public DamageTrigger(List observedParticipants, TriggeredEffect callback, + TriggerExpiration expiration, TriggerRepetition repetition) + : base(callback, expiration, repetition) { + this.observedParticipants = observedParticipants; + } + + public bool IsTriggeredBy(DealDamageEffect effect) { + return effect.Amount > 0 && this.observedParticipants.Contains(effect.Target); + } +} \ No newline at end of file diff --git a/Assets/Battle/Triggers/DamageTrigger.cs.meta b/Assets/Battle/Triggers/DamageTrigger.cs.meta new file mode 100644 index 0000000..dbc5526 --- /dev/null +++ b/Assets/Battle/Triggers/DamageTrigger.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d53e7c1da2653f45a48f309980a7ca4 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: