Jump to content

[LE] Disallow Item Unequip Script Help


Recommended Posts

I am having a spot of trouble with a papyrus script and hope to get some help with it. The premise is simple. If the player, or another actor is in the PlayerMarriedFaction, and they have the Bond of Matrimony equipped, it cannot be unequipped. Or rather the ring would be re-equipped if something unequipped it.

 

I have created a simple script, which I hoped to build on, and attached it to the Bond of Matrimony. It checks for the married faction membership and the debug messages work as intended for both the player and other actors.

Scriptname ChainOfMatrimony extends ObjectReference  
{Marriage check handler}

Faction Property PlayerMarriedFaction Auto

Event OnUnequipped(Actor akActor)
	if(akActor.GetFactionRank(PlayerMarriedFaction) >=0)
		Debug.MessageBox("Actor is in PlayerMarriedFaction")
	elseIf(akActor.GetFactionRank(PlayerMarriedFaction) <0)
		Debug.MessageBox("Actor is NOT in PlayerMarriedFaction")
	endif
endEvent

In the the first if block, when true - I'd like to call the following function, or one like it:

Function MakeImpossibleToRemove(Form CurrentObject)
	Self.GetActorReference().UnequipItem(CurrentObject,false,false)
	Utility.Wait(0.1)
	Self.GetActorReference().EquipItem(CurrentObject,true,false)
EndFunction

Though I'm not quite sure how to piece it all together. The function above was found in another forum post regarding making something impossible to remove, and that method called for a quest and script attached to the player alias. Which would work for the player but not for all actors.

 

It would be preferable in general to run a quest and attach this script to it, and reference the ring as a property like in this complete script. But how to make that work for all actors (not just the player) is something am also having difficulty with:

Armor Property YourArmorItem Auto
{Fill this with the ARMOR object you wish to remain equipped}

Weapon Property YourWeaponItem Auto
{Fill this with the WEAPON object you wish to remain equipped}

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
	If akBaseObject as Armor == YourArmorItem
		MakeImpossibleToRemove(akBaseObject)
	ElseIf akBaseObject as Weapon == YourWeaponItem
		MakeImpossibleToRemove(akBaseObject)
	EndIf
EndEvent

Function MakeImpossibleToRemove(Form CurrentObject)
	Self.GetActorReference().UnequipItem(CurrentObject,false,false)
	Utility.Wait(0.1)
	Self.GetActorReference().EquipItem(CurrentObject,true,false)
EndFunction

I am a bit new to scripting in Papyrus and hoping for spot of help from someone more experienced than I.

 

Thanks!

Link to comment
Share on other sites

I'm thinking that you could put an enchantment on the ring, and that enchantment could contain a script that detects whether or not a actor has the ring equipped.

For Example:

Armor Property Ring Auto

OnObjectEquipped(Form BaseObject, ObjectReference Reference)
   If BaseObject == Ring
      RegisterForSingleUpdate(1.0) <-- Signals an update
   endIf
endEvent

Event OnUpdate()
   If ((Put Actor There).IsEquipped(Ring)) == False <-- Unsure if this works
      (Put Actor There).EquipItem(Ring, False, False) <-- https://www.creationkit.com/index.php?title=EquipItem_-_Actor
   endIf

   RegisterForSingleUpdate(1.0)

endEvent

I'm also new to papyrus, so this is all I got.

Edited by PhilTheGamer1111
Link to comment
Share on other sites

That's not a bad idea, and I had run across something similar in my research. I think ultimately, I would like to avoid altering the ring - so I would eventually look to migrate this to a quest with alias reference against the player and actors wearing the ring. This would provide the most compatibility as it wouldn't conflict with other mods.

 

I've been working with just the ring itself for now, in an effort to get the script to work properly. I'm banking on if I can get it work with the ring itself, then I can move it to a ref alias.

Link to comment
Share on other sites

As an update, this works on the player only, when attached the ring. Consequently, it also equips the ring on the player when an npc unequips the ring, due to the function using get.player(). Progress!

Scriptname ChainOfMatrimony extends ObjectReference  
{Marriage check handler}

Faction Property PlayerMarriedFaction Auto
Armor Property BondOfMatrimony  Auto

Event OnUnequipped(Actor akActor)
	if(akActor.GetFactionRank(PlayerMarriedFaction) >=0)
		Debug.MessageBox("Actor is in PlayerMarriedFaction")
		MakeImpossibleToRemove(BondOfMatrimony)
	elseIf(akActor.GetFactionRank(PlayerMarriedFaction) <0)
		Debug.MessageBox("Actor is NOT in PlayerMarriedFaction")
	endif
endEvent

Function MakeImpossibleToRemove(Form BondOfMatrimony)
	Game.Getplayer().UnequipItem(BondOfMatrimony,false,false)
	Utility.Wait(0.1)
	Game.GetPlayer().EquipItem(BondOfMatrimony,true,false)
EndFunction



Link to comment
Share on other sites

I moved the script to a quest alias, and it's working for both the player and a test with Aela the Huntress. For anyone reading up on this, the working script is below.

 

It will detect that the actor is unequipping the Bond of Marriage Ring and in they in PlayerMarriedFaction at rank >0 (need to update this to 2) - it will re-equip the ring. It works with console unequipall command as well. This still has debug messages in it, but it's working. I plan to use some of them for the final mod version, but only for the player, if they are the actor unequipping.

 

One final question: I have a list of the marriable actors from the wiki... I can add all these (about 40 actors) as Aliases to the quest, but would be easier to do it another way? Like with a form list or some other way to group them all to a single alias?

 

