Jump to content

Arrows/bolts and quivers


Recommended Posts

@dizietemblesssma

It seems that It is having an issue with the local parameter. The errors seem to indicate that it cannot recognize the passed in actor. And your test tried replacing it with PlayerRef directly and it still had issues. I cannot figure out why.

 

@dylbill

My function should also return the equipped ammo... Oh, I see it. As ammo is found it is stored in the Entry variable and while an equipped one will exit the loop and get passed, if there is no equipped ammo the last ammo found will still be stored in the Entry variable. I'll go edit that. But that will not solve whatever issue is going on for dizietemblesssma

I got the compile to work by adding 'Global' as so:

Ammo Function GetEquippedAmmo(Actor Ref) Global

 

is this about where in the script the function is defined, I'm putting it in the empty state, should I put it in the OnTriggerEnter event?

 

Also noticed the last ammo equipped thing now that it compiles! :)

Link to comment
Share on other sites

Needed to add global? That is weird. I don't think that I have ever had to do that. At least you got it to compile, so yay!?!?

 

Functions get defined in the empty state or inside any other state if the function code will be different per state. Functions can be called from within events or other functions but cannot be defined inside of an event or function.

Link to comment
Share on other sites

But did your compiles include skse functions? I say that because by default skse's source scripts are in Data/Scripts/Source, while the Special Edition source scripts are located in Data/Source/Scripts. I tried compiling IsharaMeradin's script function and it works for me. But there's a problem in that it will always return an ammo if the actor has any ammo in their inventory, even if it's not equipped. Modified to:

 

 

 

Ammo Function GetEquippedAmmo(Actor Dude)
    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE
    Int Z = Dude.GetNumItems()
    While Z > 0
        Z -= 1
        Form Entry = Dude.GetNthForm(Z)
        If Entry as Ammo && Dude.IsEquipped(Entry)
            Return Entry as ammo
        EndIf
    EndWhile   
EndFunction

 

 

 

It will return none if no ammo is equipped.

I've tested all of the above functions for getting equipped ammo and they all work. It's just a matter of your preference.

I still had an issue with equipping arrows if none were equipped to start with, I made an edit that so far is working:

 

 

Ammo Function GetEquippedAmmo(Actor Ref) Global
    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE
    ;Ammo Entry = NONE
    Int Z = Ref.GetNumItems()
While Z > 0
        Z -= 1
        Form Entry = Ref.GetNthForm(Z)
        If Entry as Ammo && Ref.IsEquipped(Entry)
            Return Entry as ammo
            Z = 0
        Else
            Entry = NONE
           ;Return Entry as ammo
        EndIf
    EndWhile
EndFunction

 

 

 

to make my script work I had to add a variable:

Ammo player_ammo

in the empty state

 

so that I could set it in the OnTriggerEnter event using the function and still access it in the OnTriggerLeave event.

 

This has been an educational experience, though with still some questions for me about why some things didn't work, but it's good to finally have something that works - if I dare say that!

 

thanks both

 

diziet

Link to comment
Share on other sites

No problem. A few things to consider. You don't have to do Z = 0 in the function to stop the while loop. Return will automatically stop the function. You also don't have to do Entry = none. If the function doesn't find a return result, it will automatically return none. To test this here is the script I used:

 

Event OnInit()
    RegisterForKey(42) ;left shift
EndEvent 


Event OnKeyDown(Int keyCode)
    Ammo PlayerAmmo = GetEquippedAmmo(pPlayerRef)
    If PlayerAmmo == none
        Debug.MessageBox("Equipped Ammo is none")
    Else
        Debug.MessageBox("Equipped Ammo is " + PlayerAmmo.GetName())
    Endif
EndEvent


Ammo Function GetEquippedAmmo(Actor Dude)
    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE
    Int Z = Dude.GetNumItems()
    While Z > 0
        Z -= 1
        Form Entry = Dude.GetNthForm(Z)
        If Entry as Ammo && Dude.IsEquipped(Entry)
            Return Entry as ammo
        EndIf


        Debug.MessageBox("Z is " + Z)
        Utility.Wait(0.2)
    EndWhile    
