mixedcards/Assets/Battle/BattleController.cs
2020-09-19 21:33:32 -04:00

223 lines
6.8 KiB
C#

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<BattleParticipantSprite>();
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<BattleParticipantSprite>();
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();
}
}
public void DealDamage(BattleParticipant target, int amount) {
target.DealDamage(amount);
}
public void AddBlock(BattleParticipant target, int amount) {
target.AddBlock(amount);
}
}