Refactor EffectResolver out of BattleController

This commit is contained in:
henriquenakashima 2020-10-13 23:24:46 -04:00
parent 86715b790d
commit 109e55a270
5 changed files with 204 additions and 177 deletions

View file

@ -4,7 +4,7 @@ using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffectResolver
public class BattleController : MonoBehaviour, IBattleEffectApplier
{
private bool STABLE_HAND_STYLE = true;
@ -20,6 +20,7 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe
private HandPlayability<HeroCard> heroHandPlayability;
private HandPlayability<MonsterCard> monsterHandPlayability;
private TurnIntentions<MonsterCard> monsterIntentions;
private IBattleEffectResolver effectResolver;
private delegate void BattleStateChangedAction();
private event BattleStateChangedAction OnBattleStateChanged;
@ -52,6 +53,8 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe
this.state.HeroDeck, this.state.MonsterDeck, this.state.PlayArea, this.state.InsightLevel,
this.heroHandPlayability, this.monsterHandPlayability, this.monsterIntentions,
this.uiCanvas.transform.localScale.x);
this.effectResolver = new EffectResolver(this.state);
}
// Start is called before the first frame update
@ -317,184 +320,10 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe
}
}
private BattleParticipant[] GetTeam(TeamChoice team) {
return (team == TeamChoice.Heroes
? this.state.Heroes.Cast<BattleParticipant>().ToArray()
: this.state.Monsters.Cast<BattleParticipant>().ToArray());
}
public BattleState State {get => this.state;}
// IBattleEffectApplier
public void Apply(IBattleEffect effect) {
effect.Apply(this);
}
// IBattleEffectResolver
public void DropEmotion(DropEmotionEffect effect) {
if (!this.state.CanPlayEmotion(effect.Team)) {
throw new System.InvalidOperationException("Cannot play emotion");
}
this.state.NotifyPlayedEmotion(effect.Team);
EnergyPool pool = (effect.Team == TeamChoice.Heroes ? this.state.HeroEnergy : this.state.MonsterEnergy);
pool.MaxEnergy += effect.Amount;
pool.Energy += effect.Amount;
}
public void IncreaseHeroMaxEnergy(IncreaseMaxEnergyEffect effect) {
this.state.HeroEnergy.MaxEnergy += effect.Amount;
if (effect.Immediate) {
this.state.HeroEnergy.Energy += effect.Amount;
}
}
public void IncreaseMaxHP(IncreaseMaxHPEffect effect) {
if (effect.Target == null) return;
effect.Target.IncreaseMaxHP(effect.Amount);
}
public void ModifyInsight(ModifyInsightEffect effect) {
this.state.InsightLevel.Modify(effect.Amount);
}
public void DrawCards(DrawCardsEffect effect) {
if (effect.Team == TeamChoice.Heroes) {
for (int i = 0; i < effect.Amount; i++) {
this.state.HeroDeck.DrawCard();
}
} else {
for (int i = 0; i < effect.Amount; i++) {
this.state.MonsterDeck.DrawCard();
}
}
}
public void AcquireCards(AcquireCardsEffect effect) {
if (effect.Participant == null) return;
if (effect.Participant.Team == TeamChoice.Heroes) {
this.AcquireCardsTyped(effect, this.state.HeroDeck, new HeroCardDatabase());
} else {
this.AcquireCardsTyped(effect, this.state.MonsterDeck, new MonsterCardDatabase());
}
}
private void AcquireCardsTyped<BaseCardT>(
AcquireCardsEffect effect,
BattleDeck<BaseCardT> deck,
CardDatabase<BaseCardT> cardDatabase)
where BaseCardT : BaseCard {
foreach (int cardId in effect.CardIds) {
BaseCardT acquiredCard = cardDatabase.CreateCard(cardId, effect.Participant);
switch (effect.Zone) {
case BattleZone.DrawPile:
deck.PutCardOnTopOfDrawPile(acquiredCard);
break;
case BattleZone.DiscardPile:
deck.MoveCardToDiscard(acquiredCard);
break;
default:
throw new System.NotImplementedException();
}
}
if (effect.Zone == BattleZone.DrawPile) {
deck.ShuffleDrawPile();
}
}
public int DealDamage(DealDamageEffect effect) {
if (effect.Target == null) return 0;
int amount = effect.Amount;
if (effect.Source != null) {
amount += this.state.BuffManager.GetTotalBuffAmountOfType(effect.Source, BuffType.Power);
}
int damageDealt = effect.Target.DealDamage(amount);
this.state.TriggerManager.NotifyResolvedDamageEffect(effect);
return damageDealt;
}
public int DealMassDamage(MassDamageEffect effect) {
int damageDealt = 0;
BattleParticipant[] affectedTeam = GetTeam(effect.Team);
foreach (BattleParticipant bp in affectedTeam) {
damageDealt += bp.DealDamage(effect.Amount);
}
this.state.TriggerManager.NotifyResolvedMassDamageEffect(effect);
return damageDealt;
}
public int Heal(HealEffect effect) {
if (effect.Target == null) return 0;
int healedAmount = effect.Target.Heal(effect.Amount);
return healedAmount;
}
public void AddBlock(BlockEffect effect) {
if (effect.Target == null) return;
effect.Target.AddBlock(effect.Amount);
}
public void AddMassBlock(MassBlockEffect effect) {
BattleParticipant[] affectedTeam = GetTeam(effect.Team);
foreach (BattleParticipant bp in affectedTeam) {
bp.AddBlock(effect.Amount);
}
}
public void AddStatus(StatusEffect effect) {
if (effect.Target == null) return;
effect.Target.AddStatus(effect.Status, effect.Amount);
}
public void BuffParticipant(BuffParticipantEffect effect) {
this.state.BuffManager.AddBuff(effect, this.state.Clock.Now);
}
public void Rotate(RotateEffect effect) {
if (effect.Positions == 0) return;
BattleParticipant[] currentPositions = GetTeam(effect.Team);
int start = int.MaxValue;
int end = int.MinValue;
for (int i = 0; i < currentPositions.Length; i++) {
BattleParticipant bp = currentPositions[i];
if (bp != null) {
start = System.Math.Min(start, i);
end = System.Math.Max(end, i);
}
}
int[] newPositions = new int[currentPositions.Length];
for (int i = start; i <= end; i++) {
if (i < start || i > end) {
newPositions[i] = i;
} else {
int newI = start + MathUtil.TrueMod(
i - start - effect.Positions,
end - start + 1);
newPositions[newI] = i;
}
}
this.state.MoveTeamToNewPositions(effect.Team, newPositions);
}
public void SetupDefault(DefaultEffect effect) {
DefaultHeroCard previousDefault = this.state.PlayArea.SetupDefault(effect);
if (previousDefault != null) {
this.state.HeroDeck.MoveCardToDiscard(previousDefault);
}
}
public void ArmDamageTrigger(DamageTrigger damageTrigger) {
this.state.TriggerManager.ArmDamageTrigger(damageTrigger);
effect.Apply(this.effectResolver);
}
}

