Jump to content

Script Problem IsWeaponDrawn


shavkacagarikia

Recommended Posts

When you have an object that you want to have run code when the player equips it, you have two options.

 

1. OnEquipped event on the object itself

 

2. OnObjectEquipped event with a condition for the object

 

The following will yield the same result provided that the object assigned the script in the first example is the object stored in the MyObject variable of the second example.

Event OnEquipped(Actor akActor)
  If akActor == Game.GetPlayer()
    Debug.Notifcation("I just got equipped")
  EndIf
EndEvent
Event OnObjectedEquipped(Form akBaseObject, ObjectReference akReference)
  If akBaseObject == MyObject
    Debug.Notification("I just got equipped")
  EndIf
EndEvent

I takes a little bit of thought, but most code that you'd want to run on the object itself can be run from an actor or reference alias script. Something as simple as the example should be left on the object. But something more complicated which requires running an update to check for the change in status needs to run from a more stable location. Since an object inside of a container is limited in what it can run, it should be considered "less stable" as not all of its code could run as expected or desired.

 

For the OPs case, they want a specific item to be equipped whenever the player draws their weapon but only when another specific item is equipped.

Here is how I would make that happen.

 

Please note this is not tested for compilation or function.

 

 

Player alias script. It could be on a quest existing in the mod already, or a totally new quest. So long as the quest is able to be active for the entire time that the behavior is desired.

ScriptName SomePlayerAliasScript Extends ReferenceAlias

Armor Property ObjectA Auto ;Object to be equipped before anything can be done
Armor Property ObjectB Auto ;Object to be equipped when weapon is drawn
Float Property WaitTime = 5.0 Auto ;Adjustable time to wait for the single update to take place - allows to modify value in CK without need to recompile
Actor PlayerRef
Bool DrawnState = false

Event OnInit()
  PlayerRef == Game.GetPlayer()
EndEvent

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
  If akBaseObject == ObjectA
    RegisterForSingleUpdate(WaitTime)
  EndIf
EndEvent

Event OnUpdate()
  If PlayerRef.IsWeaponDrawn() && DrawnState == false
    PlayerRef.EquipItem(ObjectB,true) ;use of true will prevent player from manually removing object.
    DrawnState = true
  ElseIf !PlayerRef.IsWeaponDrawn() && DrawnState == true
    PlayerRef.UnequipItem(ObjectB,true) ;remove item if player puts weapon up.
    DrawnState = false
  EndIf
  RegisterForSingleUpdate(WaitTime)
EndEvent

Event OnObjectUnequipped(Form akBaseObject, ObjectReference akReference)
  If akBaseObject == ObjectA
    PlayerRef.UnequipItem(ObjectB,true) ;remove second object whenever first is removed - use of true prevents player from manually equipping object
    UnregisterForUpdate() ;nine times out of ten not needed.  in fact not needed unless you want to stop an existing single update before it runs.  this is because single updates stop themselves after running.
  EndIf
EndEvent

This script has a continuous loop of single updates. The only way to break the loop is for the player to unequip ObjectA. It is a necessary evil for the ability to equip/unequip ObjectB whenever weapons are drawn or put away. Thankfully, continuous single update loops are less dangerous than regular update loops. When a single update loop is broken outside of expected parameters, it will fail once and not continue. Whereas a regular update loop will keep going without being properly shut down.

 

 

Link to comment
Share on other sites

Was able to compile what you have here.

Changed Armor Property ObjectA Auto to Weapon Property ObjectA Auto

 

Never made a quest before and 2 hour tutorials are a bit more then I can stand.

I would think it wouldn't be that hard to add this to a Quest but I can't get it to work

Clearly I don't know what I'm doing when it comes to that.

 

 

Editing back here: Just like to mention a possible small logic error in your script.

Please don't take offence like everyone else seem to around here ...

(I think you are an amazing programmer always study your scripts)

 

The PlayerRef == Game.GetPlayer() can't be used everyplace in the script.

As some of the code needs to be checked in real time. I may be wrong here.

But I did try to use that in my last code and ran into problems.

 

Exp: With, If(Game.GetPlayer().GetItemCount(RingPower) == 1) It needed to check the player in real time.

The "preset version" was giving me the then on the inventory check. Not all the instances need a real time check.

But, A few of them do including the Game.GetPlayer().IsWeaponDrawn() .

 

I wish, I could understand how to do what you're talking about. It seems to be over my head. (Grrrr)

Edited by NexusComa
Link to comment
Share on other sites

Onequip/onunequip are unreliable and it will mess up eventually. Better to give it an enchantment and use oneffectstart/end on a magic effect on said enchantment.

 

I think you can register for animations from the magic effect

 

So the desired effect is that item1 equips item2 (and adds?) Item2 while a weapon is drawn? Both are rings? Wouldn't the second unequip the first?

Edited by FrankFamily
Link to comment
Share on other sites

Got it !! ... add this script to the weapon then fill property with the ring ...



Scriptname _BaseAspectRingScript extends ObjectReference

Armor Property RingPower Auto

Float UpdateTime = 3.0

Int RingState = 0

Int ScanState = 0


Event OnInit()

;Debug.MessageBox("test 19")

EndEvent


Event OnEquipped(Actor akActor)

;Debug.Notification("equiped weapon")

RingState = 0

ScanState = 1

Self.Update() ; made a reclusive function to mimic OnUpdate()

EndEvent


Event OnUnEquipped(Actor akActor)

;Debug.Notification("unequiped weapon")

Game.GetPlayer().UnEquipItem(RingPower, false, true) ; no notification

;Game.GetPlayer().RemoveItem(RingPower) ;in case you want to just remove ring

RingState = 0

ScanState = 0

EndEvent


Function Update()

;Debug.Notification("scanning")

If(Game.GetPlayer().GetItemCount(RingPower) == 1)

If(Game.GetPlayer().IsWeaponDrawn() == 1)

If(RingState == 0)

;Debug.Notification("weapon drawn")

Game.GetPlayer().EquipItem(RingPower, false, true)

RingState = 1

Endif

ElseIf(Game.GetPlayer().IsWeaponDrawn() != 1)

If(RingState == 1)

;Debug.Notification("weapon sheathed")

Game.GetPlayer().UnEquipItem(RingPower, false, true)

RingState = 0

Endif

EndIf

Utility.Wait(UpdateTime)

If(ScanState == 1)

Self.Update()

EndIf

Else

Debug.Notification("Missing the Power Ring")

Endif

EndFunction

;



Take out the 1st If-Else-Endif statements if you don't want a ring check.

Take out the lower Else-Debug statements if you don't want to tell them that.


If you remove this If statement the ring will just appear in the inventory.

(if so unrem the Game.GetPlayer().RemoveItem(RingPower) if you wish to remove it)


Also ...

If you do use this If statement, if you have the weapon equipped with out the ring in

your inventory. You will need to unequipped then reequipped when you have the ring.
Edited by NexusComa
Link to comment
Share on other sites

  • Recently Browsing   0 members

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