Refactor EffectResolver out of BattleController
This commit is contained in:
parent
86715b790d
commit
109e55a270
5 changed files with 204 additions and 177 deletions
|
|
@ -4,7 +4,7 @@ using System.Linq;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using UnityEngine.SceneManagement;
|
using UnityEngine.SceneManagement;
|
||||||
|
|
||||||
public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffectResolver
|
public class BattleController : MonoBehaviour, IBattleEffectApplier
|
||||||
{
|
{
|
||||||
private bool STABLE_HAND_STYLE = true;
|
private bool STABLE_HAND_STYLE = true;
|
||||||
|
|
||||||
|
|
@ -20,6 +20,7 @@ public class BattleController : MonoBehaviour, IBattleEffectApplier, IBattleEffe
|
||||||
private HandPlayability<HeroCard> heroHandPlayability;
|
private HandPlayability<HeroCard> heroHandPlayability;
|
||||||
private HandPlayability<MonsterCard> monsterHandPlayability;
|
private HandPlayability<MonsterCard> monsterHandPlayability;
|
||||||
private TurnIntentions<MonsterCard> monsterIntentions;
|
private TurnIntentions<MonsterCard> monsterIntentions;
|
||||||
|
private IBattleEffectResolver effectResolver;
|
||||||
|
|
||||||
private delegate void BattleStateChangedAction();
|
private delegate void BattleStateChangedAction();
|
||||||
private event BattleStateChangedAction OnBattleStateChanged;
|
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.state.HeroDeck, this.state.MonsterDeck, this.state.PlayArea, this.state.InsightLevel,
|
||||||
this.heroHandPlayability, this.monsterHandPlayability, this.monsterIntentions,
|
this.heroHandPlayability, this.monsterHandPlayability, this.monsterIntentions,
|
||||||
this.uiCanvas.transform.localScale.x);
|
this.uiCanvas.transform.localScale.x);
|
||||||
|
|
||||||
|
this.effectResolver = new EffectResolver(this.state);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start is called before the first frame update
|
// 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;}
|
public BattleState State {get => this.state;}
|
||||||
|
|
||||||
// IBattleEffectApplier
|
// IBattleEffectApplier
|
||||||
public void Apply(IBattleEffect effect) {
|
public void Apply(IBattleEffect effect) {
|
||||||
effect.Apply(this);
|
effect.Apply(this.effectResolver);
|
||||||
}
|
|
||||||
|
|
||||||
// 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);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -129,6 +129,12 @@ public class BattleState: MonsterViewpoint
|
||||||
if (OnMonsterPositionsSet != null) OnMonsterPositionsSet();
|
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 BattleHero[] Heroes {get => this.heroes;}
|
||||||
public BattleMonster[] Monsters {get => this.monsters;}
|
public BattleMonster[] Monsters {get => this.monsters;}
|
||||||
public BattleClock Clock {get => this.clock;}
|
public BattleClock Clock {get => this.clock;}
|
||||||
|
|
|
||||||
182
Assets/Battle/EffectResolver.cs
Normal file
182
Assets/Battle/EffectResolver.cs
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
11
Assets/Battle/EffectResolver.cs.meta
Normal file
11
Assets/Battle/EffectResolver.cs.meta
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
fileFormatVersion: 2
|
||||||
|
guid: dce6dd03330d4794faadaef3b88a8720
|
||||||
|
MonoImporter:
|
||||||
|
externalObjects: {}
|
||||||
|
serializedVersion: 2
|
||||||
|
defaultReferences: []
|
||||||
|
executionOrder: 0
|
||||||
|
icon: {instanceID: 0}
|
||||||
|
userData:
|
||||||
|
assetBundleName:
|
||||||
|
assetBundleVariant:
|
||||||
1
TODO.txt
1
TODO.txt
|
|
@ -4,7 +4,6 @@ Battle
|
||||||
- Show on who enemies will use the cards
|
- Show on who enemies will use the cards
|
||||||
- Highlight which card is targeting
|
- Highlight which card is targeting
|
||||||
- Allow cancelling targeting
|
- Allow cancelling targeting
|
||||||
- Extend BattleState object to contain everything for effect resolver to work
|
|
||||||
- Implement a stack/queue to control effects
|
- Implement a stack/queue to control effects
|
||||||
- Make battle work with numbers different than 3 vs 3
|
- Make battle work with numbers different than 3 vs 3
|
||||||
- Merge HeroCard and MonsterCard
|
- Merge HeroCard and MonsterCard
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue