IsharaMeradin Posted March 12, 2020 Share Posted March 12, 2020 I do have a working example of GetNthForm and I used it as reference for the function posted earlier. Here is the working code, it is taken from my Inventory Management System mod: The function is specific to the needs of the MCM script so it cannot be utilized as-is for other purposes Function GetPlayerAmmo(Bool TFbolt = false) Int Z = PlayerRef.GetNumItems() Int Y = 0 While Y < Z If PlayerRef.GetNthForm(Y) as Ammo Ammo Entry = PlayerRef.GetNthForm(Y) as Ammo If Entry != Game.GetFormFromFile(0x0010B0A7, "Skyrim.esm") && Entry != Game.GetFormFromFile(0x000CAB52,"Skyrim.esm") ;don't process bound arrows or practice arrows. If TFBolt == false If !(ArrowMaster.HasForm(Entry)) && Entry.IsBolt() == false ArrowMaster.AddForm(Entry) EndIf Else If !(BoltMaster.HasForm(Entry)) && Entry.IsBolt() == true BoltMaster.AddForm(Entry) EndIf EndIf EndIf EndIf Y += 1 EndWhile EndFunction TL;DRFollow the example on the wiki page. The description while not wrong can be misleading. The index count starts at 0. If GetNumItems returned 2 the indexes would be 0 and 1. An index of 3 would yield NONE as would an index of 2 for that matter. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 12, 2020 Author Share Posted March 12, 2020 The description while not wrong can be misleading. The index count starts at 0. If GetNumItems returned 2 the indexes would be 0 and 1. An index of 3 would yield NONE as would an index of 2 for that matter. Ah, that makes sense, thankyou for all your help and the function! :smile: diziet Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 16, 2020 Author Share Posted March 16, 2020 I'm having difficulty add ing your function to my script, does it work in a script that extends ObjectReference? Should I extend something else?here is the compile output: Starting 1 compile threads for 1 files...Compiling "dz_mcm_ver2_nakedactivator"...D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(90,21): type mismatch on parameter 1 (did you forget a cast?)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(90,35): cannot cast a none to a ammo, types are incompatibleD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(91,35): type mismatch on parameter 1 (did you forget a cast?)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(91,49): cannot cast a none to a ammo, types are incompatibleD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(93,16): property Y on script objectreference is read-only, you cannot give it a valueD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(93,16): type mismatch while assigning to a none (cast missing or types unrelated)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(96, :cool:: property Y on script objectreference is read-only, you cannot give it a valueD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(96, :cool:: type mismatch while assigning to a none (cast missing or types unrelated)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(98,11): variable Entry is undefinedNo output generated for dz_mcm_ver2_nakedactivator, compilation failed.Batch compile of 1 files finished. 0 succeeded, 1 failed.Failed on dz_mcm_ver2_nakedactivator as currently written: Ammo Function GetEquippedAmmo() ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE ;Ammo Entry = NONE Int Z = PlayerRef.GetNumItems() Int Y = 0 While Y < Z If PlayerRef.GetNthForm(Y) as Ammo Ammo Entry = PlayerRef.GetNthForm(Y) as Ammo If PlayerRef.IsEquipped(Entry) Y = Z ; only one ammo can be equipped once gotten advance count to exit early EndIf EndIf Y += 1 EndWhile Return EntryEndFunction the first line is line 84 plus in the quoted output I can't get the : ; to show properly :smile: diziet Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 16, 2020 Share Posted March 16, 2020 (edited) This is the first one that I posted, use it as is. Ammo Function GetEquippedAmmo(Actor Dude) ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE Ammo Entry = NONE Int Z = Dude.GetNumItems() Int Y = 0 While Y < Z If Dude.GetNthForm(Y) as Ammo Entry = Dude.GetNthForm(Y) as Ammo If Dude.IsEquipped(Entry) Y = Z ; only one ammo can be equipped once gotten advance count to exit early Else Entry = NONE ; we do not want this ammo as it is not equipped EndIf EndIf Y += 1 EndWhile Return Entry EndFunction Call it from within your event where you want to know what ammo is equipped as follows: GetEquippedAmmo(Game.GetPlayer()) Replace Game.GetPlayer() with PlayerRef or other variable you may have that is already referencing the player. Make sure that you do not already have properties on your script using the same name(s) as any of the variables within the function. If you do, change the variable names as necessary within the function. A lot of your errors will be resolved simply by declaring the Entry variable at the beginning as in the function above in this post rather than within the while loop as in the working example of GetNthForm in an earlier post. EDIT: Adjusted function code to account for an issue brought up by dylbill (see a few posts below on this page) Edited March 16, 2020 by IsharaMeradin Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 16, 2020 Author Share Posted March 16, 2020 This is the first one that I posted, use it as is.Well that's the problem, originally I did that but I got similar errors, what I posted above was my latest attempt:) Here is my whole script with your function verbatim: Scriptname dz_mcm_ver2_nakedactivator extends ObjectReference spell property dz_naked_spell_ver2 auto dz_mcm_ver2_undressing_script property mcm auto Actor Property PlayerRef Auto ;define variable for disrobing bool disrobed ;define variable for combat check bool noCombatCheck ;define variable for camera state int iCameraState ;define variables for weapons in each hand Weapon equippedleft Weapon equippedright ;define variable for player shield Armor player_shield ;define arrays for armour and spells Armor[] Armor_1 Armor[] Armor_2 Spell[] Spell_1 Event OnInit() Armor_1 = new Armor[20] Armor_2 = new Armor[10] Spell_1 = new Spell[4] endEvent ;;;;;;;;;;;;;;wip for arrows/quivers Ammo Function GetEquippedAmmo(Actor Dude) ;this function returns the ammo equipped by the passed in actor otherwise it returns NONE Ammo Entry = NONE Int Z = Dude.GetNumItems() Int Y = 0 While Y < Z If Dude.GetNthForm(Y) as Ammo Entry = Dude.GetNthForm(Y) as Ammo If Dude.IsEquipped(Entry) Y = Z ; only one ammo can be equipped once gotten advance count to exit early EndIf EndIf Y += 1 EndWhile Return Entry EndFunction Event OnTriggerEnter(ObjectReference triggerRef) ;debug.notification("found something!") Actor akactionRef = triggerRef as Actor disrobed = mcm.disrobes If (mcm.ignoreCombat == true) noCombatCheck = true elseif (mcm.ignoreCombat == false && !PlayerRef.isincombat()) noCombatCheck = true else noCombatCheck = false endif ;debug.notification("disrobed = "+mcm.disrobes) if (akActionRef != game.getplayer() && noCombatCheck == true) ;debug.notification("effect applied") dz_naked_spell_ver2.cast(akactionref,akactionref) else ;find camera state only if trigger is player iCameraState = Game.GetCameraState() ; this is an skse function ;check for skyui if (Game.GetFormFromFile(0x00000814, "SkyUI_SE.esp") == None) debug.notification("You have installed the SkyUI version of this mod but no SkyUI was found.") ;change to third person if not already if mcm specifies elseif (iCameraState == 0 && mcm.third_person == true) Game.ForceThirdPerson() ;otherwise stay in first person if already there elseif (mcm.third_person == false) endif if (disrobed == true && akActionRef == game.getplayer() && noCombatCheck == true) ;get weapons ;debug.messagebox("Filling weapons") equippedleft = PlayerRef.GetEquippedWeapon(true) equippedright = PlayerRef.GetEquippedWeapon() ;get shield player_shield = PlayerRef.GetEquippedShield() ;;test getammo function debug.messagebox("Ammo is "+GetEquippedAmmo(PlayerRef)) ;fill the spell_1 array Int spell_no = spell_1.length While spell_no spell_no -= 1 spell_1[spell_no] = PlayerRef.GetEquippedSpell(spell_no) endWhile ;fill the first armour array Int slot1 = armor_1.length + 30 ;ebug.messagebox("initial slot1 = "+slot1) Int index1 = armor_1.length ;debug.messagebox("initial index1 ="+index1) While index1 ;debug.messagebox("Filling " +index1) index1 -= 1 armor_1[index1] = PlayerRef.GetEquippedArmorInSlot(slot1) slot1 -= 1 endWhile ;fill the aecond armour array Int slot2 = armor_2.length + 52 Int index2 = armor_2.length While index2 index2 -= 1 armor_2[index2] = PlayerRef.GetEquippedArmorInSlot(slot2) slot2 -= 1 endWhile akActionRef.unequipall() endif endif endEvent Event OnTriggerLeave(ObjectReference triggerRef) Actor akactionRef = triggerRef as Actor if (akActionRef != PlayerRef) ;debug.notification("effect removed") akActionRef.dispelspell(dz_naked_spell_ver2) endif ;return to first person if necessary if (iCameraState == 0 && mcm.third_person == true && akActionRef == PlayerRef) Game.ForceFirstPerson() endif ;if trigger is the player if (akActionRef == PlayerRef && disrobed == true) ;equip weapons PlayerRef.EquipItemEx(equippedleft,2,true) ;this is an skse function PlayerRef.EquipItemEx(equippedright,1) ;this is an skse function ;equip shield PlayerRef.EquipItemEx(player_shield) ;re-equip the spells int spell_no = spell_1.length while spell_no spell_no -=1 PlayerRef.EquipSpell(spell_1[spell_no],spell_no) endWhile ;debug.messagebox("Re-equipping armour") ;re-equip the first armour array , int index1 = armor_1.length while index1 ;debug.messagebox("Re-equip "+index1) index1 -= 1 PlayerRef.EquipItemEx(armor_1[index1],0,false,true) endWhile ;re-equip the second armour array , int index2 = armor_2.length while index2 index2 -= 1 PlayerRef.EquipItemEx(armor_2[index2],0,false,true) endWhile endif ;debug.messagebox("Leave Triggered") endEvent and compile errors are: Starting 1 compile threads for 1 files...Compiling "dz_mcm_ver2_nakedactivator"...D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(47,16): type mismatch on parameter 1 (did you forget a cast?)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(47,30): cannot cast a none to a ammo, types are incompatibleD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(48,25): type mismatch on parameter 1 (did you forget a cast?)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(48,39): cannot cast a none to a ammo, types are incompatibleD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(50,16): property Y on script objectreference is read-only, you cannot give it a valueD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(50,16): type mismatch while assigning to a none (cast missing or types unrelated)D:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(53, :cool:: property Y on script objectreference is read-only, you cannot give it a valueD:\SteamLibrary\steamapps\common\Skyrim Special Edition\Data\Scripts\Source\dz_mcm_ver2_nakedactivator.psc(53, :cool:: type mismatch while assigning to a none (cast missing or types unrelated)No output generated for dz_mcm_ver2_nakedactivator, compilation failed.Batch compile of 1 files finished. 0 succeeded, 1 failed.Failed on dz_mcm_ver2_nakedactivator so far I'm just trying to get the ammo detected and shown in a messagebox before continuing. diziet Link to comment Share on other sites More sharing options...
dylbill Posted March 16, 2020 Share Posted March 16, 2020 (edited) Hey, thought I'd put in my 2 cents. I'm also having to detect equipped ammo for a mod I'm working on. If you're tracking all ammo in the game with a formlist, as IsharaMeradin suggested earlier, you can just compare with IsEquipped and the formlist on an actor. I recommend doing this because it doesn't require skse and actors, especially the player can have a lot of items and it's more likely that the ammo formlist will have less forms to check. Here's the function I'm using: Formlist Property AllAmmo Auto Ammo Function FindEquippedAmmo(Actor Ref) Int M = AllAmmo.GetSize() While M > 0 M -= 1 If Ref.IsEquipped(AllAmmo.GetAt(M)) Return AllAmmo.GetAt(M) as ammo Endif EndWhile EndFunction Event SomeEvent() Ammo EquippedAmmo = FindEquippedAmmo(SomeActor) EndEvent Edited March 16, 2020 by dylbill Link to comment Share on other sites More sharing options...
dylbill Posted March 16, 2020 Share Posted March 16, 2020 Hey one more thing. If you are using SKSE, you could also use Papyrus Extender: https://www.nexusmods.com/skyrimspecialedition/mods/22854 which has this: Form[] function AddAllEquippedItemsToArray(Actor akActor). That way, you only have to check equipped items on an actor. The function would then look like this: Ammo Function FindEquippedAmmo(Actor Ref) Form[] EquippedItems = PO3_SKSEfunctions.AddAllEquippedItemsToArray(Ref) Int M = EquippedItems.Length While M > 0 M -= 1 If EquippedItems[M] as ammo Return EquippedItems[M] as ammo Endif EndWhile EndFunction Event SomeEvent() Ammo EquippedAmmo = FindEquippedAmmo(SomeActor) EndEvent If you're having compilier errors, try copying all files from your Data/Scripts/Source folder to the Data/Source/Scripts folder. Link to comment Share on other sites More sharing options...
dizietemblesssma Posted March 16, 2020 Author Share Posted March 16, 2020 Thanks dylbill, Interesting ideas, and I may use them, but as part of my learning I'd like to find out why the script by IsharaMeradin doesn't work for me:)As for compiling I think my files are in the right place because I've had successful compiles before now. diziet Link to comment Share on other sites More sharing options...
dylbill Posted March 16, 2020 Share Posted March 16, 2020 (edited) 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. Edited March 16, 2020 by dylbill Link to comment Share on other sites More sharing options...
IsharaMeradin Posted March 16, 2020 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 dizietemblesssma Link to comment Share on other sites More sharing options...
Recommended Posts