diff --git a/Assets/Battle/BaseCard.cs b/Assets/Battle/BaseCard.cs index a1c2062..7285421 100644 --- a/Assets/Battle/BaseCard.cs +++ b/Assets/Battle/BaseCard.cs @@ -33,6 +33,8 @@ public abstract class BaseCard return "Skill"; case CardType.Enchantment: return "Enchantment"; + case CardType.Default: + return "Default"; default: throw new System.ArgumentException("CardType unknown", "cardType"); } @@ -40,7 +42,7 @@ public abstract class BaseCard public string GetEffectText() {return this.effectText;} public bool IsPermanent() { - return this.type == CardType.Enchantment; + return this.type == CardType.Enchantment || this.type == CardType.Default; } public bool IsEphemeral() { diff --git a/Assets/Battle/BattleClock.cs b/Assets/Battle/BattleClock.cs new file mode 100644 index 0000000..a2d067b --- /dev/null +++ b/Assets/Battle/BattleClock.cs @@ -0,0 +1,29 @@ +public class BattleClock { + public delegate void TimeChangedAction(BattleTime timeNow); + public event TimeChangedAction OnTimeChanged; + + private int mRoundNumber; + private RoundStep mStep; + + public BattleClock() { + mRoundNumber = 0; + mStep = RoundStep.None; + } + + public void AdvanceRound() { + mRoundNumber++; + mStep = RoundStep.StartOfRound; + TriggerOnTimeChanged(); + } + + public void AdvanceToStep(RoundStep step) { + mStep = step; + TriggerOnTimeChanged(); + } + + private void TriggerOnTimeChanged() { + if (OnTimeChanged != null) OnTimeChanged(this.Now); + } + + public BattleTime Now {get => new BattleTime(mRoundNumber, mStep);} +} diff --git a/Assets/Battle/BattleClock.cs.meta b/Assets/Battle/BattleClock.cs.meta new file mode 100644 index 0000000..116f55f --- /dev/null +++ b/Assets/Battle/BattleClock.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 22aaeef7020f83f47a03c0b2d8186afa +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/BattleController.cs b/Assets/Battle/BattleController.cs index 19e25c7..de01d26 100644 --- a/Assets/Battle/BattleController.cs +++ b/Assets/Battle/BattleController.cs @@ -34,6 +34,9 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe private HandPlayability heroHandPlayability; private HandPlayability monsterHandPlayability; private TurnIntentions monsterIntentions; + private BattleClock clock; + private BuffManager buffManager; + private ParticipantActivity participantActivity; private delegate void BattleStateChangedAction(); private event BattleStateChangedAction OnBattleStateChanged; @@ -93,6 +96,9 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe this.monsterDeck = new BattleDeck( this.monsterCardDatabase, parameters.MCardIds.Cast().ToArray(), mCardOwners); + this.clock = new BattleClock(); + this.buffManager = new BuffManager(this.clock); + this.participantActivity = new ParticipantActivity(); this.playArea = new PlayArea(); this.heroHandPlayability = new HandPlayability( @@ -151,6 +157,7 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe } private IEnumerator RunBattleRound() { + this.clock.AdvanceRound(); this.state.AdvanceToTeamTurn(TeamChoice.Heroes); this.damageTriggers.RemoveAll(t => t.Expiration == TriggerExpiration.StartOfNextHeroTurn); @@ -172,10 +179,14 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe this.state.AdvanceToTeamTurn(TeamChoice.Monsters); yield return RunMonsterTurn(); + + this.clock.AdvanceToStep(RoundStep.EndOfRound); + this.participantActivity.NextRound(); } private IEnumerator RunHeroTurn() { // Start of hero turn + this.clock.AdvanceToStep(RoundStep.StartOfHeroTurn); OnBattleStateChanged(); this.monsterIntentions.ResumeIntentions(); @@ -200,6 +211,7 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe } // End of hero turn + yield return this.playArea.UseHeroDefaults(this.heroes, this.participantActivity, UseHeroDefault); if (STABLE_HAND_STYLE) { this.heroDeck.DiscardInExcessOf(3); } else { @@ -208,11 +220,15 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe foreach (BattleHero hero in this.heroes) { hero.TickStatuses(); } + + this.clock.AdvanceToStep(RoundStep.EndOfHeroTurn); + OnBattleStateChanged(); this.monsterIntentions.PauseIntentions(); } private IEnumerator RunMonsterTurn() { + this.clock.AdvanceToStep(RoundStep.StartOfMonsterTurn); OnBattleStateChanged(); yield return new WaitForSeconds(0.5f); @@ -253,6 +269,8 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe foreach (BattleMonster monster in this.monsters) { monster.TickStatuses(); } + + this.clock.AdvanceToStep(RoundStep.EndOfMonsterTurn); OnBattleStateChanged(); } @@ -275,8 +293,11 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe this.heroEnergy.PayForCard(card); this.heroDeck.RemoveCardFromHand(card); + this.participantActivity.NotifyParticipantUsedCard(card.Owner, card); yield return card.Use(this, this, battlePlayerControls); - if (card.IsPermanent()) { + if (card.Type == CardType.Default) { + // Already added to playArea by effect + } else if (card.IsPermanent()) { this.playArea.AddPlayedHeroPermanent(card); } else if (card.IsEphemeral()) { this.heroDeck.MoveCardToOblivion(card); @@ -288,6 +309,17 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe OnBattleStateChanged(); } + public IEnumerator UseHeroDefault(DefaultHeroCard card) { + if (!card.Owner.CanUseDefault()) { + yield break; + } + + yield return card.UseDefault(this, this, battlePlayerControls); + + CheckState(); + OnBattleStateChanged(); + } + public IEnumerator UseMonsterCard(MonsterCard card) { this.monsterEnergy.PayForCard(card); this.monsterDeck.RemoveCardFromHand(card); @@ -444,7 +476,11 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe public int DealDamage(DealDamageEffect effect) { if (effect.Target == null) return 0; - int damageDealt = effect.Target.DealDamage(effect.Amount); + int amount = effect.Amount; + if (effect.Source != null) { + amount += this.buffManager.GetTotalBuffAmountOfType(effect.Source, BuffType.Power); + } + int damageDealt = effect.Target.DealDamage(amount); foreach (DamageTrigger dt in this.damageTriggers) { if (dt.IsTriggeredBy(effect)) { EnqueueActivatedTrigger(dt); @@ -499,6 +535,10 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe effect.Target.AddStatus(effect.Status, effect.Amount); } + public void BuffParticipant(BuffParticipantEffect effect) { + this.buffManager.AddBuff(effect, this.clock.Now); + } + public void Rotate(RotateEffect effect) { if (effect.Positions == 0) return; @@ -554,6 +594,13 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe } } + public void SetupDefault(DefaultEffect effect) { + DefaultHeroCard previousDefault = this.playArea.SetupDefault(effect); + if (previousDefault != null) { + this.heroDeck.MoveCardToDiscard(previousDefault); + } + } + public void ArmDamageTrigger(DamageTrigger damageTrigger) { this.damageTriggers.Add(damageTrigger); } diff --git a/Assets/Battle/BattleParticipant.cs b/Assets/Battle/BattleParticipant.cs index 2255095..38d5750 100644 --- a/Assets/Battle/BattleParticipant.cs +++ b/Assets/Battle/BattleParticipant.cs @@ -164,6 +164,10 @@ public class BattleParticipant return IsAlive() && !HasStatus(BattleStatus.Stun); } + public bool CanUseDefault() { + return IsAlive() && !HasStatus(BattleStatus.Stun); + } + public bool HasStatus(BattleStatus status) { return this.statuses.ContainsKey(status); } diff --git a/Assets/Battle/BattleTime.cs b/Assets/Battle/BattleTime.cs new file mode 100644 index 0000000..4dc750f --- /dev/null +++ b/Assets/Battle/BattleTime.cs @@ -0,0 +1,24 @@ +public enum RoundStep { + None, + StartOfRound, + StartOfHeroTurn, + EndOfHeroTurn, + StartOfMonsterTurn, + EndOfMonsterTurn, + EndOfRound, +} + +public class BattleTime { + private int mRoundNumber; + private RoundStep mRoundStep; + + public BattleTime(int roundNumber, RoundStep roundStep) { + mRoundNumber = roundNumber; + mRoundStep = roundStep; + } + + public int RoundNumber {get => mRoundNumber;} + public RoundStep RoundStep {get => mRoundStep;} + + public int Int {get => mRoundNumber * 100 + (int) mRoundStep;} +} diff --git a/Assets/Battle/BattleTime.cs.meta b/Assets/Battle/BattleTime.cs.meta new file mode 100644 index 0000000..8e49be6 --- /dev/null +++ b/Assets/Battle/BattleTime.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c9c620593374fcf4c985eaf5041b1eff +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/BuffDuration.cs b/Assets/Battle/BuffDuration.cs new file mode 100644 index 0000000..053cc37 --- /dev/null +++ b/Assets/Battle/BuffDuration.cs @@ -0,0 +1,3 @@ +public enum BuffDuration { + UntilEndOfNextHeroTurn, +} diff --git a/Assets/Battle/BuffDuration.cs.meta b/Assets/Battle/BuffDuration.cs.meta new file mode 100644 index 0000000..9d87db1 --- /dev/null +++ b/Assets/Battle/BuffDuration.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0b7d7799a49ca114481b8b4e0d1d3879 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/BuffManager.cs b/Assets/Battle/BuffManager.cs new file mode 100644 index 0000000..5fb9af4 --- /dev/null +++ b/Assets/Battle/BuffManager.cs @@ -0,0 +1,64 @@ +using System.Collections.Generic; +using System.Linq; + +public class Buff { + private BuffType mType; + private int mAmount; + private BattleTime mEnd; + + public Buff(BuffType type, int amount, BattleTime end) { + mType = type; + mAmount = amount; + mEnd = end; + } + + public BuffType Type {get => mType;} + public int Amount {get => mAmount;} + public BattleTime End {get => mEnd;} +} + +public class BuffManager { + + private Dictionary> mBuffs = new Dictionary>(); + + public BuffManager(BattleClock clock) { + clock.OnTimeChanged += NotifyBattleTime; + } + + public void AddBuff(BuffParticipantEffect effect, BattleTime timeNow) { + List current = GetAllBuffsFor(effect.Participant); + current.Add(new Buff(effect.Type, effect.Amount, CalculateEnd(timeNow, effect.Duration))); + mBuffs[effect.Participant] = current; + } + + public int GetTotalBuffAmountOfType(BattleParticipant participant, BuffType type) { + int total = 0; + foreach (Buff buff in GetAllBuffsFor(participant)) { + if (buff.Type == type) { + total += buff.Amount; + } + } + return total; + } + + public List GetAllBuffsFor(BattleParticipant participant) { + if (mBuffs.ContainsKey(participant)) { + return mBuffs[participant]; + } else { + return new List(); + } + } + + private void NotifyBattleTime(BattleTime timeNow) { + foreach (List buffs in mBuffs.Values) { + buffs.RemoveAll(buff => timeNow.Int >= buff.End.Int); + } + } + + private static BattleTime CalculateEnd(BattleTime timeNow, BuffDuration duration) { + if (duration == BuffDuration.UntilEndOfNextHeroTurn) { + return new BattleTime(timeNow.RoundNumber + 1, RoundStep.EndOfHeroTurn); + } + throw new System.Exception(); + } +} \ No newline at end of file diff --git a/Assets/Battle/BuffManager.cs.meta b/Assets/Battle/BuffManager.cs.meta new file mode 100644 index 0000000..9312ac5 --- /dev/null +++ b/Assets/Battle/BuffManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ef089e4327ee000469448b5357efc161 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/BuffType.cs b/Assets/Battle/BuffType.cs new file mode 100644 index 0000000..9720b12 --- /dev/null +++ b/Assets/Battle/BuffType.cs @@ -0,0 +1,3 @@ +public enum BuffType { + Power, +} diff --git a/Assets/Battle/BuffType.cs.meta b/Assets/Battle/BuffType.cs.meta new file mode 100644 index 0000000..608ca8c --- /dev/null +++ b/Assets/Battle/BuffType.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c870b0605da509b42b5fb4284f6e04f6 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/CardType.cs b/Assets/Battle/CardType.cs index eb15abe..83e62b5 100644 --- a/Assets/Battle/CardType.cs +++ b/Assets/Battle/CardType.cs @@ -3,4 +3,5 @@ public enum CardType { Attack, Skill, Enchantment, + Default, } diff --git a/Assets/Battle/CardsHeroes/BlindFuryHCard.cs b/Assets/Battle/CardsHeroes/BlindFuryHCard.cs index 14e8cf1..4eb1820 100644 --- a/Assets/Battle/CardsHeroes/BlindFuryHCard.cs +++ b/Assets/Battle/CardsHeroes/BlindFuryHCard.cs @@ -12,7 +12,7 @@ public class BlindFuryHCard : HeroCard public override IEnumerator Use(IBattleEffectApplier effectApplier, MonsterViewpoint viewpoint, BattlePlayerControls playerControls) { BattleParticipant target = AIUtils.GetNearestMonster(viewpoint, this.owner); - effectApplier.Apply(new DealDamageEffect(target, 5)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 5)); effectApplier.Apply(new ModifyInsightEffect(-1)); yield break; } diff --git a/Assets/Battle/CardsHeroes/CrashingPunchHCard.cs b/Assets/Battle/CardsHeroes/CrashingPunchHCard.cs index 5557915..50f8646 100644 --- a/Assets/Battle/CardsHeroes/CrashingPunchHCard.cs +++ b/Assets/Battle/CardsHeroes/CrashingPunchHCard.cs @@ -14,6 +14,6 @@ public class CrashingPunchHCard : HeroCard SingleTargeting singleTargeting = new SingleTargeting(new AnyTargetPolicy()); yield return playerControls.StartCoroutine(playerControls.ChooseTarget(singleTargeting)); BattleParticipant target = singleTargeting.GetTarget(); - effectApplier.Apply(new DealDamageEffect(target, 3)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 3)); } } diff --git a/Assets/Battle/CardsHeroes/LeadShotHCard.cs b/Assets/Battle/CardsHeroes/LeadShotHCard.cs index e792840..1245e1f 100644 --- a/Assets/Battle/CardsHeroes/LeadShotHCard.cs +++ b/Assets/Battle/CardsHeroes/LeadShotHCard.cs @@ -15,7 +15,7 @@ public class LeadShotHCard : HeroCard yield return playerControls.StartCoroutine(playerControls.ChooseTarget(singleTargeting)); yield return new WaitForSeconds(0.4f); BattleParticipant target = singleTargeting.GetTarget(); - effectApplier.Apply(new DealDamageEffect(target, 2)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 2)); yield return new WaitForSeconds(0.8f); } } diff --git a/Assets/Battle/CardsHeroes/LightningHatchetHCard.cs b/Assets/Battle/CardsHeroes/LightningHatchetHCard.cs index e82339b..e18ad8c 100644 --- a/Assets/Battle/CardsHeroes/LightningHatchetHCard.cs +++ b/Assets/Battle/CardsHeroes/LightningHatchetHCard.cs @@ -14,6 +14,6 @@ public class LightningHatchetHCard : HeroCard SingleTargeting singleTargeting = new SingleTargeting(new AnyMonsterTargetPolicy()); yield return playerControls.StartCoroutine(playerControls.ChooseTarget(singleTargeting)); BattleParticipant target = singleTargeting.GetTarget(); - effectApplier.Apply(new DealDamageEffect(target, 2)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 2)); } } diff --git a/Assets/Battle/CardsHeroes/LightningStrikeHCard.cs b/Assets/Battle/CardsHeroes/LightningStrikeHCard.cs index a1faf34..b5d451a 100644 --- a/Assets/Battle/CardsHeroes/LightningStrikeHCard.cs +++ b/Assets/Battle/CardsHeroes/LightningStrikeHCard.cs @@ -14,6 +14,6 @@ public class LightningStrikeHCard : HeroCard SingleTargeting singleTargeting = new SingleTargeting(new AnyTargetPolicy()); yield return playerControls.StartCoroutine(playerControls.ChooseTarget(singleTargeting)); BattleParticipant target = singleTargeting.GetTarget(); - effectApplier.Apply(new DealDamageEffect(target, 3)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 3)); } } diff --git a/Assets/Battle/CardsHeroes/OilOfSharpnessHCard.cs b/Assets/Battle/CardsHeroes/OilOfSharpnessHCard.cs new file mode 100644 index 0000000..44be2d9 --- /dev/null +++ b/Assets/Battle/CardsHeroes/OilOfSharpnessHCard.cs @@ -0,0 +1,26 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class OilOfSharpnessHCard : DefaultHeroCard +{ + public OilOfSharpnessHCard(BattleParticipant owner) + : base(owner, HCardId.OilOfSharpness, "Oil of Sharpness", 1, CardType.Default, + "Target hero gets +1 power until end of next turn.") { + } + + public override IEnumerator Use(IBattleEffectApplier effectApplier, + MonsterViewpoint viewpoint, BattlePlayerControls playerControls) { + effectApplier.Apply(new DefaultEffect(this)); + yield break; + } + + public override IEnumerator UseDefault(IBattleEffectApplier effectApplier, + MonsterViewpoint viewpoint, BattlePlayerControls playerControls) { + SingleTargeting targeting = new SingleTargeting(new AnyHeroTargetPolicy()); + yield return playerControls.ChooseTarget(targeting); + BattleParticipant target = targeting.GetTarget(); + effectApplier.Apply(new BuffParticipantEffect(target, BuffType.Power, 1, BuffDuration.UntilEndOfNextHeroTurn)); + yield break; + } +} diff --git a/Assets/Battle/CardsHeroes/OilOfSharpnessHCard.cs.meta b/Assets/Battle/CardsHeroes/OilOfSharpnessHCard.cs.meta new file mode 100644 index 0000000..e2a1920 --- /dev/null +++ b/Assets/Battle/CardsHeroes/OilOfSharpnessHCard.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: ac807b0678a548a46a0f67b2a4f43fed +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/CardsHeroes/SwordSlashHCard.cs b/Assets/Battle/CardsHeroes/SwordSlashHCard.cs index b34aa30..f14c24d 100644 --- a/Assets/Battle/CardsHeroes/SwordSlashHCard.cs +++ b/Assets/Battle/CardsHeroes/SwordSlashHCard.cs @@ -15,7 +15,7 @@ public class SwordSlashHCard : HeroCard yield return playerControls.StartCoroutine(playerControls.ChooseTarget(singleTargeting)); yield return new WaitForSeconds(0.4f); BattleParticipant target = singleTargeting.GetTarget(); - effectApplier.Apply(new DealDamageEffect(target, 1)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 1)); yield return new WaitForSeconds(0.8f); } } diff --git a/Assets/Battle/CardsMonsters/GolemBerserkMCard.cs b/Assets/Battle/CardsMonsters/GolemBerserkMCard.cs index 14c8c13..79d1ceb 100644 --- a/Assets/Battle/CardsMonsters/GolemBerserkMCard.cs +++ b/Assets/Battle/CardsMonsters/GolemBerserkMCard.cs @@ -13,11 +13,11 @@ public class GolemBerserkMCard : MonsterCard public override IEnumerator Use(IBattleEffectApplier effectApplier, MonsterViewpoint monsterViewpoint) { BattleParticipant target = AIUtils.GetNearestHero(monsterViewpoint, this.owner); - effectApplier.Apply(new DealDamageEffect(target, 8)); + effectApplier.Apply(new DealDamageEffect(Owner, target, 8)); yield return new WaitForSeconds(1f); foreach (BattleHero hero in monsterViewpoint.Heroes) { if (hero != target) { - effectApplier.Apply(new DealDamageEffect(hero, 4)); + effectApplier.Apply(new DealDamageEffect(Owner, hero, 4)); } } diff --git a/Assets/Battle/CardsMonsters/GolemChargeMCard.cs b/Assets/Battle/CardsMonsters/GolemChargeMCard.cs index cfe058f..7d99aa6 100644 --- a/Assets/Battle/CardsMonsters/GolemChargeMCard.cs +++ b/Assets/Battle/CardsMonsters/GolemChargeMCard.cs @@ -14,7 +14,7 @@ public class GolemChargeMCard : MonsterCard yield return new WaitForSeconds(0.5f); BattleParticipant target = AIUtils.GetFarthestHero(monsterViewpoint, this.owner); - DealDamageEffect damageEffect = new DealDamageEffect(target, 4); + DealDamageEffect damageEffect = new DealDamageEffect(Owner, target, 4); effectApplier.Apply(damageEffect); StatusEffect statusEffect = new StatusEffect(target, BattleStatus.Stun); effectApplier.Apply(statusEffect); diff --git a/Assets/Battle/CardsMonsters/GolemFistMCard.cs b/Assets/Battle/CardsMonsters/GolemFistMCard.cs index b89ef0a..406e0ee 100644 --- a/Assets/Battle/CardsMonsters/GolemFistMCard.cs +++ b/Assets/Battle/CardsMonsters/GolemFistMCard.cs @@ -11,7 +11,7 @@ public class GolemFistMCard : MonsterCard public override IEnumerator Use(IBattleEffectApplier effectApplier, MonsterViewpoint monsterViewpoint) { BattleParticipant target = AIUtils.GetNearestHero(monsterViewpoint, this.owner); - DealDamageEffect damageEffect = new DealDamageEffect(target, 3); + DealDamageEffect damageEffect = new DealDamageEffect(Owner, target, 3); effectApplier.Apply(damageEffect); yield break; } diff --git a/Assets/Battle/CardsMonsters/QuickSwiftDeathMCard.cs b/Assets/Battle/CardsMonsters/QuickSwiftDeathMCard.cs index 258bd5b..66ee712 100644 --- a/Assets/Battle/CardsMonsters/QuickSwiftDeathMCard.cs +++ b/Assets/Battle/CardsMonsters/QuickSwiftDeathMCard.cs @@ -11,7 +11,7 @@ public class QuickSwiftDeathMCard : MonsterCard public override IEnumerator Use(IBattleEffectApplier effectApplier, MonsterViewpoint monsterViewpoint) { BattleParticipant target = AIUtils.GetNearestHero(monsterViewpoint, this.owner); - DealDamageEffect damageEffect = new DealDamageEffect(target, 100); + DealDamageEffect damageEffect = new DealDamageEffect(Owner, target, 100); effectApplier.Apply(damageEffect); yield break; } diff --git a/Assets/Battle/CardsMonsters/VampireFangsMCard.cs b/Assets/Battle/CardsMonsters/VampireFangsMCard.cs index 1dabdb3..53f2085 100644 --- a/Assets/Battle/CardsMonsters/VampireFangsMCard.cs +++ b/Assets/Battle/CardsMonsters/VampireFangsMCard.cs @@ -11,7 +11,7 @@ public class VampireFangsMCard : MonsterCard public override IEnumerator Use(IBattleEffectApplier effectApplier, MonsterViewpoint monsterViewpoint) { BattleParticipant target = AIUtils.GetHeroWithHighestHP(monsterViewpoint); - DealDamageEffect damageEffect = new DealDamageEffect(target, 2); + DealDamageEffect damageEffect = new DealDamageEffect(Owner, target, 2); effectApplier.Apply(damageEffect); if (damageEffect.AmountDealt > 0) { HealEffect healEffect = new HealEffect(this.owner, damageEffect.AmountDealt); diff --git a/Assets/Battle/CheatBattle.cs b/Assets/Battle/CheatBattle.cs index 11dee07..2502875 100644 --- a/Assets/Battle/CheatBattle.cs +++ b/Assets/Battle/CheatBattle.cs @@ -20,20 +20,24 @@ public class CheatBattle: MonoBehaviour HCardId.Eagerness, HCardId.CrashingPunch, - HCardId.LightningHatchet, HCardId.BlindFury, HCardId.Cover, HCardId.Cover, - HCardId.Thunderstorm, HCardId.Scarring, - HCardId.Scarring, - HCardId.Meditate, + + HCardId.OilOfSharpness, HCardId.IronskinDraught, + + HCardId.LightningHatchet, + HCardId.Thunderstorm, + HCardId.Meditate, }; int[] hCardOwnerIndexes = new int[16] { 0, 0, 1, 1, 2, 2, - 0, 2, 0, 0, 0, 2, 0, 0, 2, 1, + 0, 0, 0, 0, 0, + 1, 1, + 2, 2, 2, }; MonsterId[] monsterIds = new MonsterId[3] { diff --git a/Assets/Battle/DefaultHeroCard.cs b/Assets/Battle/DefaultHeroCard.cs new file mode 100644 index 0000000..b8f529a --- /dev/null +++ b/Assets/Battle/DefaultHeroCard.cs @@ -0,0 +1,13 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public abstract class DefaultHeroCard: HeroCard +{ + public DefaultHeroCard(BattleParticipant owner, HCardId id, string displayName, int cost, CardType type, + string effectText) + : base(owner, id, displayName, cost, type, effectText) {} + + public abstract IEnumerator UseDefault(IBattleEffectApplier effectApplier, + MonsterViewpoint viewpoint, BattlePlayerControls playerControls); +} diff --git a/Assets/Battle/DefaultHeroCard.cs.meta b/Assets/Battle/DefaultHeroCard.cs.meta new file mode 100644 index 0000000..bbe0cfe --- /dev/null +++ b/Assets/Battle/DefaultHeroCard.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 6d2e07039087c844c863e1b155f4d983 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/DefaultsManager.cs b/Assets/Battle/DefaultsManager.cs new file mode 100644 index 0000000..697c800 --- /dev/null +++ b/Assets/Battle/DefaultsManager.cs @@ -0,0 +1,42 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class DefaultsManager +{ + public delegate IEnumerator UseDefaultAction(DefaultHeroCard card); + + private Dictionary mHeroDefaults = new Dictionary(); + + public DefaultsManager() { + } + + public DefaultHeroCard Setup(DefaultEffect effect) { + DefaultHeroCard newCard = effect.Card; + DefaultHeroCard previousCard = null; + BattleHero heroOwner = (BattleHero) newCard.Owner; + mHeroDefaults.TryGetValue(heroOwner, out previousCard); + + mHeroDefaults[heroOwner] = newCard; + + return previousCard; + } + + public IEnumerator UseHeroDefaults( + BattleHero[] heroes, ParticipantActivity activity, + UseDefaultAction usedDefaultAction) { + foreach (BattleHero hero in heroes) { + if (hero == null) { + continue; + } + + if (activity.GetNonEmotionCardsUsedThisRound(hero) == 0) { + DefaultHeroCard defaultCard; + mHeroDefaults.TryGetValue(hero, out defaultCard); + if (defaultCard != null) { + yield return usedDefaultAction(defaultCard); + } + } + } + } +} diff --git a/Assets/Battle/DefaultsManager.cs.meta b/Assets/Battle/DefaultsManager.cs.meta new file mode 100644 index 0000000..fca1d2b --- /dev/null +++ b/Assets/Battle/DefaultsManager.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 9517ccf8137932d458bdd10b84540001 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/Effects/BuffParticipantEffect.cs b/Assets/Battle/Effects/BuffParticipantEffect.cs new file mode 100644 index 0000000..2b8704b --- /dev/null +++ b/Assets/Battle/Effects/BuffParticipantEffect.cs @@ -0,0 +1,27 @@ +using System.Collections; +using System.Collections.Generic; +using UnityEngine; + +public class BuffParticipantEffect : IBattleEffect +{ + private BattleParticipant mParticipant; + private BuffType mType; + private BuffDuration mDuration; + private int mAmount; + + public BuffParticipantEffect(BattleParticipant participant, BuffType type, int amount, BuffDuration duration) { + mParticipant = participant; + mType = type; + mAmount = amount; + mDuration = duration; + } + + public void Apply(IBattleEffectResolver resolver) { + resolver.BuffParticipant(this); + } + + public BattleParticipant Participant {get => mParticipant;} + public BuffType Type {get => mType;} + public BuffDuration Duration {get => mDuration;} + public int Amount {get => mAmount;} +} diff --git a/Assets/Battle/Effects/BuffParticipantEffect.cs.meta b/Assets/Battle/Effects/BuffParticipantEffect.cs.meta new file mode 100644 index 0000000..f47f577 --- /dev/null +++ b/Assets/Battle/Effects/BuffParticipantEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 203a8da7e3f13cf478d850b47c3f762e +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 add8423..2aef7f6 100644 --- a/Assets/Battle/Effects/DealDamageEffect.cs +++ b/Assets/Battle/Effects/DealDamageEffect.cs @@ -4,11 +4,13 @@ using UnityEngine; public class DealDamageEffect : IBattleEffect { + private BattleParticipant source; private BattleParticipant target; private int amount; private int amountDealt; - public DealDamageEffect(BattleParticipant target, int amount) { + public DealDamageEffect(BattleParticipant source, BattleParticipant target, int amount) { + this.source = source; this.target = target; this.amount = amount; } @@ -17,6 +19,7 @@ public class DealDamageEffect : IBattleEffect this.amountDealt = resolver.DealDamage(this); } + public BattleParticipant Source {get => this.source;} public BattleParticipant Target {get => this.target;} public int Amount {get => this.amount;} public int AmountDealt {get => this.amountDealt;} diff --git a/Assets/Battle/Effects/DefaultEffect.cs b/Assets/Battle/Effects/DefaultEffect.cs new file mode 100644 index 0000000..66cf6e3 --- /dev/null +++ b/Assets/Battle/Effects/DefaultEffect.cs @@ -0,0 +1,19 @@ +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using UnityEngine; + +public class DefaultEffect : IBattleEffect +{ + private DefaultHeroCard mCard; + + public DefaultEffect(DefaultHeroCard card) { + mCard = card; + } + + public void Apply(IBattleEffectResolver resolver) { + resolver.SetupDefault(this); + } + + public DefaultHeroCard Card {get => mCard;} +} diff --git a/Assets/Battle/Effects/DefaultEffect.cs.meta b/Assets/Battle/Effects/DefaultEffect.cs.meta new file mode 100644 index 0000000..f62d1a8 --- /dev/null +++ b/Assets/Battle/Effects/DefaultEffect.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: c713bb4a53fb33249a23147f4f67114c +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/HeroCardDatabase.cs b/Assets/Battle/HeroCardDatabase.cs index 30e5fec..9302a56 100644 --- a/Assets/Battle/HeroCardDatabase.cs +++ b/Assets/Battle/HeroCardDatabase.cs @@ -24,6 +24,7 @@ public enum HCardId { LeadShot, SmokeBomb, Eagerness, + OilOfSharpness, } public class HeroCardDatabase : CardDatabase @@ -60,6 +61,8 @@ public class HeroCardDatabase : CardDatabase return new SmokeBombHCard(owner); case HCardId.Eagerness: return new EagernessHCard(owner); + case HCardId.OilOfSharpness: + return new OilOfSharpnessHCard(owner); default: throw new System.ArgumentException("HCardId unknown", "id"); } diff --git a/Assets/Battle/IBattleEffectResolver.cs b/Assets/Battle/IBattleEffectResolver.cs index 14410e2..8ecd9ff 100644 --- a/Assets/Battle/IBattleEffectResolver.cs +++ b/Assets/Battle/IBattleEffectResolver.cs @@ -13,9 +13,11 @@ public interface IBattleEffectResolver { void IncreaseHeroMaxEnergy(IncreaseMaxEnergyEffect delta); void IncreaseMaxHP(IncreaseMaxHPEffect effect); void ModifyInsight(ModifyInsightEffect effect); + void BuffParticipant(BuffParticipantEffect effect); void DrawCards(DrawCardsEffect effect); void AcquireCards(AcquireCardsEffect effect); void Rotate(RotateEffect effect); + void SetupDefault(DefaultEffect effect); void ArmDamageTrigger(DamageTrigger damageTrigger); } diff --git a/Assets/Battle/ParticipantActivity.cs b/Assets/Battle/ParticipantActivity.cs new file mode 100644 index 0000000..54560d2 --- /dev/null +++ b/Assets/Battle/ParticipantActivity.cs @@ -0,0 +1,30 @@ +using System.Collections.Generic; +using System.Linq; + +public class ParticipantActivity { + + private Dictionary> mCardsUsedThisRound = new Dictionary>(); + + public ParticipantActivity() { + } + + public void NotifyParticipantUsedCard(BattleParticipant participant, BaseCard card) { + if (mCardsUsedThisRound.ContainsKey(participant)) { + mCardsUsedThisRound[participant].Add(card); + } else { + mCardsUsedThisRound[participant] = new List() {card}; + } + } + + public int GetNonEmotionCardsUsedThisRound(BattleParticipant participant) { + if (mCardsUsedThisRound.ContainsKey(participant)) { + return mCardsUsedThisRound[participant].Count(card => card.Type != CardType.Emotion); + } else { + return 0; + } + } + + public void NextRound() { + mCardsUsedThisRound.Clear(); + } +} \ No newline at end of file diff --git a/Assets/Battle/ParticipantActivity.cs.meta b/Assets/Battle/ParticipantActivity.cs.meta new file mode 100644 index 0000000..634a2eb --- /dev/null +++ b/Assets/Battle/ParticipantActivity.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: abe2bbff2aef9fc4388e4aad5eb0b1f7 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Battle/PlayArea.cs b/Assets/Battle/PlayArea.cs index 38db77a..b6ac69c 100644 --- a/Assets/Battle/PlayArea.cs +++ b/Assets/Battle/PlayArea.cs @@ -10,10 +10,12 @@ public class PlayArea private List heroPermanents; private List monsterPermanents; + private DefaultsManager mDefaultsManager; public PlayArea() { this.heroPermanents = new List(); this.monsterPermanents = new List(); + mDefaultsManager = new DefaultsManager(); } public List GetHeroPermanents() { @@ -40,6 +42,24 @@ public class PlayArea TriggerPlayAreaChanged(); } + public DefaultHeroCard SetupDefault(DefaultEffect effect) { + DefaultHeroCard previousDefault = mDefaultsManager.Setup(effect); + if (previousDefault != null) { + RemoveHeroPermanent(previousDefault); + } + + AddPlayedHeroPermanent(effect.Card); + + TriggerPlayAreaChanged(); + return previousDefault; + } + + public IEnumerator UseHeroDefaults( + BattleHero[] heroes, ParticipantActivity activity, + DefaultsManager.UseDefaultAction useDefaultAction) { + yield return mDefaultsManager.UseHeroDefaults(heroes, activity, useDefaultAction); + } + private void TriggerPlayAreaChanged() { if (OnPlayAreaChanged != null) OnPlayAreaChanged(); } diff --git a/Assets/Resources/CardArt/HeroOilOfSharpness.jpg b/Assets/Resources/CardArt/HeroOilOfSharpness.jpg new file mode 100644 index 0000000..ab26bd3 Binary files /dev/null and b/Assets/Resources/CardArt/HeroOilOfSharpness.jpg differ diff --git a/Assets/Resources/CardArt/HeroOilOfSharpness.jpg.meta b/Assets/Resources/CardArt/HeroOilOfSharpness.jpg.meta new file mode 100644 index 0000000..3ad81c8 --- /dev/null +++ b/Assets/Resources/CardArt/HeroOilOfSharpness.jpg.meta @@ -0,0 +1,92 @@ +fileFormatVersion: 2 +guid: b5745ed63f80a524ca329b8c41725d97 +TextureImporter: + internalIDToNameTable: [] + externalObjects: {} + serializedVersion: 11 + mipmaps: + mipMapMode: 0 + enableMipMap: 0 + sRGBTexture: 1 + linearTexture: 0 + fadeOut: 0 + borderMipMap: 0 + mipMapsPreserveCoverage: 0 + alphaTestReferenceValue: 0.5 + mipMapFadeDistanceStart: 1 + mipMapFadeDistanceEnd: 3 + bumpmap: + convertToNormalMap: 0 + externalNormalMap: 0 + heightScale: 0.25 + normalMapFilter: 0 + isReadable: 0 + streamingMipmaps: 0 + streamingMipmapsPriority: 0 + grayScaleToAlpha: 0 + generateCubemap: 6 + cubemapConvolution: 0 + seamlessCubemap: 0 + textureFormat: 1 + maxTextureSize: 2048 + textureSettings: + serializedVersion: 2 + filterMode: -1 + aniso: -1 + mipBias: -100 + wrapU: 1 + wrapV: 1 + wrapW: 1 + nPOTScale: 0 + lightmap: 0 + compressionQuality: 50 + spriteMode: 1 + spriteExtrude: 1 + spriteMeshType: 1 + alignment: 0 + spritePivot: {x: 0.5, y: 0.5} + spritePixelsToUnits: 100 + spriteBorder: {x: 0, y: 0, z: 0, w: 0} + spriteGenerateFallbackPhysicsShape: 1 + alphaUsage: 1 + alphaIsTransparency: 1 + spriteTessellationDetail: -1 + textureType: 8 + textureShape: 1 + singleChannelComponent: 0 + maxTextureSizeSet: 0 + compressionQualitySet: 0 + textureFormatSet: 0 + applyGammaDecoding: 0 + platformSettings: + - serializedVersion: 3 + buildTarget: DefaultTexturePlatform + maxTextureSize: 2048 + resizeAlgorithm: 0 + textureFormat: -1 + textureCompression: 1 + compressionQuality: 50 + crunchedCompression: 0 + allowsAlphaSplitting: 0 + overridden: 0 + androidETC2FallbackOverride: 0 + forceMaximumCompressionQuality_BC6H_BC7: 0 + spriteSheet: + serializedVersion: 2 + sprites: [] + outline: [] + physicsShape: [] + bones: [] + spriteID: 5e97eb03825dee720800000000000000 + internalID: 0 + vertices: [] + indices: + edges: [] + weights: [] + secondaryTextures: [] + spritePackingTag: + pSDRemoveMatte: 0 + pSDShowRemoveMatteOption: 0 + userData: + assetBundleName: + assetBundleVariant: diff --git a/TODO.txt b/TODO.txt index 6945bda..5d95afb 100644 --- a/TODO.txt +++ b/TODO.txt @@ -7,6 +7,10 @@ Battle - Extend BattleState object to contain everything for effect resolver to work - Implement a stack/queue to control effects - Make battle work with numbers different than 3 vs 3 +- Merge HeroCard and MonsterCard +- Make Enchantments be dropped as an effect like Defaults +- No need to start coroutine for targeting +- Indicate which Default is triggering Story - Make dialogue show letter by letter.