Jump to content

[LE] Working Lock and Unlock Spells


nikolaf

Recommended Posts

Hi all,

 

I'm currently in the process of making some lock and unlock spells like in the previous Elder Scrolls games.

 

I've set up the magic effects and spells for both, and have also downloaded some mods from the nexus for comparison.

There was Spells of the Third Era, but I wanted to make a targeted spell... which has proved harder than I initially thought :sad:

 

The problem lies with the script I made, It doesn't compile nicely, and I'm not sure what I'm missing. I checked the creation kit wiki, to no avail...

Here it is as of now ( missing something? and setting it to work for containers AND doors too ):

 

 

Scriptname UnlockAdeptScript Extends ActiveMagicEffect
Event OnEffectStart(Container akTarget, Actor akCaster)
if(akTarget.IsLocked())
if(akTarget.GetLockLevel() <= 50)
akTarget.lock(FALSE)
akTarget.activate(akCaster)
else
Debug.MessageBox("The lock is too strong and can't be opened...")
endif
endif
EndEvent
Link to comment
Share on other sites

You changed the parameters for the OnEffectStart event. Its one thing to use a different variable name but the object type cannot be changed. Thus it is always best to use what is shown on the CK wiki and / or in the base game script files. i.e.

Event OnEffectStart(Actor akTarget, Actor akCaster)

It is failing to compile because Papyrus has no idea what to do with akTarget declared as a Container.

 

If you do not mind your spell only working when the player's crosshair is pointing at the object and its activation prompt is available, then it should be possible using GetCurrentCrosshairRef(). NOTE - Requires SKSE.

 

 

Event OnEffectStart(Actor akTarget, Actor akCaster)
  ObjectReference myTarget = Game.GetCurrentCrosshairRef()
  If myTarget.IsLocked()
    If myTarget.GetLockLevel() <= 50
      myTarget.Lock(False)
      myTarget.Activate(akCaster)
    Else
      Debug.MessageBox("The lock is too strong and cannot be opened...")
    EndIf
  EndIf
EndEvent

Pro - can work with any targeted container or door

Con - requires SKSE

Con - limited to standard on screen prompt activation range

 

 

 

But if you want it to work at range and / or without SKSE then you'll have to apply a secondary script to the object(s) so that they may use the OnHit event to catch the incoming projectile. Something like:

 

 

ScriptName ObjectLockUnlockScript Extends ObjectReference

Projectile Property myLockProjectile Auto ;locks target
Projectile Property myUnlockProjectile Auto ;unlocks target

Event OnHit(ObjectReference akAggressor, Form akSource, Projectile akProjectile, bool abPowerAttack, bool abSneakAttack, \
  bool abBashAttack, bool abHitBlocked)
  ObjectReference myself = Self as ObjectReference
  If akProjectile == myUnlockProjectile
    If myself.IsLocked()
      If myself.GetLockLevel() <= 50
        myself.Lock(False)
        myself.Activate(akAggressor)
      Else
        Debug.Messagebox("The lock is too strong and cannot be opened...")
      EndIf
    EndIf
  ElseIf akProjectile == myLockProjectile
    If !myself.IsLocked() ;not locked
      myself.Lock(True)
    EndIf
  EndIf
EndEvent

Pro - does not require SKSE

Pro - can work at full range of projectile as designated in the spell / effect

Con - limited to only those containers / doors with the attached script

 

 

 

All that said, it may be possible to create some aliases on a quest that can be filled with nearby containers and doors that have a non-zero lock level and apply the OnHit event on the alias' script. That would allow for some greater leeway in working with containers and doors from other mods. But may still have some limitations depending upon how often the quest is restarted to re-fill the aliases with new references. And if a given area has more lockable containers and doors than there are aliases, it obviously wouldn't work for all of them and which ones work might be random depending upon how the game decides to fill the aliases.

 

Let us also leave room for additional tricks that others may know which may improve the odds of working with any lockable container or door without the inherent limitations of GetCurrentCrosshairRef.

Link to comment
Share on other sites

Thank you Ishara :smile:

 

The crosshair idea is great, but I wanted to stick with the targeting type of spell, so I will test both out in my mod.

 

If I'm going to try the second option, I'll have to add the script to every possible container and door, won't I..?

I'll first do the GetCurrentCrosshairRef one, and see if it fits nicely. I've never made a quest, except for dialogue related ones, so that might not be viable for me...

 

I also use SKSE so that is not a problem. :smile:

 

P.S. I tested out both types, and prefer the method with OnHit event.

I don't think the number of aliases will be a huge problem, I could create dozens of them, correct?

