Jump to content

Help with a "pretty" simple script


Tobias44142

Recommended Posts

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 nails

I'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 work

If I wasn't specific enough, just ask for any details.

 

Thank you for reading.

 

https://imgur.com/FxDCSp9

Edited by Tobias44142
Link to comment
Share on other sites

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)
EndIf

With 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

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 by Tobias44142
Link to comment
Share on other sites

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

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")
EndEvent

Made 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

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 by Tobias44142
Link to comment
Share on other sites

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

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

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 Auto

Int Property NeededQuantity01 Auto

etc.

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

  • Recently Browsing   0 members

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