using System.Collections; using System.Collections.Generic; using UnityEngine; public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffectResolver { public HeroId[] heroIds; public MonsterId[] monsterIds; public CardId[] cardIds; public HeroInfoUI heroUIPrefab; public GameObject uiCanvas; public BattlePlayerControls battlePlayerControls; private HeroDeck heroDeck; private PlayArea playArea; public BattleHero[] heroes; private GameObject[] heroSprites; private HeroInfoUI[] heroUIs; public BattleMonster[] monsters; private GameObject[] monsterSprites; private HeroInfoUI[] monsterUIs; private bool heroTurn; private int maxEnergy; private int energy; void Awake() { heroes = new BattleHero[3]; heroSprites = new GameObject[3]; heroUIs = new HeroInfoUI[3]; for (int i = 0; i < 3; i++) { HeroId id = heroIds[i]; heroes[i] = new BattleHero(id); heroes[i].Init(); heroSprites[i] = HeroDatabase.createHeroSprite(id); heroSprites[i].name = "Hero" + i + "_Sprite"; heroSprites[i].transform.position = new Vector3(-1 + -3 + 3 * i, 0, 0); BattleParticipantSprite bps = heroSprites[i].AddComponent(); bps.Init(battlePlayerControls, heroes[i]); bps.OnSpriteClicked += battlePlayerControls.NotifyParticipantSpriteClicked; heroUIs[i] = (HeroInfoUI) Instantiate(heroUIPrefab.gameObject, uiCanvas.transform).GetComponent(typeof(HeroInfoUI)); heroUIs[i].Init(heroSprites[i], heroes[i]); } monsters = new BattleMonster[3]; monsterSprites = new GameObject[3]; monsterUIs = new HeroInfoUI[3]; for (int i = 0; i < 3; i++) { MonsterId id = monsterIds[i]; monsters[i] = MonsterDatabase.createMonsterScript(id); monsters[i].Init(); monsterSprites[i] = MonsterDatabase.createMonsterSprite(id); monsterSprites[i].name = "Monster" + i + "_Sprite"; monsterSprites[i].transform.position = new Vector3(+1 + -3 + 3 * i, 3, 0); BattleParticipantSprite bps = monsterSprites[i].AddComponent(); bps.Init(battlePlayerControls, monsters[i]); bps.OnSpriteClicked += battlePlayerControls.NotifyParticipantSpriteClicked; monsterUIs[i] = (HeroInfoUI) Instantiate(heroUIPrefab.gameObject, uiCanvas.transform).GetComponent(typeof(HeroInfoUI)); monsterUIs[i].Init(monsterSprites[i], monsters[i]); } BattleParticipant[] cardOwners = new BattleParticipant[this.cardIds.Length]; for (int i = 0; i < this.cardIds.Length; i++) { cardOwners[i] = FindHeroByClass(CardDatabase.GetHeroIdOfCard(this.cardIds[i])); } this.heroDeck = new HeroDeck(this.cardIds, cardOwners); this.playArea = new PlayArea(); this.battlePlayerControls.Init(this.heroDeck, this.playArea); this.battlePlayerControls.OnCardUsed += this.NotifyCardUsed; this.battlePlayerControls.OnTurnPassed += this.NotifyTurnPassed; this.heroDeck.OnHandPileChanged += this.battlePlayerControls.NotifyHandPileChanged; } private BattleParticipant FindHeroByClass(HeroId heroId) { foreach (BattleHero battleHero in this.heroes) { if (battleHero.GetId() == heroId) return battleHero; } return null; } // Start is called before the first frame update void Start() { DecideEnemyTarget(); StartHeroTurn(); } // Update is called once per frame void Update() { } private void StartHeroTurn() { this.heroTurn = true; this.energy = this.maxEnergy; foreach (BattleHero hero in this.heroes) { hero.ResetBlock(); } this.heroDeck.DrawHand(); this.battlePlayerControls.NotifyHandPileChanged(); if (this.maxEnergy < 9) { this.maxEnergy++; this.energy++; } } private void StartEnemyTurn() { this.heroTurn = false; this.heroDeck.DiscardHand(); foreach (BattleMonster monster in this.monsters) { monster.ResetBlock(); } heroes[this.enemyTarget].DealDamage(2); DecideEnemyTarget(); StartHeroTurn(); } private int enemyTarget; private void DecideEnemyTarget() { this.enemyTarget = Random.Range(0, 3); Debug.Log("Will attack " + this.heroes[this.enemyTarget].GetDisplayName()); } public void NotifyCardUsed(BaseCard card) { if (!CanUseCard(card)) { throw new System.InvalidOperationException("Cannot use card " + card.GetDisplayName()); } StartCoroutine(UseCard(card)); } public IEnumerator UseCard(BaseCard card) { yield return card.Use(this, battlePlayerControls); PayCardCost(card); this.heroDeck.RemoveCardFromHand(card); if (card.IsPermanent()) { this.playArea.AddPlayedHeroPermanent(card); } else { this.heroDeck.MoveCardToDiscard(card); } } public void NotifyTurnPassed() { if (this.heroTurn) { StartEnemyTurn(); } } public bool CanUseCard(BaseCard card) { return this.heroTurn && this.energy >= card.GetCost(); } private void PayCardCost(BaseCard card) { this.energy -= card.GetCost(); } public int GetEnergy() { return this.energy; } public int GetMaxEnergy() { return this.maxEnergy; } public HeroDeck GetHeroDeck() { return this.heroDeck; } public PlayArea GetPlayArea() { return this.playArea; } // IBattleEffectApplier public void Apply(IBattleEffect effect) { effect.Apply(this); } // IBattleEffectResolver public void IncreaseHeroMaxEnergy(int delta) { this.maxEnergy += delta; } public void AcquireHeroCards(CardId[] cardIds, BattleZone zone, BattleHero owner) { foreach (CardId cardId in cardIds) { BaseCard acquiredCard = CardDatabase.CreateCard(cardId, owner); switch (zone) { case BattleZone.DrawPile: this.GetHeroDeck().PutCardOnTopOfDrawPile(acquiredCard); break; default: throw new System.NotImplementedException(); } } if (zone == BattleZone.DrawPile) { this.GetHeroDeck().ShuffleDrawPile(); } } }