Can you please explain to me how to make a quest to work with this?

Thank you for your help this far :)

Edited by nikolaf
Link to comment
Share on other sites

If I'm going to try the second option, I'll have to add the script to every possible container and door, won't I..?

I'll first do the GetCurrentCrosshairRef one, and see if it fits nicely. I've never made a quest, except for dialogue related ones, so that might not be viable for me...

 

I also use SKSE so that is not a problem. :smile:

 

P.S. I tested out both types, and prefer the method with OnHit event.

I don't think the number of aliases will be a huge problem, I could create dozens of them, correct?

Can you please explain to me how to make a quest to work with this?

Thank you for your help this far :smile:

 

Basically what you'd do is create a quest with some arbitrary number of aliases that are to be filled with things that match certain conditions, i.e. that they are a door or a container in the loaded area (and have a lock and are locked, depending), and then attach a (the same) script to each of those aliases that listens for an OnHit event with the magic effect of your spell to lock/unlock the item. You'd then restart the quest every time you need to, which'd be done through a script on an alias applied to the player in a second quest.

 

This might sound complicated, but it's fairly straightforward once you get into making the aliases.

 

It's even possible to trigger the search-quest as the player casts the spell, through an OnSpellCast() event, but because the search process takes a little bit of time it may not be done by the time the projectile hits, especially at short range and/or with fast projectiles. Firing the quest whenever a player loads an area requires more aliases to cover all the potential targets -- dozens, for some of the larger areas, and several times that if you plan to allow the spell to lock any container -- but fixes the timing issues. Perhaps combining it with pulling the crosshair reference would also mitigate that.

Link to comment
Share on other sites

I'd like to add, that the condition also needs to filter out the other aliases, otherwise, the same door/container would fill multiple aliases. I've had that problem(though I wasn't making lock/unlock spells).

 

By default, only one alias will be filled by any given object. You need to manually tick 'allow reuse in quest' in the flags to override that, or, alternatively, use a method to force a ref into an alias.

Link to comment
Share on other sites

I'll try making the quest. But I'm going to need help with the scripts, since I have only basic knowledge ( how to implement them without too many errors :confused:)...

 

I should make a dozen or so aliases referring to containers and doors ( locked ones ), and then where would I put the scripts?

Link to comment
Share on other sites

I'll try making the quest. But I'm going to need help with the scripts, since I have only basic knowledge ( how to implement them without too many errors :confused:)...

 

I should make a dozen or so aliases referring to containers and doors ( locked ones ), and then where would I put the scripts?

 

Open up each individual alias, top right. For the container/door aliases, the easiest way to do this is to build one alias as a prototype, confirm that it fills as it should and the script works correctly for detecting hits and changing the lock status (the console command sqv, to check what is in the alias, and moveto, to go to it) and then duplicate it (CTRL-D) a bunch of times. That way you save having to fill out the same properties again and again, which is tedious and error prone.

 

The script on the player -- whichever route you take -- will be a unique one applied to an alias which is forced to be filled by the player. This should be done in a separate quest from the one that contains all the aliases for the stuff you want to work on, since that one will be regularly reset.

Edited by foamyesque
Link to comment
Share on other sites

  • 1 year later...

Hi, just in case it helps anyone. I figured out another method for opening/locking doors using a spell that doesn't use quest alias or SKSE in case anyone else is still wanting to do this. Basically i do these steps.

 

  • Have the magic effect shoot a projectile, with a custom explosion
  • Have the explosions "placed object" be a custom xmarker
  • Have a script on the base form of the custom xmarker that on Event OnLoad() enables and moves a trigger box objectreference to itself.
  • The triggerbox objectreference starts disabled in a blank interior cell and has a script (on the reference) to unlock/lock whatever enters it, then it moves back to the blank interior cell and disables itself
  • The triggerbox reference has a custom collision layer in the primitive tab that allows it to detect statics or anything else.

That's the overview of how it works, and you can add more to the trigger box script such as a condition that its akActionRef must be a certain type of form. What i did was make a form list and add all the the doors, and one for all the containers, then if the akActionRef was in the formlist the triggerbox would also place visual effects, and a debug.notifcation either "door unlocked" or "container unlocked".

 

This method should also work to unlock doors introduced from mods, but if you use a form list for the visual effects they will only work on the doors/ containers in the list. The actual code to unlock/lock, as well as get lock level can run on any objects, and will only actually do anything on a door/container so it doesn't need a condition to run on an akActionRef.

 

On another note you can also use a trigger box in this way to have spells that act on items and statics aswell,

Edited by PrincessMely
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...