View file

@ -129,6 +129,12 @@ public class BattleState: MonsterViewpoint
if (OnMonsterPositionsSet != null) OnMonsterPositionsSet();
}
public BattleParticipant[] GetTeam(TeamChoice team) {
return (team == TeamChoice.Heroes
? this.heroes.Cast<BattleParticipant>().ToArray()
: this.monsters.Cast<BattleParticipant>().ToArray());
}
public BattleHero[] Heroes {get => this.heroes;}
public BattleMonster[] Monsters {get => this.monsters;}
public BattleClock Clock {get => this.clock;}

View file

@ -0,0 +1,182 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.SceneManagement;
public class EffectResolver : IBattleEffectResolver
{
private BattleState state;
public EffectResolver(BattleState state) {
this.state = state;
}
// IBattleEffectResolver
public void DropEmotion(DropEmotionEffect effect) {
if (!this.state.CanPlayEmotion(effect.Team)) {
throw new System.InvalidOperationException("Cannot play emotion");
}
this.state.NotifyPlayedEmotion(effect.Team);
EnergyPool pool = (effect.Team == TeamChoice.Heroes ? this.state.HeroEnergy : this.state.MonsterEnergy);
pool.MaxEnergy += effect.Amount;
pool.Energy += effect.Amount;
}
public void IncreaseHeroMaxEnergy(IncreaseMaxEnergyEffect effect) {
this.state.HeroEnergy.MaxEnergy += effect.Amount;
if (effect.Immediate) {
this.state.HeroEnergy.Energy += effect.Amount;
}
}
public void IncreaseMaxHP(IncreaseMaxHPEffect effect) {
if (effect.Target == null) return;
effect.Target.IncreaseMaxHP(effect.Amount);
}
public void ModifyInsight(ModifyInsightEffect effect) {
this.state.InsightLevel.Modify(effect.Amount);
}
public void DrawCards(DrawCardsEffect effect) {
if (effect.Team == TeamChoice.Heroes) {
for (int i = 0; i < effect.Amount; i++) {
this.state.HeroDeck.DrawCard();
}
} else {
for (int i = 0; i < effect.Amount; i++) {
this.state.MonsterDeck.DrawCard();
}
}
}
public void AcquireCards(AcquireCardsEffect effect) {
if (effect.Participant == null) return;
if (effect.Participant.Team == TeamChoice.Heroes) {
this.AcquireCardsTyped(effect, this.state.HeroDeck, new HeroCardDatabase());
} else {
this.AcquireCardsTyped(effect, this.state.MonsterDeck, new MonsterCardDatabase());
}
}
private void AcquireCardsTyped<BaseCardT>(
AcquireCardsEffect effect,
BattleDeck<BaseCardT> deck,
CardDatabase<BaseCardT> cardDatabase)
where BaseCardT : BaseCard {
foreach (int cardId in effect.CardIds) {
BaseCardT acquiredCard = cardDatabase.CreateCard(cardId, effect.Participant);
switch (effect.Zone) {
case BattleZone.DrawPile:
deck.PutCardOnTopOfDrawPile(acquiredCard);
break;
case BattleZone.DiscardPile:
deck.MoveCardToDiscard(acquiredCard);
break;
default:
throw new System.NotImplementedException();
}
}
if (effect.Zone == BattleZone.DrawPile) {
deck.ShuffleDrawPile();
}
}
public int DealDamage(DealDamageEffect effect) {
if (effect.Target == null) return 0;
int amount = effect.Amount;
if (effect.Source != null) {
amount += this.state.BuffManager.GetTotalBuffAmountOfType(effect.Source, BuffType.Power);
}
int damageDealt = effect.Target.DealDamage(amount);
this.state.TriggerManager.NotifyResolvedDamageEffect(effect);
return damageDealt;
}
public int DealMassDamage(MassDamageEffect effect) {
int damageDealt = 0;
BattleParticipant[] affectedTeam = this.state.GetTeam(effect.Team);
foreach (BattleParticipant bp in affectedTeam) {
damageDealt += bp.DealDamage(effect.Amount);
}
this.state.TriggerManager.NotifyResolvedMassDamageEffect(effect);
return damageDealt;
}
public int Heal(HealEffect effect) {
if (effect.Target == null) return 0;
int healedAmount = effect.Target.Heal(effect.Amount);
return healedAmount;
}
public void AddBlock(BlockEffect effect) {
if (effect.Target == null) return;
effect.Target.AddBlock(effect.Amount);
}
public void AddMassBlock(MassBlockEffect effect) {
BattleParticipant[] affectedTeam = this.state.GetTeam(effect.Team);
foreach (BattleParticipant bp in affectedTeam) {
bp.AddBlock(effect.Amount);
}
}
public void AddStatus(StatusEffect effect) {
if (effect.Target == null) return;
effect.Target.AddStatus(effect.Status, effect.Amount);
}
public void BuffParticipant(BuffParticipantEffect effect) {
this.state.BuffManager.AddBuff(effect, this.state.Clock.Now);
}
public void Rotate(RotateEffect effect) {
if (effect.Positions == 0) return;
BattleParticipant[] currentPositions = this.state.GetTeam(effect.Team);
int start = int.MaxValue;
int end = int.MinValue;
for (int i = 0; i < currentPositions.Length; i++) {
BattleParticipant bp = currentPositions[i];
if (bp != null) {
start = System.Math.Min(start, i);
end = System.Math.Max(end, i);
}
}
int[] newPositions = new int[currentPositions.Length];
for (int i = start; i <= end; i++) {
if (i < start || i > end) {
newPositions[i] = i;
} else {
int newI = start + MathUtil.TrueMod(
i - start - effect.Positions,
end - start + 1);
newPositions[newI] = i;
}
}
this.state.MoveTeamToNewPositions(effect.Team, newPositions);
}
public void SetupDefault(DefaultEffect effect) {
DefaultHeroCard previousDefault = this.state.PlayArea.SetupDefault(effect);
if (previousDefault != null) {
this.state.HeroDeck.MoveCardToDiscard(previousDefault);
}
}
public void ArmDamageTrigger(DamageTrigger damageTrigger) {
this.state.TriggerManager.ArmDamageTrigger(damageTrigger);
}
}

View file

@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: dce6dd03330d4794faadaef3b88a8720
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: