Jump to content

DOWNLOAD MODS

Are you looking for something shiny for your load order? We have many exclusive mods and resources you won't find anywhere else. Start your search now...

LEARN MODDING

Ready to try your hand at making your own mod creations? Visit the Enclave, the original ES/FO modding school, and learn the tricks of the trade from veteran modders...

JOIN THE ALLIANCE

Membership is free and registering unlocks image galleries, project hosting, live chat, unlimited downloads, & more...

Completely stuck on an event script


zeromaveric
 Share

Recommended Posts

needless to say, i'm a complete noob at scripting. i've managed a couple from copying/modifying others' work to get some working, but now i'm completely stuck since i can't find any evidence of this working.

 

basically, i managed a weapon enchantment akin to Notched Pickaxe in which the weapon can cast a magic effect on the weilder. somehow i got it to activate when the weapon is drawn, rather than simply equipped, which is what i wanted. now here's where i'm stuck

 

i want the magic effect to dispel when i sheathe the weapon, rather than having to open menu and dequip it for it to wear off. i've searched and found someone mentioning a combination of OnEquipped, OnUnequipped, and using IsWeaponDrawn as a method to check and activate, but i can't for the life of me find out how to get this to go through, as there are no written examples of these going together

Link to comment
Share on other sites

There are a couple ways to go about this:

  1. Without SKSE: Use a RegisterForUpate call to set up a polling loop. In the OnUpdate event check IsWeaponDrawn. If false, stop the magic effect.
  2. With SKSE: RegisterForActorAction(10) to catch the Sheath End event. In the OnActorAction event stop the magic effect.

if you use SKSE, it is more efficient as there is no polling and you don't have the do the IsWeaponDrawn test. Ideally your code would be something like:


Event OnEquipped(Actor akActor)
    Apply your magic effect
    RegisterForActorAction(7)   ;draw start    
    RegisterForActorAction(10) ;sheath end
EndEvent

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
    If actionType == 7
         apply magic effect
    Else
        remove magic effect
    EndIf
EndEvent

Event OnUnequipped(Actor akActor)
    RegisterForActorAction(7)   ;draw start    
    RegisterForActorAction(10) ;sheath end
EndEvent
BTW, this code could be directly attached to the weapon object, rather than having to go through the whole enchantment/spell/magiceffect routine.
Edited by jaxonz
Link to comment
Share on other sites

yeah, i was hoping i could apply it directly to the weapon, even though i have all the enchantment properties made for it to activate. i was hoping to not use SKSE, if possible, but if it means a simpler way of getting this to work, i'll try it out

 

also, i noticed you put in magic effect, rather than the spell. how would this script know the magnitude of the effect? i'm using a speed multiplier effect to triple how fast you can move with weapon drawn, but that variable had to be put in with my spell i created. or can i put in the spell for it to be cast, then use the remove function for the magic effect when sheathed?

 

Edit: and when i tried to complile this, CK spat out 'unkown type apply/remove'

Edited by zeromaveric
Link to comment
Share on other sites

To apply a magic effect to the player (or remove it) the command is not apply OR remove - he was just saying to do that there, he didn't not actually post fully functional code.

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
if (akActor == Game.GetPlayer() && actionType == 7
Game.GetPlayer().AddSpell(YourSpell, false) ;false means the spell will be added silently with no notification to the player
Else
Game.GetPlayer().RemoveSpell(YourSpell, false)
EndEvent

In order to tell it when to do this you will have to do an update thing but if you are using OnUpdate it contributes to save game bloat since this is ALWAYS ON even if they don't have the weapon, don't have it equipped, all sortsa things.

You may also be able to do something without any scripting.  It's actually pretty easy with items.

Make sure your spell is attached to the weapon somehow.

I used a keyword with mine - you may also want to add a specific keyword to your item.

 

Now go to your spell in the CK.

Your spell has effects listed I assume.

Double click to open an effect.

Right click and select New in the Conditions box.

The condition you want is WornHasKeyword, set the keyword, and make it == 1

Also IsWeaponOut, set the weapon, and make it == 1

See if it works.

Link to comment
Share on other sites

To apply a magic effect to the player (or remove it) the command is not apply OR remove - he was just saying to do that there, he didn't not actually post fully functional code.

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
if (akActor == Game.GetPlayer() && actionType == 7
Game.GetPlayer().AddSpell(YourSpell, false) ;false means the spell will be added silently with no notification to the player
Else
Game.GetPlayer().RemoveSpell(YourSpell, false)
EndEvent

In order to tell it when to do this you will have to do an update thing but if you are using OnUpdate it contributes to save game bloat since this is ALWAYS ON even if they don't have the weapon, don't have it equipped, all sortsa things.

You may also be able to do something without any scripting.  It's actually pretty easy with items.

Make sure your spell is attached to the weapon somehow.

I used a keyword with mine - you may also want to add a specific keyword to your item.

 

Now go to your spell in the CK.

Your spell has effects listed I assume.

Double click to open an effect.

Right click and select New in the Conditions box.

The condition you want is WornHasKeyword, set the keyword, and make it == 1

Also IsWeaponOut, set the weapon, and make it == 1

See if it works.

yeah, i've tried with using just CK and no scripts, but it would always keep the ability active when i sheathe, even if i have it set with WornHasKeyword or IsWeaponOut. only way i could get it to deactivate was to unequip altogether, but that defeats the purpose of the enchantment in the way i want it to work

 

but with this revision, now i'm getting missing RPAREN at '\\r\\n' in place of the , after Actor akActor.

 

Edit: ok, seems i used those conditions on the enchantment before, and it didn't work. put it on the spell, and it seems to sort of work. when i sheathe, it's still active until i open the spells/powers menu to confirm it's deactivated, then it goes into effect

Edited by zeromaveric
Link to comment
Share on other sites

That means it's missing a right parenthesis.  And the weapon would be enchanted but the enchant shouldn't effect the player unless the weapon is out if the IsWeaponOut flag is set.  Are you saying it still does in your game and if so, have you tried on a clean save and in a new cell.

 

Example - Boethiah's Cloak.  When worn gives the player immunity to the sun if they're a vampire (scriptlessly if not using Dawnguard or Vampire Lord).  It's not a weapon though so I haven't tested the IsWeaponDrawn flag but it should work exactly the same as all the other flags.

 

Parenthesis looks like it's actually missing from this line.

if (akActor == Game.GetPlayer() && actionType == 7

Which should then read

if akActor == Game.GetPlayer() && actionType == 7

There was a left parenthesis where it didn't belong.  I think.

Edited by Vain
Link to comment
Share on other sites

This may help you a little - 
The script you are using is an ObjectReference Script.
It is going to effect a person so you then progress to Actor Script for things you want to do here.
Then we can go to GetEquippedWeapon (you only want this to be in effect if that weapon is equipped), IsWeaponDrawn, IsWeaponOut, SheatheWeapon (SKSE Function) but I did NOT see anything for OnSheathe so you'd have to do something with IsWeaponOut/Drawn = false to have it remove something when the weapon is sheathed if the conditions on the spell effect don't work...

 

Perhaps we're using IsWeaponDrawn when we really want IsWeaponOut or vice versa - you may wish to experiment a little.

Link to comment
Share on other sites

ok, after switching things around, i got it to compile, but now it seems it's not working at all. from what you guys posted, and what i was able to gather, here's what i got

 

ScriptName SilfarionSKSEScript extends ObjectReference

Spell Property SilfarionSpeedAbEquip Auto

Event OnEquipped(Actor akActor)
    RegisterForActorAction(7)   ;draw start    
    RegisterForActorAction(10) ;sheath end
EndEvent

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
    if (akActor == Game.GetPlayer() && actionType == 7)
        Game.GetPlayer().AddSpell(SilfarionSpeedAbEquip, false) ;false means the spell will be added silently with no notification to the player
    Else
        Game.GetPlayer().RemoveSpell(SilfarionSpeedAbEquip)
    endIf
EndEvent

Event OnUnequipped(Actor akActor)
    RegisterForActorAction(7)   ;draw start    
    RegisterForActorAction(10) ;sheath end
EndEvent

Function StartChain()
    RegisterForSingleUpdate(0.1)
EndFunction

Event OnUpdate()
    Bool bKeepUpdating = True
    If bKeepUpdating
        RegisterForSingleUpdate(0.1)
    EndIf
EndEvent
Link to comment
Share on other sites

This is how I would make it work:

Scriptname SilfarionSKSEScript extends ObjectReference

Spell Property SilfarionSpeedAbEquip Auto
int ACTOR_ACTION_DRAW_START = 7
int ACTOR_ACTION_SHEATH_END = 10

Event OnEquipped(Actor akActor)
    RegisterForActorAction(ACTOR_ACTION_DRAW_START)
    RegisterForActorAction(10)
EndEvent

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
    if (akActor == Game.GetPlayer() && actionType == ACTOR_ACTION_DRAW_START)
        SilfarionSpeedAbEquip.Cast(akActor, akActor)
    ElseIf (akActor == Game.GetPlayer() && actionType == ACTOR_ACTION_SHEATH_END)
        akActor.DispelSpell(SilfarionSpeedAbEquip)
    endIf
EndEvent

Event OnUnequipped(Actor akActor)
    UnregisterForActorAction(ACTOR_ACTION_DRAW_START)
    UnregisterForActorAction(ACTOR_ACTION_SHEATH_END)
EndEvent

Comments:

  • In the OnUnequipped event you want to use UnregisterForActorAction() to stop listening for this event because if the weapon isn't equipped, there's no way it could be drawn.
  • The RegisterForSingleUpdate loop actually accomplishes nothing. Make your spell cast a permanent magiceffect and rely on sheathing to dispell it.
  • With the Spell Cast function, there is actually no check to make sure the player has and is able to cast the spell, so I removed the AddSpell and RemoveSpell calls. If you still want to add/remove the spell it seems to me that it would make more sense to do so on the OnEquipped/OnUnequipped events since the player is likely to draw and sheath the weapon many times more.
  • Added affirmative test for End Sheath event... just good programming practice

 

As Vain indicated above, it may be easier to accomplish the same thing without scripting using conditionals. I gave this a try myself and found that since Weapons can only carry Contact rather than Self targeted enchantments, it is difficult to actually accomplish this in the Creation Kit. It might  be functionally possible, but a tool like TESEdit may be needed to hook things up.

Edited by jaxonz
Link to comment
Share on other sites

still doesn't go through. seems only way i got it to even activate was adding the enchantment to the weapon through CK, leaving out any scripts >.< even then, the effect won't dissipate until i either open a menu or crouch/uncrouch to cancel out

Link to comment
Share on other sites

OK... this seemed to be fairly straightforward so I gave it a try myself.

 

What I found out is that there's an underlying bug that causes the RegisterForActorAction calls to fail with the log message:

     "no native object bound to the script object, or object is of incorrect type"

Looking this up, there seems to be a disconnect for what some term "transient objectrefereneces". (See http://www.gamesas.com/native-object-object-incorrect-type-t344408.html )

 

I had similar behavior using the native RegisterForUpdate function. The OnUpdate event never fires. However, there is no error in the script log as with RegisterForActorAction.

 

 

I commented earlier today (not on this thread) about how buggy and poorly documented Papyrus is, and how valuable it is to have a community of modders to help one avoid the various pitfalls. Here's another prime example.

 

Working on a workaround...

Link to comment
Share on other sites

OK, here's what I ended up with as a workaround. Happy I didn't have to resort to a quest for holding object references.

 

Weapon has no enchantments, just carries this script: (and forgive me for the script naming, that's just my convention to be able to find things in CK)

Scriptname JaxonzSpeedyDaggerScript extends ObjectReference  

Spell Property splSpeedyDagger Auto

Event OnEquipped(Actor akActor)
        Debug.Notification("OnEquipped")
	splSpeedyDagger.Cast(akActor,akActor)
EndEvent

Event OnUnequipped(Actor akActor)
        Debug.Notification("OnUnequipped")
	akActor.DispelSpell(splSpeedyDagger)
EndEvent

Notes:

  • All we are doing here is overcoming the limitation for weapon enchantments having to be of type Contact rather than self cast.
  • The spell is set up to be 1000 days duration, constant effect, 0 cost
  • The Debug.Notification lines are diagnostic and can be removed

 

The MagicEffect for the spell only carries this script:

Scriptname JaxonzSpeedyDaggerMGEFScript extends ActiveMagicEffect  

int ACTOR_ACTION_DRAW_START = 7
int ACTOR_ACTION_SHEATH_END = 10
float fOriginalSpeedMult
Actor akWhoHasEquipped

Event OnInit()
        Debug.Notification("OnInit JaxonzSpeedyDaggerMGEFScript")
	akWhoHasEquipped = GetTargetActor()
	fOriginalSpeedMult = akWhoHasEquipped.GetActorValue("SpeedMult")
        RegisterForActorAction(ACTOR_ACTION_DRAW_START)
        RegisterForActorAction(ACTOR_ACTION_SHEATH_END)
EndEvent

Event OnActorAction(int actionType, Actor akActor, Form source, int slot)
        Debug.Notification("OnActorAction: " + actionType)
	If akActor == akWhoHasEquipped
	    If actionType == ACTOR_ACTION_DRAW_START
                Debug.Notification("SpeedMult: " + 3.0 * fOriginalSpeedMult)
	        akActor.SetActorValue("SpeedMult", 3.0 * fOriginalSpeedMult)
	    ElseIf actionType == ACTOR_ACTION_SHEATH_END
                Debug.Notification("SpeedMult: " + fOriginalSpeedMult)
	        akActor.SetActorValue("SpeedMult", fOriginalSpeedMult)
	        ;a bug in skyrim causes reduced SpeedMult not to be honored immediately
	        ;following faked key input is a workaround to cause it to be honored
	        Input.HoldKey(Input.GetMappedKey("Sprint"))
	        Input.HoldKey(Input.GetMappedKey("Forward"))
	        Utility.Wait(0.1)
	        Input.ReleaseKey(Input.GetMappedKey("Forward"))
	        Input.ReleaseKey(Input.GetMappedKey("Sprint"))
	    EndIf
	 EndIf
EndEvent

Notes:

  • Here we are successfully using the SKSE RegisterForActorAction function to fire events when weapons are drawn and sheathed. (This is a workaround for the  "no native object bound to the script object, or object is of incorrect type" cited earlier.)
  • Since the spell is only in effect when the weapon is equipped, there's no need to double check that our weapon is equipped. However, we do check that the actor causing the weapon drawn event is the same as has the spell cast on them.
  • My code doesn't assume akActor is Game.GetPlayer(). This should allow the weapon to be used by NPCs, but I haven't tested it. It may also fail if multiple instances of the weapon exist, as I'm not 100% sure that each weapon would get its own spell script instance and the akActor internal variable may get shared.
  • The script is a bit longer than necessary, but I wanted to use good practices and not make assumptions about an actor's base movement value, control mappings, etc.
  • Note also the workaround for setting movement speed back to normal. I think this may have been the cause of what you observed before. The Skyrim engine has a bug in that a reduced SpeedMult actor value is not immediately honored. One must open a menu or swing a weapon or take some other activity before it takes effect. In this case, the code causes an extremely brief sprint. Yet another reminder that our beloved Skyrim is full of bugs.
  • Debug.Notification lines can all be removed.

 

If you still have difficulty in getting this to work, I can post the .esp and scripts to Google Docs.

Edited by jaxonz
Link to comment
Share on other sites

i may have to look at your esp after all. i'm looking at my spell effect properties, and i can't affect the duration at all. only thing that pops up for my MGEF is the magnitude and any conditions

 

also noticed that when adding the MGEF script, it didn't allow for inputting any properties. i assume that was normal?

 

Edit: ok, forgot i had no duration ticked on my magic. got it set to 1000 as you did, but only the debug OnEquipped message pops up when i equip it. the MGEF script seems to be nonexistent, assuming from the fact i can't modify properties in CK

 

Edit again: ok, tried adding in the spell through console, and it did add an effect of 1000 day duration speed multiplier. weilding/sheathing any weapon did affect my run speed to fast then normal, so i know that works. i guess it's just the action of casting/dispelling with the sword's script that isn't going through

 

Edit 3: ok, tested with the sword. unequipping the sword does dispel the effect entirely, so it's just the action of casting when i equip that isn't working

Edited by zeromaveric
Link to comment
Share on other sites

*facepalm* magic effect archetype wasn't set to script, so that's probably why it wasn't activating. totally overlooked that part in CK since i had it activating naturally beforehand and neglected to change it. plus i had the spell set to ability, rather than spell. got those changed, and it works perfectly now. thanks :D

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...