Jump to content

Script Compiles, Doesn't Work as Intended (noob)


CompGuyJMB

Recommended Posts

Hi Everyone,

 

I'm still getting my bearings in the creation kit. I'm familiar with Object Oriented Programming (Visual Basic), but I'm having a heck of a time with Papyrus.

 

I'm trying to design a script that will be attached to a device (a radio). The intent of the script is to check to see if the power generator (PowerSource) is turned on. If it is, the radio will be "allowed" turn on. If the power source is off, the radio will turn off and not be "allowed" to turn on.

 

My script compiles successfully, but is not working as intended. It seems that it is stuck in the "PowerIsOff" state. I'm not sure if my OnPowerOn event is not working (or correct), or what's going on. It could even be the initial IsPowered check. Ideally, I'd prefer to use the EnableMarker for the PowerSource (and not the generator itself), but I haven't been able to find an OnEnable event in the Creation Kit documentation.

 

I also added the below lines to my OnInit() section, but this didn't make a difference:

RegisterForRemoteEvent (PowerSource, "OnPowerOn")
RegisterForRemoteEvent (PowerSource, "OnPowerOff")

I also tried the below after adding the RegisterForRemoteEvent lines:

Event PowerSource.OnActivate(ObjectReference PowerSource)

Any help is appreciated. Please try to walk me through your solution, as I'm new :) Script posted below:

Scriptname JMBCheckForPower extends ObjectReference

ObjectReference Property PowerSource Auto
{Power Source Device ie Generator}

ObjectReference Property DeviceToPower Auto
{Device to Turn On / Off}

Event OnInit()
	If (PowerSource.IsPowered())
		GotoState ("PowerIsOn")
	Else
		GotoState ("PowerIsOff")
	EndIf
EndEvent

State PowerIsOff
	Event OnBeginState(string asOldState)
		DeviceToPower.BlockActivation(true)
	EndEvent

	Event OnActivate(ObjectReference DeviceToPower)
		Debug.MessageBox ("The Power Source is Off")
	EndEvent
	
	Event OnPowerOn(ObjectReference PowerSource)
		GotoState ("PowerIsOn")
	EndEvent
EndState

State PowerIsOn
	Event OnBeginState(string asOldState)
		DeviceToPower.BlockActivation(false)
	EndEvent

	Event OnActivate(ObjectReference DeviceToPower)
		Debug.MessageBox ("Enjoy Your Device!")
	EndEvent
	
	Event OnPowerOff()
		GotoState ("PowerIsOff")
	EndEvent
EndState
Link to comment
Share on other sites

  • Replies 57
  • Created
  • Last Reply

Top Posters In This Topic

Ok the first issue is that you're registering for a remote event, but not providing the call back event.

 

You have the Event OnPowerOn() and OnPowerOff() but those are for local to the object, not remotes.

 

You need to use something like

Scriptname JMBCheckForPower extends ObjectReference
 
ObjectReference Property PowerSource Auto
{Power Source Device ie Generator}
 
ObjectReference Property DeviceToPower Auto
{Device to Turn On / Off}
 
Event OnInit()
    RegisterForRemoteEvent (PowerSource, "OnPowerOn")
    RegisterForRemoteEvent (PowerSource, "OnPowerOff")
 
    If (PowerSource.IsPowered())
        GotoState ("PowerIsOn")
    Else
        GotoState ("PowerIsOff")
    EndIf
EndEvent
 
State PowerIsOff
    Event OnBeginState(string asOldState)
        DeviceToPower.BlockActivation(true)
    EndEvent
 
    Event OnActivate(ObjectReference DeviceToPower)
        Debug.MessageBox ("The Power Source is Off")
    EndEvent
    
    Event ObjectReference.OnPowerOn(ObjectReference akSender, ObjectReference akPowerGenerator)
        GotoState ("PowerIsOn")
    EndEvent
EndState
 
State PowerIsOn
    Event OnBeginState(string asOldState)
        DeviceToPower.BlockActivation(false)
    EndEvent
 
    Event OnActivate(ObjectReference DeviceToPower)
        Debug.MessageBox ("Enjoy Your Device!")
    EndEvent
    
    Event ObjectReference.OnPowerOff(ObjectReference akSender)
        GotoState ("PowerIsOff")
    EndEvent
EndState
 
; Empty state placeholders may be required for remotes. I cannot remember.
Event ObjectReference.OnPowerOn(ObjectReference akSender, ObjectReference akPowerGenerator)
EndEvent
Event ObjectReference.OnPowerOff(ObjectReference akSender)
EndEvent

Remote callbacks will always have the object type then the period and Event name. Then the parameters will be the same as normal for the event with the exception that an addition first parameter will be in from as the calling source object with its type.

 

You can see more of this in the vanilla source of the FollowerScript.psc. It has 2 types being Actor and ReferenceAlias. FusionGeneratorPowerPuzzleScript.psc also has remotes for ObjectReference. Which is where I got the reminder that it may need the empty state placeholders.

Edited by BigAndFlabby
Link to comment
Share on other sites

Thank you. I'm at work now, so I'll check when I get home. One more question though, in the States sections, should

 

ObjectReference.OnPowerOn(ObjectReference akSender)

 

Be

 

ObjectReference.OnPowerOn(PowerSource akSender)

 

