Jump to content

Issue with a perks and scripts


XBlayde

Recommended Posts

h'okay, so I've been beating my head at this for a while, let me see what the pros have to say about this. Hopefully I am providing enough information, let me know what more I can provide. I am not great at programming or script writing, just various rudimentary things and lots of google searching.

 

So the idea is that there's a sword (Durandal) stabbed into a coffin, and you can only pull it if you're wearing the proper gauntlets (Durandal's Handlers). If you're not wearing the gauntlets, you can't take the sword and it burns you for 30 damage. If you are equipped with the sword and take the gauntlets off, you drop the sword and are burned for 30 damage. If you've dropped the sword and try to pick up the sword without the gauntlets, you fail to pick it up and burn for 30 fire damage.

 

So first, let me describe my current (and faulty) set up. I'll list the issues at the bottom.

 

I'm having all kinds of mixed results. The setup thatI have is that I made a perk (something very simple, enough to just be a tag that the scripts can use), wrote a short script so that the gauntlets apply the perk (DPGlovesPerk) when equipped on and remove the perk when they're unequipped; when you remove them, it also checks to see if you're equipped with Durandal, and if you are not wearing them you are dealt 30 damage and drop the sword. For reference, _DPDurandal is the ID of the sword, DPGlovesPerk is the name of the perk.

 

Scriptname DurandalPerk extends ObjectReference

{Adds perk necessary to wield Durandal}
Perk Property DPGlovesPerk auto
Weapon Property _DPDurandal Auto
Event OnEquipped(Actor akActor)
akActor.AddPerk(DPGlovesPerk)
debug.notification("A holy fire fills your arms") ; checking to see if the script fires
EndEvent
Event OnUnEquipped(Actor akActor)
akActor.RemovePerk(DPGlovesPerk)
debug.notification("Your arms become numb for a moment, then feel normal again.") ; checking to see if the script fires
If (Game.GetPlayer().GetEquippedWeapon() == _DPDurandal)
Game.GetPlayer().DropObject(_DPDurandal, 1)
Game.GetPlayer().DamageActorValue("Health", 30.0)
Debug.Notification("Durandal heats to a glowing red, causing you to drop it.")
endif
EndEvent

 

Also put a script on the sword to look for the perk as well to just cover all the bases:

 

Scriptname _DPDurandalStopScript extends ObjectReference

{Prevents player from picking up Durandal without gauntlets}
Weapon Property _DPDurandal Auto
Perk Property DPGlovesPerk Auto
Event OnActivate(ObjectReference akActor)
if (Game.GetPlayer().HasPerk(DPGlovesPerk))
BlockActivation(false) ; mostly fluff to help me logic it out in my brain correctly
else
BlockActivation()
Game.GetPlayer().DamageActorValue("Health", 30.0)
Debug.Notification("Durandal burns you as you try to pick it up.")
endIf
EndEvent
Event OnEquipped(Actor akActor)
Utility.Wait(0.5) ; to make sure durandal is equipped
If (Game.GetPlayer().HasPerk(DPGlovesPerk))
BlockActivation(false) ; mostly fluff to help me logic it out in my brain correctly
else
Game.GetPlayer().DropObject(_DPDurandal, 1)
Game.GetPlayer().DamageActorValue("Health", 30.0)
Debug.Notification("Durandal heats to a glowing red, causing you to drop it.")
EndIf
EndEvent

 

And then lastly, at first I had the sword out in the world stuck in the coffin as a lootable item with a script in the reference window, but that wasn't working at all, so I made an activator with the same model and attached a script to that via the Reference window. This seems to be working better, but there's an issue with that too. Here's the script for that one:

 

 

Scriptname _DPDurandalObj extends ObjectReference

{Stop activation if player tries to pick up without Durandal's Handlers}
Weapon Property _DPDurandal Auto
Perk Property DPGlovesPerk Auto
Event OnActivate(ObjectReference akActor)
if (Game.GetPlayer().HasPerk(DPGlovesPerk))
Game.GetPlayer().AddItem(_DPDurandal, 1, false)
Debug.Messagebox("Your to quest to purify the hands of Ottomeus allow you the chance to redeem his legacy. Take his blade and armor and strike back at the darkness!")
Disable() ; to make the activator sword disappear
else
BlockActivation()
Game.GetPlayer().DamageActorValue("Health", 30.0)
Debug.Notification("Durandal burns you as you try to pick it up.")
endIf
EndEvent

 

Later on, I'll figure out how to script it to unlock the coffin its stuck into for additional loot when you take the sword (was thinking it will be a lock that requires a key and just unlock it in the activator script somehow)

 

Issues I'm having:

 

-The biggest one: its as if I don't have the DPGlovesPerk at all. The activator always throws the Else function and burns me, with or without the gloves equipped. I haven't even been able to test if it generates the item in my inventory correctly and removes the activator object.

-Having the gloves equipped doesn't prevent me from being burned from picking it up, and equipping the sword with the gloves on still causes me to drop the sword. This is occurred when I only had the script on the gloves and not on the sword

-When the sword is on the ground as a lootable item, I am able to pick up the sword without the gloves. It still burns me, as expected, but the idea is that I shouldn't be able to pick it up without the gloves on.

 

Any assistance would be great, and I would be happy to provide more information

Edited by XBlayde
Link to comment
Share on other sites

create a spell as cloak effect, that spell has a magicEffect (anything what you like) but attached a special keyword, use this inside the scripts as follow

 

xb_DurandalGlovesScript

 

Scriptname xb_DurandalGlovesScript extends ObjectReference  
{Prevents player from picking up Durandal without gauntlets}
; https://forums.nexusmods.com/index.php?/topic/8218198-issue-with-a-perks-and-scripts/

; Description: "a sword (Durandal) stabbed into a coffin, and you can only pull it
; if you're wearing the proper gauntlets (Durandal's Handlers)."

  Weapon PROPERTY _DPSword auto            ; Durandel

  Spell PROPERTY _DPCloakSpell auto        ; a cloak effect as long as an actor has special gloves equipped
  ; a magicEffect within the spell should have a "special keyword"


; https://www.creationkit.com/index.php?title=Cast_-_Spell
; https://www.creationkit.com/index.php?title=GetEquippedWeapon_-_Actor

; -- EVENTs -- 3

EVENT OnInit()
;===========
    Debug.Trace(self+" OnInit() - Durandal gloves..")
ENDEVENT


EVENT OnEquipped(Actor akActor)
;===============
    objectReference oRef = akActor as ObjectReference
    _DPCloakSpell.cast(oRef, oRef)        ; cast a spell to get the keyword for weapon script
ENDEVENT


EVENT OnUnEquipped(Actor akActor)
;=================
    akActor.DispelSpell(_DPCloakSpell)

; If you are equipped with the sword and take the gauntlets off,
; you drop the sword and are burned for 60 damage.

IF (akActor.GetEquippedWeapon(False) == _DPSword) || (akActor.GetEquippedWeapon(TRUE) == _DPSword)
    Debug.Notification("Durandal heats to a glowing red, causing you to drop it.")
    akActor.DropObject(_DPSword, 1)
    akActor.DamageActorValue("Health", 60.0)
ENDIF

 

 

 

xb_DurandalSwordScript

 

Scriptname xb_DurandalSwordScript extends ObjectReference  
{Prevents player from picking up Durandal without gauntlets}
; https://forums.nexusmods.com/index.php?/topic/8218198-issue-with-a-perks-and-scripts/

; Description: "a sword (Durandal) stabbed into a coffin, and you can only pull it"
; if you are wearing the proper gauntlets (Durandals Handler).

  Weapon PROPERTY _DPSword auto            ; Durandel

  Keyword PROPERTY _DPDurandel auto        ; the special keyword from magic effect we are looking for


; -- EVENTs -- 5

EVENT OnInit()
;=============
    Debug.Trace(self+" OnInit() - Durandal sword..")
ENDEVENT


EVENT OnActivate(ObjectReference akActionRef)
;===============
IF (akActionRef as Actor)
ELSE
    RETURN    ; - STOP -    sword was touched by object, not an actor
ENDIF
;---------------------
    actor aRef = akActionRef as Actor

IF aRef.HasMagicEffectWithKeyword(_DPDurandel)
    RETURN    ; - STOP - special gloves are equipped
ENDIF
;---------------------
; If not wearing the gauntlets, you cannot take and sword burns you for 30 damage.

    IF (aRef == Game.GetPlayer())
        Debug.Notification("Durandal burns you as you try to pick it up.")
        UnRegisterForUpdate()
        RegisterForSingleUpdate(2.0)
    ENDIF
    aRef.DamageActorValue("Health", 30.0)
ENDEVENT


EVENT OnUpdate()
;=============
    actor aRef = Game.GetPlayer()
    IF aRef.HasMagicEffectWithKeyword(_DPDurandel)
        ; gauntlets equipped
    ELSEIF (aRef.GetItemCount(_DPSword) > 0)
        aRef.DamageActorValue("Health", 1.0)     ; player will be damaged by one every other second
        RegisterForSingleUpdate(2.0)
    ENDIF
ENDEVENT


EVENT OnContainerChanged(ObjectReference akNewContainer, ObjectReference akOldContainer)
;=======================
    actor aRef = akNewContainer as Actor

IF (!aRef) || aRef.HasMagicEffectWithKeyword(_DPDurandel)
    RETURN    ; - STOP -
ENDIF
;---------------------
; If you have dropped the sword and try to pick up the sword without the gauntlets,
; you fail to pick it up and burn for 30 fire damage.

    IF (aRef == Game.GetPlayer())
        Debug.Notification("Durandal heats to a glowing red, causing you to drop it.")
    ENDIF
    aRef.DropObject(_DPSword, 1)
    aRef.DamageActorValue("Health", 60.0)
ENDEVENT

 
EVENT OnEquipped(Actor akActor)
;===============
; "If sword is equipped through the console or papyrus calls, this event will not fire."

IF akActor.HasMagicEffectWithKeyword(_DPDurandel)
    RETURN    ; - STOP - special gloves are equipped
ENDIF
;---------------------
; If you try to equip the sword and doe not have the gauntlets equipped
; you drop the sword and are burned for 30 damage.

    IF (akActor == Game.GetPlayer())
        Debug.Notification("Durandal heats to a glowing red, causing you to drop it.")
    ENDIF
    akActor.DropObject(_DPSword, 1)
    akActor.DamageActorValue("Health", 60.0)
ENDEVENT

 

 

Edited by ReDragon2013
Link to comment
Share on other sites

Okay, so I replaced the script I made on the sword with the one you made for the sword (xb_DurandalSwordScript). When I go into the game, my character does not have the gauntlets, and I am able to pick up the sword. When I pick up the sword from the ground, I take damage and get both notifications ("Durandal burns you as you try to pick it up." and "Durandal heats to a glowing red, causing you to drop it."). I don't ever drop the weapon unless I do it manually. I can equip it successfully from my inventory without the gloves, but I still take damage and get the "Durandal heats to a glowing red, causing you to drop it." notification.

 

I made the spell and the magic effect with the keyword like you said, and added the gloves script to the gauntlets. While wearing the gauntlets, I still take damage and get the notifications just the same. Unequipping the gauntlets doesn't force me to drop the sword while wielding the sword in my hands.

 

I made sure papyrus logging was active and dug around the log files and below is what I dug up. It seems like my keyword is not working? I set up a magic effect and made sure _DPDurandal is attached to it, then I made a cloak effect spell that used the magic effect, called it _DPCloakSpell since that's what's called for in your script.

 

[ (00000014)].Actor.HasMagicEffectWithKeyword() - "<native>" Line ?

[item 34 in container (00000014)].xb_DurandalSwordScript.OnActivate() - "xb_DurandalSwordScript.psc" Line 30
[12/09/2019 - 10:04:25PM] error: HasMagicEffectWithKeyword called with invalid Keyword
stack:
[ (00000014)].Actor.HasMagicEffectWithKeyword() - "<native>" Line ?
[item 34 in container (00000014)].xb_DurandalSwordScript.OnContainerChanged() - "xb_DurandalSwordScript.psc" Line 61
[12/09/2019 - 10:04:25PM] error: Cannot drop a None item
stack:
[ (00000014)].Actor.DropObject() - "<native>" Line ?
[item 34 in container (00000014)].xb_DurandalSwordScript.OnContainerChanged() - "xb_DurandalSwordScript.psc" Line 71
[12/09/2019 - 10:04:28PM] error: HasMagicEffectWithKeyword called with invalid Keyword
stack:
[ (00000014)].Actor.HasMagicEffectWithKeyword() - "<native>" Line ?
[item 34 in container (00000014)].xb_DurandalSwordScript.OnEquipped() - "xb_DurandalSwordScript.psc" Line 80
[12/09/2019 - 10:04:28PM] error: Cannot drop a None item
stack:
[ (00000014)].Actor.DropObject() - "<native>" Line ?
[item 34 in container (00000014)].xb_DurandalSwordScript.OnEquipped() - "xb_DurandalSwordScript.psc" Line 90
[12/09/2019 - 10:04:30PM] error: Object reference has no 3D
stack:
[ (0001E68C)].Sound.Play() - "<native>" Line ?
[ (00029BFC)].fxDustDropRandomSCRIPT.OnLoad() - "<savegame>" Line ?
[12/09/2019 - 10:04:34PM] error: HasMagicEffectWithKeyword called with invalid Keyword
stack:
[ (00000014)].Actor.HasMagicEffectWithKeyword() - "<native>" Line ?
[item 34 in container (00000014)].xb_DurandalSwordScript.OnEquipped() - "xb_DurandalSwordScript.psc" Line 80
[12/09/2019 - 10:04:34PM] error: Cannot drop a None item
stack:
[ (00000014)].Actor.DropObject() - "<native>" Line ?
[item 34 in container (00000014)].xb_DurandalSwordScript.OnEquipped() - "xb_DurandalSwordScript.psc" Line 90
[12/09/2019 - 10:04:38PM] error: Object reference has no 3D
stack:
[item 32 in container (00000014)].xb_DurandalGlovesScript.OnEquipped() - "xb_DurandalGlovesScript.psc" Line 28
[12/09/2019 - 10:05:02PM] error: HasMagicEffectWithKeyword called with invalid Keyword
stack:
[ (00000014)].Actor.HasMagicEffectWithKeyword() - "<native>" Line ?
Link to comment
Share on other sites

[ (00000014)].Actor <-- that is the player, all fine

 

[item 34 in container (00000014)].xb_DurandalSwordScript <-- that is not so good, if an object (that has an script attached) is dropped to into the world and another script event try to catch the reference of this object such mistakes may happen, the objectReference is broken every time except the event OnItemRemoved().. that is one of the various script engine bugs

 

step (1)

xb_DurandalSwordScript

EVENT OnInit()
;=============
   Debug.Trace(self+" OnInit() - Durandal sword.. baseObject = " +self.GetBaseObject()+ " == " +_DPSword as Form)
   Debug.Trace(self+" OnInit() - Durandal sword.. keyword = " +_DPDurandel)
ENDEVENT

xb_DurandalGlovesScript

EVENT OnInit()
;=============
   Debug.Trace(self+" OnInit() - Durandal gloves.. baseObject = " +self.GetBaseObject()+ ", weapon = " +_DPSword)
   Debug.Trace(self+" OnInit() - Durandal sword.. spell = " +_DPCloakSpell)
ENDEVENT

to make sure your properties are well assigned.

 

step (2) there is an issue with gloves script

 

if "akActor" drops the sword, inside the sword script next events will be triggered OnContainerChanged() and OnUnEquipped(),

no idea in which order they are running. If you now try to drop a droped object (the sword) this could lead to circle dependencies.

 

Use Debug.Trace(self+" describe the event ") in front of each event to recognize/discover the issue.

 

--- off topic

[12/09/2019 - 10:04:30PM] error: Object reference has no 3D
stack:
[ (0001E68C)].Sound.Play() - "<native>" Line ?
[ (00029BFC)].fxDustDropRandomSCRIPT.OnLoad() - "<savegame>" Line ?
---
I made a better script version of fxDustDropRandomSCRIPT to clean out your savegame stack. You should give it a chance!
Edited by ReDragon2013
Link to comment
Share on other sites

Hmm, okay, I think I follow. Does it matter where I put those events in the scripts? I'll give those a shot and get back to you on the results of the log from those debug traces.

 

As for the off-topic portion, sure, I'll give it a shot. Where can I find that script?

Link to comment
Share on other sites

  • Recently Browsing   0 members

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