Scripted Spellcasting with Papyrus

Post » Mon Aug 10, 2015 9:49 am

I'm working on a script to drag paralyzed actors in a way that resembles the vanilla mechanic for dragging dead ones. I'm using a spell with the Grip Actor effect archetype. I want to trigger the spell when the player holds the Activate button and release it when the button is released through a script attached to the actor that monitors player key presses using Spell.Cast() and the SKSE functions RegisterForKey(), OnKeyDown(), IsKeyPressed(), and OnKeyUp(). The script adds the spell to the player and detects button presses fine, but I'm running into problems with the casting mechanic. At the moment, when I press activate on an unconscious actor, the spell activates instantaneously then seemingly deactivates, which usually throws the actor anywhere from a few dozen to a few hundred feet away. I have a hunch this is because Grip Actor is a concentration spell and normally the cast button needs to be held down to maintain it, but the OnKeyDown event only triggers once discretely at the start of the button press. I've tried to circumvent this using the HoldKey() function to keep Activate held, but it seems this doesn't trigger the OnKeyDown event fast enough for the engine and actors are still thrown. Is there some kind of polling loop I can set up where I can make the player cast a continuous concentration spell until the scripted key is released? Has anyone else accomplished something like this, or found a better way to fudge the drag mechanic? I've tried everything from force-ragdolling the bodies to temporarily killing the actors but this seems to be the only near-feasible solution. Thanks!

User avatar
Ann Church
 
Posts: 3450
Joined: Sat Jul 29, 2006 7:41 pm

Post » Mon Aug 10, 2015 8:14 am

Post Code :user:

User avatar
Vincent Joe
 
Posts: 3370
Joined: Wed Sep 26, 2007 1:13 pm

Post » Sun Aug 09, 2015 9:16 pm

Here's what I'm working with thus far, I couldn't figure out how to use IsKeyPressed without it throwing errors, so I attached a boolean to KeyUp and KeyDown. I've tried firing the spell on a perpetual zero-length Update loop, but it seems like the script doesn't run fast enough for that to register as the spell being held down. I'm at a loss! Any ideas?

Scriptname aaaKnockoutUnconsciousEffectScript extends activemagiceffect
Actor property playerRef auto
Actor actorRef = None
Spell property aaaKnockoutUnconsciousSpell auto
Spell property aaaKnockoutDragSpell auto
MagicEffect property aaaKnockoutUnconsciousEffect Auto
int ActivateKey
bool IsDragging
Event OnInit()
UnregisterForAllKeys()
ActivateKey = Input.GetMappedKey("Activate")
RegisterForKey(ActivateKey)
EndEvent
Event OnEffectStart(Actor akTarget, Actor akCaster)
actorRef = akTarget
Debug.Notification("KO Script: Target KO'd")
actorRef.ModActorValue("Paralysis", 1)
actorRef.PushActorAway(actorRef, 0.001)
actorRef.SetUnconscious(true)
actorRef.StopCombat()
EndEvent
Event OnActivate(ObjectReference akActionRef)
actorRef.BlockActivation()
EndEvent
Event OnKeyDown(int keyCode)
Debug.Notification("KO Script: Activate Key Down")
RegisterForSingleUpdate(0)
IsDragging = 1
EndEvent
Event OnKeyUp(Int KeyCode, Float HoldTime)
Debug.Notification("KO Script: Activate Key Up")
UnregisterForUpdate()
IsDragging = 0
EndEvent
Event OnUpdate()
If(IsDragging == 1)
aaaKnockoutDragSpell.cast(playerRef, actorRef)
RegisterForSingleUpdate(0)
EndIf
EndEvent
Event OnEffectFinish(Actor akTarget, Actor akCaster)
Debug.Notification("KO Script: Actor Revived")
actorRef.ForceActorValue("Paralysis", 0)
actorRef.SetUnconscious(false)
actorRef.QueueNiNodeUpdate()
actorRef.RemoveSpell(aaaKnockoutUnconsciousSpell)
actorRef.BlockActivation(false)
EndEvent

User avatar
Curveballs On Phoenix
 
Posts: 3365
Joined: Sun Jul 01, 2007 4:43 am


Return to V - Skyrim