Talk:Enable - ObjectReference

From the CreationKit Wiki
Jump to navigation Jump to search

Parentheses Must Be Left Blank[edit source]

"Lights will never fade. In order for an enable/disable function to work on a light, the enable() function must be left blank for the light to be enabled or disabled."

This note doesn't seem right to me. I know, from viewing the assembly files generated by the Papyrus Compiler, that calling Enable or Disable without parentheses is *identical* to calling them with the default value specified - the game literally has no way of telling the two apart because the same output is generated for both sets of Papyrus code.

Is it possible this note was added as the result of a false positive in testing? I can't test it myself at the moment but will when I get the chance if no one else has by then.

-- Cipscis (talk) 23:38, 13 September 2012 (EDT)

Nope I've tested it myself and it's a plain fact. Don't use anything between parenthesis (leave blank) when the reference is of type Light, else it won't do anything even though it compiles ok. Which doesn't mean to get rid of parenthesis btw if I read correctly, they're still mandatory...
--HawkFest (talk) 21:25, 21 November 2012 (EST)
Sorry, I misspoke when I said "without parentheses". Like you guessed, I meant "with empty parentheses". The point I made still stands, though. For example, here is an example script showing various ways in which Enable can be called on an ObjectReference variable:
ScriptName Test

ObjectReference rLight

Function Foo()
	rLight.Enable()
	rLight.Enable(true)
	rLight.Enable(false)
EndFunction
When I compile this function, here is the output (in Papyrus assembly) for the function "Foo":
        .function Foo 
          .userFlags 0
          .docString ""
          .return NONE
          .paramTable
          .endParamTable
          .localTable
            .local ::nonevar none
          .endLocalTable
          .code
            CALLMETHOD Enable rLight ::nonevar false ;@line 6
            CALLMETHOD Enable rLight ::nonevar true ;@line 7
            CALLMETHOD Enable rLight ::nonevar false ;@line 8
          .endCode
        .endFunction
As you can see, lines 6 and 8 compile to be absolutely identical - the game could not tell them apart even if it wanted to.
Would you mind elaborating on exactly how you tested this? I'm curious as to how you could have achieved that result. Unfortunately, although I usually have access to the Papyrus compiler and assembler, I don't often have the opportunity to actually test things in Skyrim.
-- Cipscis (talk) 21:34, 21 November 2012 (EST)

Sorry for the delay I don't verify these threads often... To answer your questions :

  • Lines 6 and 8 show the same "results" because providing no parameter will initialize abFadeIn to its default value which is "False", e.g. the compiler "understands" enable() and enable(False) identically. Why then do they behave differently in-game even though the compiler "throws out" the same result? Who knows, maybe some left-over from a previous fading mechanism related to the fact that the engine cannot fade light sources real time (it can only be done in the CK it seems)? Your guess... The bottom line is that we cannot fade-in fade-out light sources.
  • Note : enabling an already enabled light bulb will disable it (a bug?).
  • Example - The following script toggles on or off a light bulb object, and is triggered when the player hits an object to which the script is attached (either a trigger object, or any static having a collision mesh - some target) :

    Step 1- Put a bubl object in the render window and force its persistence by giving it a Reference Editor ID.
    Step 2- Choose a static object with collision that can get hit by the player with any weapons (or hand-to-hand) : a dummy target, a box, a wall, whatever. Then attach the following script to it (an alternative would be to use an activator such as a button or a lever, and code the OnActivate event, instead of the OnHit event as is the case below - which would also allow you to add controls to their gamebryo animations within the same code structure if need be):
    Scriptname SimpleLightBulbCollisionSwitchScript extends ObjectReference 
    ObjectReference Property LightBulbRef Auto
    
    Event OnHit(ObjectReference Aggressor, Form Source, Projectile AkProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    	If Aggressor == Game.GetPlayer()
    		If LightBulbRef.IsDisabled() ;enabling an already enabled light disables it, thus we evaluate its state as the conditional branching instead of toggling a boolean variable.
    			LightBulbRef.Enable() ;if you put a fade parameter in-between parenthesis it will never get enabled.
    		Else
    			LightBulbRef.Disable()
    		EndIf
    	EndIf
    EndEvent

    Alternative - Since enabling an enabled light Bulb disables it, one could come up with a much simpler script exploiting this glitch. Note that doing this can be dangerous, as would be any script exploiting any glitch, because a glitch has the potential to get repaired. Consequently the script itself has the potential to become flawed :

    Scriptname SimpleLightBulbCollisionSwitchScript extends ObjectReference 
    ObjectReference Property LightBulbRef Auto
    
    Event OnHit(ObjectReference Aggressor, Form Source, Projectile AkProjectile, bool abPowerAttack, bool abSneakAttack, bool abBashAttack, bool abHitBlocked)
    	If Aggressor == Game.GetPlayer()
    		LightBulbRef.Enable() ;if you put a fade parameter in-between parenthesis it will never get enabled.
    	EndIf
    EndEvent
    Last step : assign the light bulb reference from the above step 1, to the LightBulbRef property (via CK's form script tab where you've attached the script).
    TEST : In the above code, if you provide a parameter to the Enable function, e.g. LightBulbRef.Enable(True|False), then the light will not render at all, even with False as a parameter although it's the default value.

    --HawkFest (talk) 01:12, 3 December 2012 (EST)