Use TESHitEvent to track unlock spell hits
This commit is contained in:
parent
3c1725cbcb
commit
a43aa14bef
Binary file not shown.
BIN
SKSE/Plugins/EnderalSE.dll
(Stored with Git LFS)
BIN
SKSE/Plugins/EnderalSE.dll
(Stored with Git LFS)
Binary file not shown.
BIN
Skyrim.esm
BIN
Skyrim.esm
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
scripts/_00E_UnlockSpellAlias.pex
Normal file
BIN
scripts/_00E_UnlockSpellAlias.pex
Normal file
Binary file not shown.
|
@ -13,6 +13,7 @@ void EventListener::Install()
|
||||||
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
|
RE::UI::GetSingleton()->AddEventSink<RE::MenuOpenCloseEvent>(EventListener::GetSingleton());
|
||||||
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
|
SKSE::GetModCallbackEventSource()->AddEventSink(EventListener::GetSingleton());
|
||||||
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESCombatEvent>()->AddEventSink(EventListener::GetSingleton());
|
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESCombatEvent>()->AddEventSink(EventListener::GetSingleton());
|
||||||
|
RE::ScriptEventSourceHolder::GetSingleton()->GetEventSource<RE::TESHitEvent>()->AddEventSink(EventListener::GetSingleton());
|
||||||
}
|
}
|
||||||
|
|
||||||
auto EventListener::ProcessEvent(
|
auto EventListener::ProcessEvent(
|
||||||
|
@ -99,3 +100,34 @@ auto EventListener::ProcessEvent(
|
||||||
|
|
||||||
return RE::BSEventNotifyControl::kContinue;
|
return RE::BSEventNotifyControl::kContinue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto EventListener::ProcessEvent(
|
||||||
|
const RE::TESHitEvent* a_event,
|
||||||
|
RE::BSTEventSource<RE::TESHitEvent>* a_eventSource)
|
||||||
|
-> RE::BSEventNotifyControl
|
||||||
|
{
|
||||||
|
if (!a_event || !a_event->cause || a_event->cause->formID != 0x14) {
|
||||||
|
return RE::BSEventNotifyControl::kContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE::FormID spellFormID = a_event->projectile ? a_event->projectile : a_event->source;
|
||||||
|
RE::TESObjectREFR* containerRef = a_event->target ? a_event->target->As<RE::TESObjectREFR>() : nullptr;
|
||||||
|
|
||||||
|
if (!containerRef || !spellFormID) {
|
||||||
|
return RE::BSEventNotifyControl::kContinue;
|
||||||
|
}
|
||||||
|
|
||||||
|
RE::TESBoundObject* baseObject = containerRef->GetBaseObject();
|
||||||
|
|
||||||
|
if (baseObject && (baseObject->Is(RE::FormType::Container) || baseObject->Is(RE::FormType::Door)) && containerRef->IsLocked()) {
|
||||||
|
auto* dataHandler = RE::TESDataHandler::GetSingleton();
|
||||||
|
const RE::BGSListForm* formList = dataHandler ? dataHandler->LookupForm<RE::BGSListForm>(0x44EE4, "Skyrim.esm") : nullptr;
|
||||||
|
|
||||||
|
if (formList && formList->HasForm(spellFormID)) {
|
||||||
|
SKSE::ModCallbackEvent modEvent{ "Enderal_UnlockSpellHit", "", spellFormID, containerRef };
|
||||||
|
SKSE::GetModCallbackEventSource()->SendEvent(&modEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return RE::BSEventNotifyControl::kContinue;
|
||||||
|
}
|
||||||
|
|
|
@ -10,7 +10,8 @@ class EventListener :
|
||||||
public RE::BSTEventSink<RE::TESContainerChangedEvent>,
|
public RE::BSTEventSink<RE::TESContainerChangedEvent>,
|
||||||
public RE::BSTEventSink<RE::MenuOpenCloseEvent>,
|
public RE::BSTEventSink<RE::MenuOpenCloseEvent>,
|
||||||
public RE::BSTEventSink<RE::TESActivateEvent>,
|
public RE::BSTEventSink<RE::TESActivateEvent>,
|
||||||
public RE::BSTEventSink<RE::TESCombatEvent>
|
public RE::BSTEventSink<RE::TESCombatEvent>,
|
||||||
|
public RE::BSTEventSink<RE::TESHitEvent>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
~EventListener() = default;
|
~EventListener() = default;
|
||||||
|
@ -47,6 +48,11 @@ public:
|
||||||
RE::BSTEventSource<RE::TESCombatEvent>* a_eventSource)
|
RE::BSTEventSource<RE::TESCombatEvent>* a_eventSource)
|
||||||
-> RE::BSEventNotifyControl override;
|
-> RE::BSEventNotifyControl override;
|
||||||
|
|
||||||
|
auto ProcessEvent(
|
||||||
|
const RE::TESHitEvent* a_event,
|
||||||
|
RE::BSTEventSource<RE::TESHitEvent>* a_eventSource)
|
||||||
|
-> RE::BSEventNotifyControl override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EventListener() = default;
|
EventListener() = default;
|
||||||
};
|
};
|
|
@ -1,77 +0,0 @@
|
||||||
Scriptname _00E_ClosedChestAlias extends ReferenceAlias
|
|
||||||
|
|
||||||
Int Property LOCK_LEVEL_NOVICE = 1 AutoReadOnly
|
|
||||||
Int Property LOCK_LEVEL_APPRENTICE = 25 AutoReadOnly
|
|
||||||
Int Property LOCK_LEVEL_ADEPT = 50 AutoReadOnly
|
|
||||||
Int Property LOCK_LEVEL_EXPERT = 75 AutoReadOnly
|
|
||||||
Int Property LOCK_LEVEL_MASTER = 254 AutoReadOnly
|
|
||||||
|
|
||||||
Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
|
|
||||||
|
|
||||||
ObjectReference hitRef = GetReference()
|
|
||||||
|
|
||||||
If akAggressor != PlayerREF || hitRef.IsLocked() == False
|
|
||||||
Return
|
|
||||||
EndIf
|
|
||||||
|
|
||||||
Int projectileLevel = 0
|
|
||||||
|
|
||||||
If akProjectile == _00E_UnlockProjectile_Novice
|
|
||||||
projectileLevel = LOCK_LEVEL_NOVICE
|
|
||||||
ElseIf akProjectile == _00E_UnlockProjectile_Apprentice
|
|
||||||
projectileLevel = LOCK_LEVEL_APPRENTICE
|
|
||||||
ElseIf akProjectile == _00E_UnlockProjectile_Adept
|
|
||||||
projectileLevel = LOCK_LEVEL_ADEPT
|
|
||||||
ElseIf akProjectile == _00E_UnlockProjectile_Expert
|
|
||||||
projectileLevel = LOCK_LEVEL_EXPERT
|
|
||||||
ElseIf akProjectile == _00E_UnlockProjectile_Master
|
|
||||||
projectileLevel = LOCK_LEVEL_MASTER
|
|
||||||
ElseIf akSource
|
|
||||||
Formlist unlockSpells = _00E_ChestAndDoorUnlockScript_UnlockSpells
|
|
||||||
If unlockSpells.HasForm(akSource)
|
|
||||||
If akSource == unlockSpells.GetAt(0) as Explosion
|
|
||||||
projectileLevel = LOCK_LEVEL_APPRENTICE
|
|
||||||
ElseIf akSource == unlockSpells.GetAt(1) as Explosion
|
|
||||||
projectileLevel = LOCK_LEVEL_ADEPT
|
|
||||||
ElseIf akSource == unlockSpells.GetAt(2) as Explosion
|
|
||||||
projectileLevel = LOCK_LEVEL_EXPERT
|
|
||||||
ElseIf akSource == unlockSpells.GetAt(3) as Explosion
|
|
||||||
projectileLevel = LOCK_LEVEL_MASTER
|
|
||||||
EndIf
|
|
||||||
EndIf
|
|
||||||
EndIf
|
|
||||||
|
|
||||||
If projectileLevel > 0
|
|
||||||
Int lockLevel = hitRef.GetLockLevel()
|
|
||||||
If lockLevel > LOCK_LEVEL_MASTER
|
|
||||||
_00E_sDoorLocked.Show()
|
|
||||||
WPNTG06ControlStaffShootFailM.Play(hitRef)
|
|
||||||
ElseIf projectileLevel >= lockLevel
|
|
||||||
; Unlock
|
|
||||||
hitRef.Lock(False)
|
|
||||||
_00E_UILockpickingUnlockM.Play(hitRef)
|
|
||||||
_00E_Ability_Antimagic_FXSShader.Play(hitRef)
|
|
||||||
hitRef.PlaceAtMe(_00E_UnlockLockExplosion, 1)
|
|
||||||
EndIf
|
|
||||||
EndIf
|
|
||||||
|
|
||||||
EndEvent
|
|
||||||
|
|
||||||
Projectile Property _00E_UnlockProjectile_Novice Auto
|
|
||||||
Projectile Property _00E_UnlockProjectile_Apprentice Auto
|
|
||||||
Projectile Property _00E_UnlockProjectile_Adept Auto
|
|
||||||
Projectile Property _00E_UnlockProjectile_Expert Auto
|
|
||||||
Projectile Property _00E_UnlockProjectile_Master Auto
|
|
||||||
|
|
||||||
Message Property _00E_sDoorLocked Auto
|
|
||||||
|
|
||||||
Sound Property _00E_UILockpickingUnlockM Auto
|
|
||||||
Sound Property WPNTG06ControlStaffShootFailM Auto
|
|
||||||
|
|
||||||
EffectShader Property _00E_Ability_Antimagic_FXSShader Auto
|
|
||||||
Explosion Property _00E_UnlockLockExplosion Auto
|
|
||||||
|
|
||||||
FormList Property _00E_UnlockScrolls Auto
|
|
||||||
FormList Property _00E_ChestAndDoorUnlockScript_UnlockSpells Auto
|
|
||||||
|
|
||||||
Actor Property PlayerREF Auto
|
|
|
@ -1,97 +0,0 @@
|
||||||
Scriptname _00E_ScrollUnlockAlias extends ReferenceAlias Hidden
|
|
||||||
|
|
||||||
event OnPlayerLoadGame()
|
|
||||||
if UnlockScrollEquipped()
|
|
||||||
GotoState("Equipped")
|
|
||||||
endif
|
|
||||||
endevent
|
|
||||||
|
|
||||||
Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
|
|
||||||
if akBaseObject as Scroll && _00E_UnlockScrolls.HasForm(akBaseObject)
|
|
||||||
GotoState("Equipped")
|
|
||||||
endif
|
|
||||||
endEvent
|
|
||||||
|
|
||||||
bool function UnlockScrollEquipped()
|
|
||||||
Actor PlayerREF = GetReference() as Actor
|
|
||||||
if PlayerREF.IsEquipped(_00E_UnlockScrolls)
|
|
||||||
return true
|
|
||||||
endif
|
|
||||||
Form leftHand = PlayerREF.GetEquippedObject(0)
|
|
||||||
return leftHand && _00E_UnlockScrolls.HasForm(leftHand)
|
|
||||||
endfunction
|
|
||||||
|
|
||||||
Event OnUpdate()
|
|
||||||
if UnlockScrollAliases.IsStopped()
|
|
||||||
if ! UnlockScrollAliases.Start()
|
|
||||||
RegisterForSingleUpdate(0.1)
|
|
||||||
endif
|
|
||||||
elseif UnlockScrollAliases.IsStopping()
|
|
||||||
RegisterForSingleUpdate(0.01)
|
|
||||||
elseif UnlockScrollAliases.IsStarting()
|
|
||||||
RegisterForSingleUpdate(0.01)
|
|
||||||
endif
|
|
||||||
EndEvent
|
|
||||||
|
|
||||||
state Equipped
|
|
||||||
event OnPlayerLoadGame()
|
|
||||||
if ! UnlockScrollEquipped()
|
|
||||||
GotoState("")
|
|
||||||
endif
|
|
||||||
endevent
|
|
||||||
|
|
||||||
event OnBeginState()
|
|
||||||
ObjectReference actorRef = GetReference()
|
|
||||||
RegisterForAnimationEvent(actorRef, "BeginCastRight")
|
|
||||||
RegisterForAnimationEvent(actorRef, "BeginCastLeft")
|
|
||||||
endevent
|
|
||||||
|
|
||||||
event OnEndState()
|
|
||||||
ObjectReference actorRef = GetReference()
|
|
||||||
UnregisterForAnimationEvent(actorRef, "BeginCastRight")
|
|
||||||
UnregisterForAnimationEvent(actorRef, "BeginCastLeft")
|
|
||||||
endevent
|
|
||||||
|
|
||||||
Event OnUpdate()
|
|
||||||
if UnlockScrollAliases.IsStopped()
|
|
||||||
if ! UnlockScrollAliases.Start()
|
|
||||||
RegisterForSingleUpdate(0.1)
|
|
||||||
endif
|
|
||||||
elseif UnlockScrollAliases.IsStopping()
|
|
||||||
RegisterForSingleUpdate(0.01)
|
|
||||||
elseif UnlockScrollAliases.IsStarting()
|
|
||||||
RegisterForSingleUpdate(0.01)
|
|
||||||
endif
|
|
||||||
EndEvent
|
|
||||||
|
|
||||||
Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
|
|
||||||
; do nothing
|
|
||||||
endEvent
|
|
||||||
|
|
||||||
Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
|
|
||||||
if ! UnlockScrollEquipped()
|
|
||||||
GotoState("")
|
|
||||||
endif
|
|
||||||
endEvent
|
|
||||||
|
|
||||||
Event OnAnimationEvent(ObjectReference akSource, string asEventName)
|
|
||||||
ObjectReference crosshairRef = Game.GetCurrentCrosshairRef()
|
|
||||||
|
|
||||||
if crosshairRef
|
|
||||||
Form baseObject = crosshairRef.GetBaseObject()
|
|
||||||
if baseObject as Container || baseObject as Door
|
|
||||||
ScrollTarget.ForceRefTo(crosshairRef)
|
|
||||||
UnlockScrollAliases.Stop()
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
|
|
||||||
UnlockScrollAliases.Stop()
|
|
||||||
RegisterForSingleUpdate(0.01)
|
|
||||||
ScrollTarget.Clear()
|
|
||||||
endEvent
|
|
||||||
endstate
|
|
||||||
|
|
||||||
Quest Property UnlockScrollAliases Auto
|
|
||||||
FormList Property _00E_UnlockScrolls Auto
|
|
||||||
ReferenceAlias Property ScrollTarget Auto
|
|
69
source/scripts/_00E_UnlockSpellAlias.psc
Normal file
69
source/scripts/_00E_UnlockSpellAlias.psc
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
Scriptname _00E_UnlockSpellAlias extends ReferenceAlias
|
||||||
|
|
||||||
|
Int Property LOCK_LEVEL_NOVICE = 1 AutoReadOnly
|
||||||
|
Int Property LOCK_LEVEL_APPRENTICE = 25 AutoReadOnly
|
||||||
|
Int Property LOCK_LEVEL_ADEPT = 50 AutoReadOnly
|
||||||
|
Int Property LOCK_LEVEL_EXPERT = 75 AutoReadOnly
|
||||||
|
Int Property LOCK_LEVEL_MASTER = 254 AutoReadOnly
|
||||||
|
|
||||||
|
event OnInit()
|
||||||
|
RegisterForModEvent("Enderal_UnlockSpellHit", "OnUnlockSpell")
|
||||||
|
endevent
|
||||||
|
|
||||||
|
event OnPlayerLoadGame()
|
||||||
|
RegisterForModEvent("Enderal_UnlockSpellHit", "OnUnlockSpell")
|
||||||
|
endevent
|
||||||
|
|
||||||
|
Event OnUnlockSpell(string eventName, string strArg, float fSpellFormID, Form containerForm)
|
||||||
|
|
||||||
|
ObjectReference rContainer = containerForm as ObjectReference
|
||||||
|
Form rSpell = Game.GetForm(fSpellFormID as int)
|
||||||
|
Int projectileLevel = 0
|
||||||
|
|
||||||
|
If rSpell == _00E_UnlockProjectile_Novice
|
||||||
|
projectileLevel = LOCK_LEVEL_NOVICE
|
||||||
|
ElseIf rSpell == _00E_UnlockProjectile_Apprentice || rSpell == _25E_UnlockLockExplosion_Apprentice
|
||||||
|
projectileLevel = LOCK_LEVEL_APPRENTICE
|
||||||
|
ElseIf rSpell == _00E_UnlockProjectile_Adept || rSpell == _50E_UnlockLockExplosion_Adept
|
||||||
|
projectileLevel = LOCK_LEVEL_ADEPT
|
||||||
|
ElseIf rSpell == _00E_UnlockProjectile_Expert || rSpell == _75E_UnlockLockExplosion_Expert
|
||||||
|
projectileLevel = LOCK_LEVEL_EXPERT
|
||||||
|
ElseIf rSpell == _00E_UnlockProjectile_Master || rSpell == _100E_UnlockLockExplosion_Master
|
||||||
|
projectileLevel = LOCK_LEVEL_MASTER
|
||||||
|
else
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
Int lockLevel = rContainer.GetLockLevel()
|
||||||
|
|
||||||
|
If lockLevel > LOCK_LEVEL_MASTER
|
||||||
|
_00E_sDoorLocked.Show()
|
||||||
|
WPNTG06ControlStaffShootFailM.Play(rContainer)
|
||||||
|
ElseIf projectileLevel >= lockLevel
|
||||||
|
; Unlock
|
||||||
|
rContainer.Lock(False)
|
||||||
|
_00E_UILockpickingUnlockM.Play(rContainer)
|
||||||
|
_00E_Ability_Antimagic_FXSShader.Play(rContainer)
|
||||||
|
rContainer.PlaceAtMe(_00E_UnlockLockExplosion, 1)
|
||||||
|
EndIf
|
||||||
|
|
||||||
|
endevent
|
||||||
|
|
||||||
|
Projectile Property _00E_UnlockProjectile_Novice Auto
|
||||||
|
Projectile Property _00E_UnlockProjectile_Apprentice Auto
|
||||||
|
Projectile Property _00E_UnlockProjectile_Adept Auto
|
||||||
|
Projectile Property _00E_UnlockProjectile_Expert Auto
|
||||||
|
Projectile Property _00E_UnlockProjectile_Master Auto
|
||||||
|
|
||||||
|
Explosion Property _00E_UnlockLockExplosion Auto
|
||||||
|
Explosion Property _100E_UnlockLockExplosion_Master Auto
|
||||||
|
Explosion Property _25E_UnlockLockExplosion_Apprentice Auto
|
||||||
|
Explosion Property _50E_UnlockLockExplosion_Adept Auto
|
||||||
|
Explosion Property _75E_UnlockLockExplosion_Expert Auto
|
||||||
|
|
||||||
|
Message Property _00E_sDoorLocked Auto
|
||||||
|
|
||||||
|
Sound Property WPNTG06ControlStaffShootFailM Auto
|
||||||
|
Sound Property _00E_UILockpickingUnlockM Auto
|
||||||
|
|
||||||
|
EffectShader Property _00E_Ability_Antimagic_FXSShader Auto
|
Loading…
Reference in New Issue
Block a user