EndFunction

If you're using a script function to fill a property, the script can only use it at the same level, or upwards. Example:
This script won't compile, it will say MyWeapon is undefined.

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
    If akBaseObject as Weapon 
        Weapon MyWeapon = akBaseObject as weapon
    Elseif akBaseObject as Ammo 
        Ammo MyAmmo = akBaseObject as ammo
    Endif 
    
    Debug.MessageBox(MyWeapon.GetName() + "\n" + MyAmmo.GetName())
EndEvent

This script will compile:

Event OnObjectEquipped(Form akBaseObject, ObjectReference akReference)
    Weapon MyWeapon
    Ammo MyAmmo
    
    If akBaseObject as Weapon 
        MyWeapon = akBaseObject as weapon
    Elseif akBaseObject as Ammo 
        MyAmmo = akBaseObject as ammo
    Endif 
    
    Debug.MessageBox(MyWeapon.GetName() + "\n" + MyAmmo.GetName())
EndEvent

So, if you need to use a property in multiple events, or states, define it outside of any events or states. I would also put any custom functions outside of any states, that may be why you're having to use Global.
As an example, here's how I would do the triggerbox script:

Scriptname dz_mcm_ver2_nakedactivator extends ObjectReference 

Ammo EquippedAmmo

Event OnTriggerEnter(ObjectReference triggerRef)
    If triggerRef as Actor
        EquippedAmmo == GetEquippedAmmo(triggerRef as actor)
        Debug.MessageBox(EquippedAmmo.GetName())
    Endif
    
EndEvent

Event OnTriggerLeave(ObjectReference akTriggerRef)
    If EquippedAmmo != none 
        Debug.MessageBox(EquippedAmmo.GetName())
    EndIf
EndEvent

Ammo Function GetEquippedAmmo(Actor Dude)
    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE
    Int M = Dude.GetNumItems()
    While M > 0
        M -= 1
        Form Entry = Dude.GetNthForm(M)
        If Entry as Ammo && Dude.IsEquipped(Entry)
            Return Entry as ammo
        EndIf
    EndWhile    
EndFunction

Edited by dylbill
Link to comment
Share on other sites

No problem. A few things to consider. You don't have to do Z = 0 in the function to stop the while loop. Return will automatically stop the function. You also don't have to do Entry = none. If the function doesn't find a return result, it will automatically return none. To test this here is the script I used:

 

OK, when testing I had some problems and they went away after I did that but I just removed them as per your example and the problems didn't come back so thanks:)

As an example, here's how I would do the triggerbox script:

Scriptname dz_mcm_ver2_nakedactivator extends ObjectReference 

Ammo EquippedAmmo

Event OnTriggerEnter(ObjectReference triggerRef)
    If triggerRef as Actor
        EquippedAmmo == GetEquippedAmmo(triggerRef as actor)
        Debug.MessageBox(EquippedAmmo.GetName())
    Endif
    
EndEvent

Event OnTriggerLeave(ObjectReference akTriggerRef)
    If EquippedAmmo != none 
        Debug.MessageBox(EquippedAmmo.GetName())
    EndIf
EndEvent

Ammo Function GetEquippedAmmo(Actor Dude)
    ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE
    Int M = Dude.GetNumItems()
    While M > 0
        M -= 1
        Form Entry = Dude.GetNthForm(M)
        If Entry as Ammo && Dude.IsEquipped(Entry)
            Return Entry as ammo
        EndIf
    EndWhile    
EndFunction

 

Well I place the function outside all events and I had to use 'Global' to get a successful compile, but since it works now I'm happy!
diziet
Link to comment
Share on other sites

No prob, glad it's working! That is weird about the global thing though, I've also never had to do that.

Well following some help I'm getting in another thread I swapped the 'Z' for 'i' in:

 

Int Z = Dude.GetNumItems()
    While Z > 0
        Z -= 1
        Form Entry = Dude.GetNthForm(Z)

 

and now it compiles without the 'Global'

 

I suspect the explanation is way above my pay grade. :)

Link to comment
Share on other sites

  • Recently Browsing   0 members

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