Jump to content

[LE] Just a little help to get this simple script to work


Recommended Posts

Hi! I created an invisible activator (it's just a shack wall, not a real lever) and when the player interacts with it, he quits Skyrim and returns to desktop.

The invisible activator does have a collision, so, you can interact with it even if it has been painted with the "null texture set".

 

This is my script:

Scriptname MortarballCloseGameScript extends ObjectReference  
{EVENT onActivate (objectReference triggerRef)
            ;do nothing
        endEVENT

Function()
            ; immediately quits the game
            Debug.QuitGame()
    endFunction}

And if you're wondering why should I create a script like that, it's because I created a standalone indie game (it still requires Skyrim to work because it uses some Skyrim resources). So... There's this modern internet browser that acts like an online videogame menu, and you can close the brower by interacting with the traditional X (=close) button

When you close the browser, you close everything. Even Skyrim itself. Here's a picture from my Google Drive

 

https://drive.google.com/file/d/1OxXgjv7tvHJIkP1fxAIpEsgnpT_z0t56/view?usp=sharing

Edited by DavideMitra
Link to comment
Share on other sites

Try this:

Scriptname MortarballCloseGameScript extends ObjectReference  
; https://forums.nexusmods.com/index.php?/topic/10311913-just-a-little-help-to-get-this-simple-script-to-work/

; you can close the browser by interacting with the traditional X (=close) button

; -- EVENT --

EVENT OnActivate(ObjectReference akActionRef)
    IF (akActionRef == Game.GetPlayer() as ObjectReference)
        ; only allow "when the player interacts with it"

        Debug.QuitGame()    ; immediately quits the game

    ENDIF
ENDEVENT
Link to comment
Share on other sites

For learning purposes you had three issues:

 

#1 The entire code had been entered in the description field denoted by being wrapped in { }. This would cause papyrus to skip all of that and thus do nothing.

 

#2 The OnActivate event was correct except that it was doing nothing. You needed to either call a function that was doing the work or do the work directly in the event as in ReDragon2013's example

 

#3 The function you tried to put together was incomplete. It needed a name that could be used to call it. Example:

Function ShutDownGame()
  Debug.QuitGame()
EndFunction

In this example the function could be called using ShutDownGame(). Thus the entire script could have been:

Scriptname MortarballCloseGameScript extends ObjectReference  
Event onActivate(objectReference akActivator)
  If akActivator == Game.GetPlayer()
    ShutDownGame()
  EndIf
EndEvent

Function ShutDownGame()
  Debug.QuitGame()
EndFunction

However, unless you need to access that function in other events it is probably best to use the single event as in ReDragon2013's example.

Link to comment
Share on other sites

 

Simple as it gets

 

Event OnActivate(ObjectReference akActionRef)
   akActionRef.GetFormID() == 0x14 && Debug.QuitGame()
EndEvent

You cannot use == and/or && without being part of a conditional statement such as an IF or a While

Also GetFormID returns an integer which cannot be compared directly to a hexadecimal number.

 

The "simple as it gets" example would be ReDragon2013's suggested code posted earlier.

Link to comment
Share on other sites

OP asked for simple and sure, I realize folks likely are not aware you can chain bools to functions in a single line so figured I'd share, Been down this road before of seeing people diss a method because they werent aware of ii. Hey... coolz. Do you. But know sometimes you should verify something before assuming

Link to comment
Share on other sites

Sphered wrote: "Been down this road before of seeing people diss a method"

 

The following script code should explain, does it works and what is the different in both methods of player condition. I use a state to show the different in the same script.

Keep in mind 0x14 (or 20 decimal) is the vanilla formID of the player actor.

 

TestScript

 

Scriptname testScript extends ObjectReference

Event OnActivate(ObjectReference akActionRef)  ; Sphered method
   akActionRef.GetFormID() == 0x14 && Debug.QuitGame()
EndEvent


;========================
state Waiting
;============
    Event OnActivate(ObjectReference akActionRef)  ; normal method used in papyrus scripts
        IF (akActionRef == Game.GetPlayer() as ObjectReference)
            Debug.QuitGame()
        ENDIF
    EndEvent
;=======
endState

 

 

 

(1) How does the according pas-file is looking?

 

 

.objectTable
  .object testScript ObjectReference
    .userFlags 0
    .docString ""
    .autoState
    .variableTable
    .endVariableTable
    .propertyTable
    .endPropertyTable
    .stateTable

.state
        .function GetState
          .userFlags 0
          .docString "Function that returns the current state"
          .return String
          .paramTable
          .endParamTable
          .localTable
          .endLocalTable
          .code
            RETURN ::state
          .endCode
        .endFunction
        .function GotoState
          .userFlags 0
          .docString "Function that switches this object to the specified state"
          .return None
          .paramTable
            .param newState String
          .endParamTable
          .localTable
            .local ::NoneVar None
          .endLocalTable
          .code
            CALLMETHOD onEndState self ::NoneVar
            ASSIGN ::state newState
            CALLMETHOD onBeginState self ::NoneVar
          .endCode
        .endFunction

        .function OnActivate
          .userFlags 0
          .docString ""
          .return NONE
          .paramTable
            .param akActionRef ObjectReference
          .endParamTable
          .localTable
            .local ::temp0 int
            .local ::temp1 bool
            .local ::nonevar none
          .endLocalTable
          .code
            CALLMETHOD GetFormID akActionRef ::temp0  ;@line 4
            COMPAREEQ ::temp1 ::temp0 20 ;@line 4
            CAST ::temp1 ::temp1 ;@line 4
            JUMPF ::temp1 label0 ;@line 4
            CALLSTATIC debug QuitGame ::nonevar  ;@line 4
            CAST ::temp1 ::nonevar ;@line 4
            label0:
          .endCode
        .endFunction
.endState
      
.state waiting
        .function OnActivate
          .userFlags 0
          .docString ""
          .return NONE
          .paramTable
            .param akActionRef ObjectReference
          .endParamTable
          .localTable
            .local ::temp2 actor
            .local ::temp3 objectreference
            .local ::temp4 bool
            .local ::nonevar none
          .endLocalTable
          .code
            CALLSTATIC game GetPlayer ::temp2  ;@line 12
            CAST ::temp3 ::temp2 ;@line 12
            COMPAREEQ ::temp4 akActionRef ::temp3 ;@line 12
            JUMPF ::temp4 label2 ;@line 12
            CALLSTATIC debug QuitGame ::nonevar  ;@line 13
            JUMP label1
            label2:
            label1:
          .endCode
        .endFunction
.endState

    .endStateTable
  .endObject
.endObjectTable

 

 

 

(3) What can we see?

 

Both versions are working and make a reliable papyrus condition at runtime. First method is a bit C++ style and not so intuitive in understanding.

But I made some testings in the past and in my experience the following method

akActionRef.GetFormID() == 0x14

is not threading safe in Skyrims papyrus engine. That is my opinion to Sphered coding alternative.

Edited by ReDragon2013
Link to comment
Share on other sites

  • Recently Browsing   0 members

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