-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDelayedDamageStatusEffect.cs
144 lines (130 loc) · 5.73 KB
/
DelayedDamageStatusEffect.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using Handelabra.Sentinels.Engine.Controller;
using Handelabra.Sentinels.Engine.Model;
namespace Jp.SOTMUtilities
{
// A reflection status effect indicating that one card will do damage to a target at a the start of a later phase.
// Due to engine limitations, you must still provide the method for this reflection status effect to call.
// That function can simply be:
//
// public IEnumerator HandleDelayedDamage(PhaseChangeAction unused, OnPhaseChangeStatusEffect sourceEffect)
// {
// return this.DoDelayedDamage(sourceEffect);
// }
//
// The damage will be cancelled if the card card receiving the damage leaves play. The damage source is not
// specified in the status effect, so the effect will not necessarily expire if the damage source leaves play.
// That's up to you.
//
// The damage will not occur until the specific phase it happens in occurs, and damage triggers will fire then.
//
// The only expiry criteria in the status effect is TargetLeavesPlayExpiryCriteria.IsOneOfTheseCards. Additional
// criteria can be used if you wish to expire on other things.
//
// Use the effect by making a new DelayedDamageStatusEffect then calling DealDamageToTargetAtStartOfNextTurn.
[Serializable]
public class DelayedDamageStatusEffect : OnPhaseChangeStatusEffect
{
public DelayedDamageStatusEffect(Card cardWithMethod, string nameOfMethod, string description, Card cardSource)
: base(cardWithMethod, nameOfMethod, description, new TriggerType[] { TriggerType.DealDamage }, cardSource)
{
}
// At the start of 'player's next turn, deal 'target' 'damage' damage of type 'damageType',
// with an as-yet undetermined damage source.
public void DealDamageToTargetAtStartOfNextTurn(TurnTaker player, Card target, int damage, DamageType damageType)
{
DamageToDeal = damage;
DamageType = damageType;
UntilTargetLeavesPlay(target);
TurnTakerCriteria.IsSpecificTurnTaker = player;
TurnPhaseCriteria.Phase = Phase.Start;
BeforeOrAfter = BeforeOrAfter.After;
CanEffectStack = true;
DoesDealDamage = true;
}
public int DamageToDeal { get; private set; }
public DamageType DamageType { get; private set; }
public Card Target { get { return TargetLeavesPlayExpiryCriteria.IsOneOfTheseCards.FirstOrDefault(); } }
}
public static class DelayedDamageExtension
{
// Fires the delayed damage status effect. Source 'damageSource' will do the damage stored in 'effect', with
// 'co' as the CardSource.
//
// If 'effect' isn't a DelayedDamageStatusEffect, does something unspecified. Don't do that.
//
// Will add 'co' to CardControllerListType.CanCauseDamageOutOfPlay.
//
// If 'damageSource' is null, it defaults to 'co.CharacterCard'.
//
// Will expire the status effect.
public static IEnumerator DoDelayedDamage(this CardController co, OnPhaseChangeStatusEffect effect, DamageSource damageSource = null)
{
co.AddThisCardControllerToList(CardControllerListType.CanCauseDamageOutOfPlay);
if (damageSource == null)
{
damageSource = new DamageSource(co.GameController, co.CharacterCard);
}
IEnumerator e;
while (true)
{
var delayedDamageEffect = effect as DelayedDamageStatusEffect;
if (delayedDamageEffect == null) { break; }
var target = delayedDamageEffect.Target;
if (target == null) { break; }
if (damageSource.IsCard && damageSource.Card.IsIncapacitatedOrOutOfGame) { break; }
if (! target.IsTarget || !target.IsInPlayAndNotUnderCard) { break; }
if (co.GameController.IsCardVisibleToCardSource(target, co.GetCardSource(delayedDamageEffect)))
{
e = co.GameController.DealDamageToTarget(
damageSource,
target,
delayedDamageEffect.DamageToDeal,
delayedDamageEffect.DamageType,
cardSource: co.GetCardSource()
);
if (co.UseUnityCoroutines)
{
yield return co.GameController.StartCoroutine(e);
}
else
{
co.GameController.ExhaustCoroutine(e);
}
}
else
{
e = co.GameController.SendMessageAction(
$"{target.Title} is no longer visible",
Priority.Medium,
co.GetCardSource(),
new[] { target },
showCardSource: true
);
if (co.UseUnityCoroutines)
{
yield return co.GameController.StartCoroutine(e);
}
else
{
co.GameController.ExhaustCoroutine(e);
}
}
break;
}
e = co.GameController.ExpireStatusEffect(effect, co.GetCardSource());
if (co.UseUnityCoroutines)
{
yield return co.GameController.StartCoroutine(e);
}
else
{
co.GameController.ExhaustCoroutine(e);
}
}
}
}