-
Notifications
You must be signed in to change notification settings - Fork 0
/
INEQ_AurielsShield.psc
351 lines (302 loc) · 11.7 KB
/
INEQ_AurielsShield.psc
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
Scriptname INEQ_AurielsShield extends INEQ_AbilityBaseShield
{Script for reflecting shield to appear to reflect certain incoming spells.}
;=========================================== Properties ===========================================================================>
Message Property OptionsMenu Auto
Message Property ChargeIntervalMenu Auto
Spell Property ChargeSpell1 Auto
Spell Property ChargeSpell2 Auto
Spell Property ChargeSpell3 Auto
Sound Property ChargSound Auto
ImagespaceModifier Property ChargeIMod Auto
ImagespaceModifier Property BlastIMod Auto
bool Property bBalanced Auto Hidden
Int Property ChargeMode Auto Hidden ;(0==prioritize shared charges, 1=prioritize local, 2= use local only)
Int Property ChargeInterval Auto Hidden
;========================================== Autoreadonly ==========================================================================>
Int Property NumStages = 3 Autoreadonly
int Property DEFChargeMode = 1 Autoreadonly
Int Property DEFMaxLocalCharge = 3 Autoreadonly
Int Property DEFChargeInterval = 5 Autoreadonly
String Property BashExit = "bashExit" Autoreadonly ; exit bashing
String Property BashStop = "bashStop" Autoreadonly ; stop bashing
String Property BashRelease = "bashRelease" Autoreadonly ; power bashing
;=========================================== Variables ============================================================================>
bool RefIsPlayer
int TimesHit
;===============================================================================================================================
;==================================== Maintenance ================================================
;================================================================================================
Event OnEffectStart (Actor akTarget, Actor akCaster)
parent.EffectStart(akTarget, akCaster)
RefIsPlayer = ( SelfRef == Game.GetPlayer() )
EndEvent
Function RestoreDefaultFields()
parent.RestoreDefaultFields()
bBalanced = True
TimesHit = 0
LocalCharge = 0
ChargeInterval = DEFChargeInterval
MaxLocalCharge = DEFMaxLocalCharge
ChargeMode = DEFChargeMode
EndFunction
;===============================================================================================================================
;==================================== States ================================================
;================================================================================================
; Override of base state in order to use busy state for OnWardHit (since States cannot be nested)
Auto State Unequipped
Event OnBeginState()
UnregisterForUpdate()
UnregisterForAnimationEvent(selfRef, BashRelease)
UnregisterForAnimationEvent(selfRef, BashExit)
UnregisterForAnimationEvent(selfRef, BashStop)
EndEvent
Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
EquipCheckKW(akReference)
EndEvent
Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
EndEvent
Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
EndEvent
Event OnWardHit(ObjectReference akCaster, Spell akSpell, int aiStatus)
EndEvent
Event OnAnimationEvent(ObjectReference akSource, string EventName)
EndEvent
EndState
;___________________________________________________________________________________________________________________________
; Main state, uses all external events except for OnWardHit when it's delayed
State Equipped
Event OnBeginState()
if (RefIsPlayer)
registerForAnimationEvent(selfRef, BashRelease)
else
registerForAnimationEvent(selfRef, BashExit)
registerForAnimationEvent(selfRef, BashStop)
endif
UpdateShieldVisuals()
EndEvent
EndState
;===============================================================================================================================
;==================================== Events ================================================
;================================================================================================
; When hit, increments times hit, possibly increasing the charge of the shield. Power attacks provide twice as much charge
Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
if abHitBlocked
TimesHit += 1
if TimesHit >= ChargeInterval
AddCharge()
TimesHit %= ChargeInterval
endif
else
;debug.Trace("I've been hit but NOT in the shield while blocking!")
endif
EndEvent
;___________________________________________________________________________________________________________________________
; Event for spellbreaker ward, increasing TimesHit at specified maximum frequency
Event OnWardHit(ObjectReference akCaster, Spell akSpell, int aiStatus)
if SelfRef.GetAnimationVariableBool("IsBlocking") && aiStatus == 1
TimesHit +=1
if TimesHit >= ChargeInterval
AddCharge()
TimesHit %= ChargeInterval
endif
GoToState("WardBusy")
RegisterForSingleUpdate(1.0)
endif
EndEvent
;Delay to prevent concentration spell from charging the ward too fast
State WardBusy
Event OnWardHit(ObjectReference akCaster, Spell akSpell, int aiStatus)
EndEvent
Event OnUpdate()
GoToState("Equipped")
EndEvent
Event OnEndState()
UnregisterForUpdate()
EndEvent
EndState
;___________________________________________________________________________________________________________________________
; Cast the apropriate spell on bash and removes charges. Possibly uses charges from SharedCharges
Event OnAnimationEvent(ObjectReference akSource, string EventName)
if RefIsPlayer
if EventName == BashRelease && SelfRef.GetActorValue("Stamina") > 0.0
if ChargeMode == 0
prioritizeShared()
elseif ChargeMode == 1
prioritizeLocal()
elseif ChargeMode == 2
localOnly()
else
Debug.Trace("INEQ_AurielsShield: Unhandled priority value " + ChargeMode)
endif
endif
else
if (eventName == BashExit) || (eventName == BashStop)
localOnly()
UpdateShieldVisuals()
endif
endif
EndEvent
;===============================================================================================================================
;==================================== Functions ================================================
;================================================================================================
; Uses any shared charges and -- if less than the top spell cost -- any aditional local charges
function prioritizeShared()
int total = RequestSharedChargeUpTo(NumStages)
total += removeLocalChargeUpTo(NumStages - total)
castBashSpell(total)
UpdateShieldVisuals(localCharge + GetSharedCharge())
Endfunction
; Uses any local charges first. If localCharge = 0, uses shared charges instead
function prioritizeLocal()
int total = removeLocalChargeUpTo(NumStages)
if total == 0
total = RequestSharedChargeUpTo(NumStages)
endif
castBashSpell(total)
UpdateShieldVisuals()
endFunction
; Only uses the number of local charges when casting bash spell. Allowing player to reliably charge shared charges for other abilities
function localOnly()
int total = removeLocalChargeUpTo(NumStages)
castBashSpell(total)
UpdateShieldVisuals()
endFunction
;___________________________________________________________________________________________________________________________
; Casts the offensive spell depending on the number of charges expended
function castBashSpell(int charges)
if charges == 3
BlastIMod.Apply(1.0)
ChargeSpell3.cast(selfRef)
elseif charges == 2
BlastIMod.Apply(0.6)
ChargeSpell2.cast(selfRef)
elseif charges == 1
BlastIMod.Apply(0.3)
ChargeSpell1.cast(selfRef)
endif
endFunction
;___________________________________________________________________________________________________________________________
; Add the given number of charges to the local charge. If too much, transfers the charges to the SharedCharge
function AddCharge(int num = 1)
LocalCharge += num
if LocalCharge > MaxLocalCharge
AddSharedCharge(LocalCharge - MaxLocalCharge)
LocalCharge = MaxLocalCharge
else
UpdateShieldVisuals()
if RefIsPlayer
ChargeIMod.Apply()
endif
endif
EndFunction
;___________________________________________________________________________________________________________________________
; Removes and returns the number of requested charges from the local charge
int function removeLocalChargeUpTo(int iRequest, bool bExact = False)
if iRequest > 0
if LocalCharge >= iRequest
LocalCharge -= iRequest
return iRequest
elseif !bExact
iRequest = LocalCharge
LocalCharge = 0
return iRequest
else
return 0
endif
else
return 0
endif
EndFunction
;___________________________________________________________________________________________________________________________
; Updates the visuals on the shield according to the number of local charges
Function UpdateShieldVisuals(int charges = 0)
if !charges
charges = LocalCharge
endif
if charges == 1
;debug.Notification("Shield at LEVEL 1")
selfRef.SetSubGraphFloatVariable("fDampRate", 1)
selfRef.SetSubGraphFloatVariable("fToggleBlend", 0.75)
elseif charges == 2
;debug.Notification("Shield at LEVEL 2")
selfRef.SetSubGraphFloatVariable("fDampRate", 1)
selfRef.SetSubGraphFloatVariable("fToggleBlend", 0.85)
elseif charges >= 3
;debug.Notification("Shield at LEVEL 3")
selfRef.SetSubGraphFloatVariable("fDampRate", 1)
selfRef.SetSubGraphFloatVariable("fToggleBlend", 1)
else
selfRef.SetSubGraphFloatVariable("fToggleBlend", 0)
endif
EndFunction
;===============================================================================================================================
;==================================== Menus ================================================
;================================================================================================
Function AbilityMenu(INEQ_MenuButtonConditional Button, INEQ_ListenerMenu ListenerMenu, GlobalVariable MenuActive)
bool abMenu = True
int aiButton
while abMenu && MenuActive.Value
setButtonMain(Button)
aiButton = OptionsMenu.Show()
if aiButton == 0
abMenu = False
elseif aiButton == 9 ; Cancel Menu
MenuActive.SetValue(0)
elseif aiButton == 1 ; Turn on Balanced (Magicka Based)
RestoreDefaultFields()
elseif aiButton == 2 ; Turn off Balanced (Cooldown Based)
bBalanced = False
elseif aiButton == 3 ; Charge Mode
ChargeMode = ListenerMenu.ChargeMode(ChargeMode, DEFChargeMode)
elseif aiButton == 4 ; Hits per Charge
MenuChargeInterval()
elseif aiButton == 5 ; Local Charge
MaxLocalCharge = ListenerMenu.ChargeStorage(MaxLocalCharge, DEFMaxLocalCharge)
endif
endwhile
EndFunction
Function setButtonMain(INEQ_MenuButtonConditional Button)
Button.clear()
if bBalanced
Button.set(2)
else
Button.set(1)
Button.set(4)
Button.set(5)
endif
Button.set(3)
Button.set(9)
EndFunction
;___________________________________________________________________________________________________________________________
Function MenuChargeInterval()
bool abMenu = True
int aiButton
While abMenu
Debug.Notification("Hits until charge: " +ChargeInterval)
aiButton = ChargeIntervalMenu.Show()
if aiButton == 0
return
elseif aiButton == 1
ChargeInterval -= 50
elseif aiButton == 2
ChargeInterval -= 10
elseif aiButton == 3
ChargeInterval -= 5
elseif aiButton == 4
ChargeInterval -= 1
elseif aiButton == 5
ChargeInterval += 1
elseif aiButton == 6
ChargeInterval += 5
elseif aiButton == 7
ChargeInterval += 10
elseif aiButton == 8
ChargeInterval += 50
elseif aiButton == 9
ChargeInterval = DEFChargeInterval
endif
if ChargeInterval < 1
ChargeInterval = 1
endif
endwhile
EndFunction