Thanks to IsharaMeradan - I found a lot of good information posted in other threads dealing with various parts of what I was trying to do. :wink:

Scriptname ChainsOfMatrimonyRef extends ReferenceAlias

Armor Property BondOfMatrimony Auto
{Fill this with the Bond of Matrimony}

Faction Property PlayerMarriedFaction  Auto
{Fill this with the PlayerMarriedFaction}

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
If (akBaseObject as Armor == BondOfMatrimony)
  Debug.MessageBox("Bond of Matrimony was equipped")
EndIf
EndEvent

Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
If (akBaseObject as Armor == BondOfMatrimony)
Debug.MessageBox("Bond of Matrimony was unequipped")
  If(Self.GetActorReference().GetFactionRank(PlayerMarriedFaction) >=0)
   Debug.MessageBox("Actor is in PlayeMarriedFaction")
  PutItemBackOnActor(akBaseObject)
  EndIf
EndIf
EndEvent

Function PutItemBackOnActor(Form CurrentObject)
Self.GetActorReference().UnequipItem(CurrentObject,false,true)
Utility.Wait(0.1)
Self.GetActorReference().EquipItem(CurrentObject,false,true)
EndFunction
Link to comment
Share on other sites

Oh, hey, a name mention... Guess I better sound like I know something. :tongue:

 

Reading through I was thinking that you probably should go with the quest approach and then I saw that that is what you have ended up with.

 

The question is this: While you have 40+ NPCs who can be married, how many can actually be married at one time? If only one, then perhaps you could force fill the quest alias as needed rather than pointing to each one individually. It would have the benefit of possibly including mod added or mod tweaked NPCs that can be married. If you are wanting to allow for a multiple spouse situation, then you may want to go ahead and point to each one individually and have X more empty ones to be force filled as needed by mod added / tweaked NPCs.

 

Just a thought, maybe not the best solution.

 

**********

Coding thoughts:

You are using Self.GetActorReference() a good bit. Why not store that in a local variable and update it each time its ran? Better to call an off script function once rather than multiple times if you can help it. Using your code above...

 

 

criptname ChainsOfMatrimonyRef extends ReferenceAlias

Armor Property BondOfMatrimony Auto
{Fill this with the Bond of Matrimony}

Faction Property PlayerMarriedFaction  Auto
{Fill this with the PlayerMarriedFaction}

Actor MyActor

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
	If (akBaseObject as Armor == BondOfMatrimony)
 		Debug.MessageBox("Bond of Matrimony was equipped")
	EndIf
EndEvent

Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
	If (akBaseObject as Armor == BondOfMatrimony)
		MyActor = Self.GetReference() as Actor
		Debug.MessageBox("Bond of Matrimony was unequipped")
 		If(MyActor.GetFactionRank(PlayerMarriedFaction) >=0)
 			Debug.MessageBox("Actor is in PlayeMarriedFaction")
			PutItemBackOnActor(akBaseObject,MyActor)
 		EndIf
	EndIf
EndEvent

Function PutItemBackOnActor(Form CurrentObject,Actor TheActor)
	TheActor.UnequipItem(CurrentObject,false,true)
	Utility.Wait(0.1)
	TheActor.EquipItem(CurrentObject,false,true)
EndFunction

also note that I changed Self.GetActorReference() to Self.GetReference() as Actor. They both yield the same thing, the latter is faster as the former actually calls upon the latter before returning the result. Might as well skip the middle man, right?

 

 

Link to comment
Share on other sites

Thanks a lot! Your suggestion about filling the alias is a great idea, I hadn't thought of. I don't think the vanilla game allows for polygamy and it wasn't something I anticipated supporting. In my testing, when having a number of NPCs in the test cell, all meeting the proper marriage requirements - after initiating the conversation and accepting the proposal with any of them, the others stop asking about it - so I think that may be a much better way to go, in fact.

 

My only question with that (still new to scripting) is if I fill that alias during OnObjectEquipped - does it persist across gaming sessions? i.e. is something something that does in fact get stored in the player's save? I suppose I could just not care about the OnObjectEquippied event though, as we only really care about the marriage faction during OnObjectUnequipped. The game itself handles adding/removing actors to the married faction. They are added a the wedding ceremony and removed on break-up/death.

 

I have altered the script just a touch to add handling of the death case - as we don't want to re-equip the ring on a dead actor.

 

I'll see what I can do with your suggestions. You've helped me out a great deal actually, whether you knew it or not - through your other posts on similar topics. Thanks again!

Link to comment
Share on other sites

If you force fill an alias on a quest, that assignment should persist across game sessions for as long as that quest is active.

 

You cannot fill the alias within the OnObjectEquipped event. This script is the one that will be running on the alias being filled. You'd need to obtain the actor via another means and fill the alias from there. I'm not sure what process you'll need. Perhaps from a dialog entry? Or possibly an alias for the ring itself and use the OnEquipped event there to obtain the one now wearing the ring.

 

I could see the following being useful:

 

 

 

Script for ring alias, unequips and removes the ring if actor is dead. If the actor is alive, force them into the alias of your quest.

ReferenceAlias Property MyQuestAliasRef Auto

Event OnEquipped(Actor akActor)
  ObjectReference Ring = Self.GetReference()
  If akActor  ;valid actor
    If akActor.IsDead() ;dead actor
      akActor.UnEquipItem(Ring)
      akActor.RemoveItem(Ring,1)
    Else
      MyQuestAliasRef.ForceRefTo(akActor)
    EndIf
  EndIf
EndEvent

 

 

Link to comment
Share on other sites

  • Recently Browsing   0 members

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