Or

 

PowerSource.OnPowerOn(ObjectReference akSender)

 

How does the script know which device I want to check the OnPowerOn? I can see how this might work if only the PowerSource had an OnPowerOn event, but doesn't that event apply to all ObjectReference objects?

 

Sorry for any typos, I'm on my phone :-)

Link to comment
Share on other sites

Hah as deadbeeftffn says remote events get an extra argument. Which is the object that the event is firing on. I corrected my post above as I didn't check the argument list previously.

 

So in your case you registered for the events on PowerSource. PowerSource is the object sending the event to your script remotely. So... using the definition from CK wiki as a design basis:

 

Event ObjectReference.OnPowerOn(ObjectReference akSender, ObjectReference akPowerGenerator)

 

akSender would be your "PowerSource" ObjectReference.

akPowerGenerator is the actual game ObjectReference making the power that is powering akSender.

 

To be clear. If you register for remote events on other objects for the same OnPowerOn and OnPowerOff events. The same event triggers in this script will get all of the trigger calls. So you would then need to do an if tree to check which akSender it is to deal with it. Since your original script only specified one remote registration only one object would be sending events to you.

Edited by BigAndFlabby
Link to comment
Share on other sites

Thanks for the input, deadbeeftffn .

 

BigAndFlabby, I compiled your code as is above (after your edit), and it compiled no problem. You were right, the Empty State placeholders were required (I deleted them to try it, compiler complained).

 

In game, I had the same problem as in my OP. Once the PowerSource was turned on, I went to activate the DeviceToPower (the radio), and it was still "stuck" in the PowerIsOff state.

 

Was I supposed to rename something to one of my variable names? i.e. akPowerGenerator to PowerSource? I'm also wondering if it has to do with the IF statement in the OnInit event not being formatted properly (with the remote reference), so it goes to the PowerIsOff state by default?

 

I will review the other examples you provided me and try to see what I'm missing. Wife's calling me to dinner :-).

 

Any other ideas?

Link to comment
Share on other sites

I re-wrote my If statement as below, and was still stuck in the PowerIsOff state.

    If (PowerSource.IsPowered()==false)

        GotoState ("PowerIsOff")
    Else
        GotoState ("PowerIsOn")
    EndIf

So, I tried writing my If statement "backwards", so that if the PowerSource was off, the radio would work. I got stuck in the PowerIsOn state. The only conclusion I can make is that it's not properly changing states - which would lead me back to the OnPowerOn and OnPowerOff events not working.

    If (PowerSource.IsPowered())
        GotoState ("PowerIsOff")
    Else
        GotoState ("PowerIsOn")
    EndIf

Edited by CompGuyJMB
Link to comment
Share on other sites

So I would conclude likely one of the following from what you're describing:

 

1) the object PowerSource is pointing to is in fact not powered.

2) the object PowerSource is pointing to doesn't exist. IE property isn't set correctly.

3) PowerSource isn't loaded and isn't persistent.

4) whatever you're doing to test isn't causing PowerSource to change power state.

 

Can you post the esp and source you're using so we could try ourselves. It's probably something simple but trying to think of every scenario is tough.

Link to comment
Share on other sites

PowerSource is defined to be a generator. Generators can be de/activated, though this does not change their 'isPowered' state. Only objects needing power to operate will change their 'onPower' state (DeviceToPower).

ObjectReference Property DeviceToPower Auto
{Device to Turn On / Off}

Since the script should be attached to the radio (as far as i understand), you do not need this property. Therefore you may replace all occurences of "DeviceToPower" with "Self"

 

Now the tricky part:

ObjectReference Property PowerSource Auto
{Power Source Device ie Generator}

This can't work. An ObjectReference is an object that already exists. Since generators are usually placed in workshop mode, your script can't know the reference id of this newly placed generator beforehand.

 

What you may try is to find out, if there is a generator connected to the workshop, and if yes, the radio may be activated.

WorkshopParentScript Property WorkshopParent Auto Const

import WorkshopDataScript
import CommonArrayFunctions


WorkshopScript workshopRef = WorkshopParent.GetWorkshopFromLocation(Self.GetCurrentLocation())
float power = workshopRef.GetValue(WorkshopParent.WorkshopRatings[WorkshopParent.WorkshopRatingPower].resourceValue)

if (power > 0.0)
    ; we have power in our settlement
Else
   ; no power here
endif
Edited by deadbeeftffn
Link to comment
Share on other sites

Hi deadbeeftffn,

 

Thanks again for your input. I'll be uploading my ESP tonight. But to respond, the Generator is an object I placed using the Creation Kit. It is pre-existing when the cell loads.

 

Your idea of checking for workshop power may be the ticket. The pre-existing generator is linked to the workshop via keyword. Your method will also allow the user to scrap my pre-existing generator and place their own (and not cause the script to fail because the previous generator no longer exists).

 

I'll try that before uploading my ESP.

 

Edit: For clarification, the generator is an activator. I have a toggle button enabling and disabling an enable marker, which also disables / enables the generator (and some lights). That all works OK. I have a static version of the generator in the same location so that it doesn't look weird when the generator is disabled.

Edited by CompGuyJMB
Link to comment
Share on other sites

  • Recently Browsing   0 members

    • No registered users viewing this page.

×
×
  • Create New...