duude98 Posted March 18, 2016 Posted March 18, 2016 I am working on a system for my Zelda mod that makes keys behave like they do in that game. I want it to remove one key each time a door is unlocked. In testing, I picked up two keys from my inventory, and unlocked one door, which removed both keys. Quickly, here is my script;Actor Property PlayerRef Auto Key Property SmallKey AutoEvent OnActivate(ObjectReference akActionREF) If akActionREF == PlayerRef If Self.GetLockLevel() == 255 Game.GetPlayer().RemoveItem(SmallKey, 1) Debug.MessageBox("The script fired") Self.SetLockLevel(0) EndIf EndIfEndEvent I attach this to every locked door, and I only use GetLockLevel because IsLocked did not work correctly. This might be too much information, or the wrong information, to solve this problem, but basically, how do I remove just ONE key from the player's inventory? When I pick up multiple keys, there is a number next to it in the inventory, so they do stack. I guess this doesn't work this way because it never comes up in normal gameplay?
JetSteele Posted March 18, 2016 Posted March 18, 2016 Its the self part of the script that won't fire properly. Try using a door property then set the property to itself (meaning the door and NOT the objectreference of the door), its a little redundant to do it this way and to have to set the door itself as itself but this should make it work properly. Just test it on one door first...don't set all the doors up until you know that it works.
duude98 Posted March 18, 2016 Author Posted March 18, 2016 (edited) On 3/18/2016 at 8:00 AM, JetSteele said: Its the self part of the script that won't fire properly. Try using a door property then set the property to itself (meaning the door and NOT the objectreference of the door), its a little redundant to do it this way and to have to set the door itself as itself but this should make it work properly. Just test it on one door first...don't set all the doors up until you know that it works.The script actually fires fine, it just removes more keys than it should. Plus I tried that, but I could not set the property to the door the script was on, as i could not select it in the render window because the edit dialogue for that specific door was open, and I re-use that door in the cell, so I can't tell which it is in the list.Also, I am just testing it on one door atm.EDIT: Re-read what you typed, and I realize that my second sentence is void. But, what did you mean by the door and not the objectreference? The actual form for the door in the object window? I don't want this to happen to all doors of this type, just ones I apply the script to. Edited March 18, 2016 by duude98
JetSteele Posted March 18, 2016 Posted March 18, 2016 Oops sorry misread your issue with the script, lol. I scimmed it and thought you had issues getting the GetLockLevel to fire, my mistake. Okay so try adding this to your script before removing your key: GlobalVariable Property KeyCount Auto KeyCount.SetValue(Game.GetPlayer().GetItemCount(SmallKey))KeyCount.Mod(-1) and after you remove your key: if ( Game.GetPlayer().GetItemCount(SmallKey) != KeyCount.GetValue() )Game.GetPlayer().RemoveItem(SmallKey, Game.GetPlayer().GetItemCount(SmallKey), true)Utility.Wait(0.5)Game.GetPlayer().AddItem(SmallKey, KeyCount.GetValue(), true)Utility.Wait(1.0) ;safeguard for items added before set to 0, could lower this amount to test how fast to fire the next line.endifKeyCount.SetValue(0) though you shouldn't be needing to do this; the game should be subtracting the normal amount of keys on its own with the RemoveItem() function...really strange. *I tweaked the code to first check if you have the amount of keys you need before adding more keys to the player, to remove the possibility of a bug happening where you can just get extra keys for no reason. Let me know if the remove item line in after the key is removed doesn't work and I'll tweak it to work with an integer instead of calling that function from the RemoveItem() directly
duude98 Posted March 18, 2016 Author Posted March 18, 2016 On 3/18/2016 at 8:32 AM, JetSteele said: Oops sorry misread your issue with the script, lol. I scimmed it and thought you had issues getting the GetLockLevel to fire, my mistake. Okay so try adding this to your script before removing your key: GlobalVariable Property KeyCount Auto KeyCount.SetValue(Game.GetPlayer().GetItemCount(SmallKey))KeyCount.Mod(-1) and after you remove your key: Game.GetPlayer.AddItem(SmallKey, KeyCount.GetValue(), true)Utility.Wait(1.0) ;safeguard for items added before set to 0, could lower this amount to test how fast to fire the next line.KeyCount.SetValue(0) though you shouldn't be needing to do this; the game should be subtracting the normal amount of keys on its own with the RemoveItem() function...really strange.I added those, and now I get this error when compiling;Starting 1 compile threads for 1 files...Compiling "zeldadungeonlockeddoorscript"...E:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\temp\zeldadungeonlockeddoorscript.psc(12,20): type mismatch on parameter 2 (did you forget a cast?)No output generated for zeldadungeonlockeddoorscript, compilation failed. Batch compile of 1 files finished. 0 succeeded, 1 failed.Failed on zeldadungeonlockeddoorscript Also, my script now looks like this;Scriptname zeldadungeonlockeddoorscript extends ObjectReference Actor Property PlayerRef Auto Key Property SmallKey AutoGlobalVariable Property KeyCount AutoEvent OnActivate(ObjectReference akActionREF) If akActionREF == PlayerRef If Self.GetLockLevel() == 255 KeyCount.SetValue(Game.GetPlayer().GetItemCount(SmallKey)) KeyCount.Mod(-1) Game.GetPlayer().RemoveItem(SmallKey, 1) Game.GetPlayer().AddItem(SmallKey, KeyCount.GetValue(), true) Utility.Wait(1.0) ;safeguard for items added before set to 0, could lower this amount to test how fast to fire the next line. KeyCount.SetValue(0) Debug.MessageBox("The script fired") Self.SetLockLevel(0) EndIf EndIfEndEvent Seems papyrus doesn't like the additem line for some reason, though it looks fine to me...
JetSteele Posted March 18, 2016 Posted March 18, 2016 Alright seems that AddItem doesn't play nice with globals. Let's try it with integers:Actor Property PlayerRef Auto Key Property SmallKey Auto GlobalVariable Property KeyCount Auto int KeyCountActual Event OnActivate(ObjectReference akActionREF) if akActionREF == PlayerRef if Self.GetLockLevel() == 255 KeyCount.SetValue(PlayerRef.GetItemCount(SmallKey)) KeyCount.Mod(-1) PlayerRef.RemoveItem(SmallKey, 1) if (PlayerRef.GetItemCount(SmallKey) != KeyCount.GetValue()) KeyCountActual == KeyCount.GetValue() PlayerRef.RemoveItem(SmallKey, PlayerRef.GetItemCount(SmallKey), true) Utility.Wait(0,5) PlayerRef.AddItem(SmallKey, KeyCountActual, true) Utility.Wait(1.0) endif KeyCount.SetValue(0) Debug.MessageBox("The Script fired") Self.SetLockLevel(0) endif endif EndEventTry this out.
duude98 Posted March 18, 2016 Author Posted March 18, 2016 Starting 1 compile threads for 1 files...Compiling "zeldadungeonlockeddoorscript"...E:\Program Files (x86)\Steam\steamapps\common\skyrim\Data\Scripts\Source\temp\zeldadungeonlockeddoorscript.psc(18,8): too many arguments passed to functionNo output generated for zeldadungeonlockeddoorscript, compilation failed.Batch compile of 1 files finished. 0 succeeded, 1 failed.Failed on zeldadungeonlockeddoorscript Seems to now have a problem with the wait line. I deleted an endif too to get rid of another error, but I think that one might have been left over.
JetSteele Posted March 18, 2016 Posted March 18, 2016 Actor Property PlayerRef Auto Key Property SmallKey Auto GlobalVariable Property KeyCount Auto int KeyCountActual int KetCountOld Event OnActivate(ObjectReference akActionREF) if akActionREF == PlayerRef if Self.GetLockLevel() == 255 KeyCount.SetValue(PlayerRef.GetItemCount(SmallKey)) KeyCount.Mod(-1) PlayerRef.RemoveItem(SmallKey, 1) if (PlayerRef.GetItemCount(SmallKey) != KeyCount.GetValue()) KeyCountActual == KeyCount.GetValue() KeyCountOld == PlayerRef.GetItemCount(SmallKey) PlayerRef.RemoveItem(SmallKey, KeyCountOld, true) Utility.Wait(0,5) PlayerRef.AddItem(SmallKey, KeyCountActual, true) Utility.Wait(1.0) endif KeyCount.SetValue(0) Debug.MessageBox("The Script fired") Self.SetLockLevel(0) endif endif EndEventTry this...I've tweaked it to make the integers take over all the functions that the globals used.
duude98 Posted March 18, 2016 Author Posted March 18, 2016 I added "property" and "auto" to keycountactual and keycountold, and on compiling, it still gives the same error for the same line. Is it possible that there is something wrong on my end that would cause this to not work? Also, is this Utility.Wait line needed? I feel like it should work, but if it never actually does, could the script as you wrote it function without it?
JetSteele Posted March 18, 2016 Posted March 18, 2016 Yes it'll work without it...I just saw I put a comma instead of a period on the wait function change it to a period. The function is just to give the game enough time to remove the keys before adding back the proper amount.
Recommended Posts