Tobias44142 Posted March 27, 2023 Share Posted March 27, 2023 (edited) This script works 100% when theres only one IF statement in regards to "Player.GetItemCount". Originally it was designed to just check and see if the player had the required firewood for the "YES" button on the message box to fix the dock. What I want to do is have it so you need both set number of wood AND BYOH Nails from Hearthfire. Because why not? Anyways. Most of the script works with the exception being the default notification "Else" statements should the player not have either or both of the materials for the script to fire.So as highlighted with the red arrows in the picture below, as it stands right now, only the nails will give the notification of being short but only when player has the required wood.To be clear, the notification will not run if:-Player has the nails, but not enough wood-Player has neither the wood nor nailsI've played around with the order of things and changing my "Else" statements to "ElseIf" statements to no avail. I'm guessing this is something fairly simple but i've only ever worked on 3 scripts (this one included) in the Creation kit.Hoping someone can instruct me on what I might need to add or change to get these to workIf I wasn't specific enough, just ask for any details. Thank you for reading. https://imgur.com/FxDCSp9 Edited March 27, 2023 by Tobias44142 Link to comment Share on other sites More sharing options...
scorrp10 Posted March 27, 2023 Share Posted March 27, 2023 Proper indentation is your friend. Now, here is a pseudo-rendering of your code. PGI is getting item count If Button==0 If PGI(Wood) >= 30 If PGI(Nails) >= 15 do_stuff Else If PGI(Wood) < 30 DN(Not enough wood) Else If PGI(Nails) < 15 DN(Not enough Nails) EndIf EndIf EndIf EndIf ElseIf Button == 1 DN(Meh) EndIfWith this, you can immediately see that if you lack needed wood, you will skip the entire block.AND if got the wood, but not nails, the 'PGI(Wood) < 30' check is always false, and PGI(Nails) < 15 is always true.Now how I would do it? If (aiButton == 0) Int WoodCount = Player.GetItemCount(Firewood01) Int NailCount = Player.GetItemCount(BYOHMaterialNails) If(WoodCount < 30) Debug.Notiification("Not enough Wood (" + WoodCount + "/30)") EndIf If(NailCount < 15) Debug.Notiification("Not enough Nails (" + NailCount + "/15)") EndIf If (WoodCount >= 30 && NailCount >= 15) {Get It Done} EndIf Else Debug.Notification("I quit") EndIf Link to comment Share on other sites More sharing options...
Tobias44142 Posted March 27, 2023 Author Share Posted March 27, 2023 (edited) Scriptname RiftenDockFixActivatorScript extends ObjectReference Message Property RiftenDockFixStartMenu1 Auto ObjectReference Property RiftenDockFixMarker Auto MiscObject Property Firewood01 Auto MiscObject Property BYOHMaterialNails Auto Actor Property PlayerRef Auto Sound Property NPCHumanBlacksmithRepairHammer Auto ObjectReference Property RiftenDockWoodPileNAVCUT1 Auto ObjectReference Property RiftenDockWoodPileNAVCUT2 Auto ObjectReference Property RiftenDockWoodPile1 Auto ObjectReference Property RiftenDockWoodPile2 Auto ObjectReference Property RiftenDockFixActivator2Trigger Auto Event OnActivate(ObjectReference akActionRef) Menu() EndEvent Function Menu(int aiButton = 0) aiButton = RiftendockFixStartMenu1.show() If aiButton == 0 Int WoodCount = PlayerRef.GetItemCount(Firewood01) Int NailCount = PlayerRef.GetItemCount(BYOHMaterialNails) If(NailCount < 15) debug.Notification ("You don't have the required nails") debug.Notification("As far as nails go, you have: "+PlayerRef.GetItemCount(BYOHMaterialNails)) EndIf If(WoodCount < 30) debug.Notification ("You don't have the required wood") debug.Notification("As far as lumber goes, you have: "+PlayerRef.GetItemCount(Firewood01)) EndIf If (WoodCount >= 30 && NailCount >= 15) Game.FadeOutGame(false, true, 3.0, 2.0) NPCHumanBlacksmithRepairHammer.Play(Self) Utility.Wait(0.4) NPCHumanBlacksmithRepairHammer.Play(Self) Utility.Wait(0.4) NPCHumanBlacksmithRepairHammer.Play(Self) Utility.Wait(0.4) NPCHumanBlacksmithRepairHammer.Play(Self) RiftenDockFixActivator2Trigger.enable() RiftenDockWoodPileNAVCUT1.enable() RiftenDockWoodPileNAVCUT2.enable() RiftenDockWoodPile1.enable() RiftenDockWoodPile2.enable() RiftenDockFixMarker.enable() PlayerRef.RemoveItem(Firewood01, 30) PlayerRef.RemoveItem(BYOHMaterialNails, 15) Utility.Wait(2.0) EndIf ElseIf aiButton == 1 Debug.Notification ("You decide not to bother with this mess") EndIf EndFunction This is what I got so far, trying to follow your example.hitting "YES" always reads you have 0 wood and 0 nails regardless of how many the player has.Having both required materials does not fire the script anymore this way. Edited March 27, 2023 by Tobias44142 Link to comment Share on other sites More sharing options...
scorrp10 Posted March 27, 2023 Share Posted March 27, 2023 You might have noticed I introduced the extra variables specifically in order to avoid making redundant 'GetItemCount' calls... But if you are saying that this line: debug.Notification("As far as nails go, you have: "+PlayerRef.GetItemCount(BYOHMaterialNails)) Says 'you have: 0', well, it means that PlayerRef.GetItemCount() is returning 0. If so, you should double-check that your properties are still being filled properly.I.e. right after 'If aiButton == 0'I would add: debug.Trace(Self + "Wood :" + Firewood01 + ", Nails :" + BYOHMateriialNails + ", Player :" + PlayerRef) You got your Papyrus logging enabled,, right? Link to comment Share on other sites More sharing options...
scorrp10 Posted March 27, 2023 Share Posted March 27, 2023 Just did a quickie, adding this to a magic effect script. MiscObject Property Firewood01 Auto MiscObject Property BYOHMaterialNails Auto Actor effectActor Event OnEffectStart(Actor akTarget, Actor akCaster) effectActor = akTarget Int WoodCount = effectActor.GetItemCount(Firewood01) Int NailCount = effectActor.GetItemCount(BYOHMaterialNails) Debug.Trace(Self + "Wood :" + Firewood01 + ", Nails :" + BYOHMaterialNails + ", Actor :" + effectActor + \ "(" + effectActor.GetActorBase().GetName() + ")") Debug.Trace(Self + ":" + effectActor.GetActorBase().GetName() + " has " + WoodCount + " wood and " + NailCount + " nails") EndEventMade sure that those properties are filled, seeing this in the log when effect is applied:[03/27/2023 - 05:27:19PM] [MyTestEffect <Active effect 7 on (00000014)>]Wood :[MiscObject < (0006F993)>], Nails :[MiscObject < (0300300F)>], Actor :[Actor < (00000014)>](Amy)[03/27/2023 - 05:27:19PM] [MyTestEffect <Active effect 7 on (00000014)>]:Amy has 30 wood and 20 nails Link to comment Share on other sites More sharing options...
Tobias44142 Posted March 27, 2023 Author Share Posted March 27, 2023 (edited) Ok i THINK i found the problem. I always use PlayerREF because simply defining an Actor Property with just "Player" doesn't seem to auto fill in the properties after editing the source. Its not a HUGE deal, I can just manually define it. But I removed the PlayerREF and went for just PLAYER in all instances of the script and now it seems to work so far. Still doing a bit more testing. Wow scripting really is touchy though. Like whatever its called the PLAYER has been defined so why's papyrus having a kanipshit over it lol? And of course THANK YOU for your dedicated help. Now i'll know how to use these INT properties a bit more.Its different cause normally properties are all defined at the begining or the end of the script. Its weird to me that they get defined right in the middle of a function. Edited March 27, 2023 by Tobias44142 Link to comment Share on other sites More sharing options...
anjenthedog Posted March 27, 2023 Share Posted March 27, 2023 Do you have an OR operator? if so, to logic should be simple In pseudo code since I'm not sure about which things have to be declared or how in this environment, where x and y represent booleans. Also not sure how embedding variable info into strings works so falling back on old RoR data insertion with the "#{...}" x = (WoodCount < 30) y = (NailCount < 15) if (x || y) { #ie, if either boolean test fails, process the errors and exit the routine if x { WoodUndercount = 30 - WoodCount "you need #{WoodUnderCount} more woodsezes" } if y { NailUndercount = 15 - NailCount "you need #{NailUnderCount} more Nailsezes" } } else # otherwise, everything is hunkee doree { your crafting recipe actions } end Link to comment Share on other sites More sharing options...
Tobias44142 Posted March 27, 2023 Author Share Posted March 27, 2023 No I'm not using any OR operator. I'm not sure how to implement one. But you're saying my original code could work if I did use an OR operator? Link to comment Share on other sites More sharing options...
anjenthedog Posted March 27, 2023 Share Posted March 27, 2023 Well I'm saying it's pretty trivial. set two Boolean variables to contain the result of test for failure of the thresholds (wood and nails) if either flags as true (error) , then it has failed "THE" test , so do whatever post fail text output you wan the user to see and exit routine. In my example, for this error situation, I then populated one or two temporary ?Integers? (WoodUnderCount, and NailUnderCount) with the missing qty(s) and created error text to display (the proper syntax for which I leave to you) Otherwise, the error test failed (we have enough of both nails and wood), and we can then process the else statement, ie, process your ?crafting? recipe the coding is an extension of, or is JavaScript right? If so, it should have an OR operator. Like I said, what I typed above is pseudo code. I really have no idea of the specific syntax used. Just guessing. But I know the logic. ex: you might have to write "If (x) { }" to have "x" evaluated AS a boolean, I'm not sure. Link to comment Share on other sites More sharing options...
scorrp10 Posted March 27, 2023 Share Posted March 27, 2023 WoodCount and NailCount are NOT properties, they are local variables. A property (defined using word Property) is essentially a member of a class, and can be accessed by other scripts, or they can serve to 'hook' your script to specific game objects.And indeed Properties are always defined outside of any function. A variable (defined without a word Property) is just that. These variables are accessible only to your script's internals. They can be global, in which case they will persist as long as this script instance exists, or they can be local.A local variable is scoped to a logical block where it is defined. Loading properties: you should never trust CK to fill your properties. After a script has been compiled, you should click its 'Properties' button and make sure properties are loaded correctly.I mean, if you define 'MiscObject Property Firewood01 Auto', then yeah, if you got the name exactly right, CK will likely auto-fill it. But lets say you create a more advanced script, usable in multiple cases, and you may define: MiscObject Property NeededMaterial01 AutoInt Property NeededQuantity01 Autoetc.CK would have no idea how to autofill those. But you can attach this script to multiple references, and on one, fill these properties with 'Firewood01' and 15, and on other, with, say, 'SteelIngot' and 3 Link to comment Share on other sites More sharing options...
Recommended Posts