dizietemblesssma Posted March 16, 2020 Author Share Posted March 16, 2020 @dizietemblesssmaIt 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. @dylbillMy 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 dizietemblesssmaI 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 More sharing options...
IsharaMeradin Posted March 16, 2020 Share Posted March 16, 2020 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 More sharing options...
dizietemblesssma Posted March 16, 2020 Author Share Posted March 16, 2020 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 More sharing options...
dylbill Posted March 17, 2020 Share Posted March 17, 2020 (edited) 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 March 17, 2020 by dylbill Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 17, 2020 Author Share Posted March 17, 2020 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 More sharing options...
dylbill Posted March 17, 2020 Share Posted March 17, 2020 No prob, glad it's working! That is weird about the global thing though, I've also never had to do that. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 19, 2020 Author Share Posted March 19, 2020 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 More sharing options...
dylbill Posted March 19, 2020 Share Posted March 19, 2020 Ah yes, I noticed that problem too when I was testing. I think its cause z is already a property on an object reference. XYZ position or angle maybe. Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 19, 2020 Share Posted March 19, 2020 Could be. My usage was on an MCM script where there were no objects referenced directly but rather within an array or formlist. That might be why the Y and Z variables worked for me but did not work in your situation. Link to comment Share on other sites More sharing options...
Recommended Posts