/** * Abstract Light * * Copyright 1998-2013 Epic Games, Inc. All Rights Reserved. */ class Light extends Actor native(Light) ClassGroup( Lights ); var() editconst const LightComponent LightComponent; `if(`__TW_LIGHTING_MODIFICATIONS_) // Light Animation /** Supported light animation types */ enum ELightAnimationTechnique { /** No Animation */ LightAnim_None, /** Random on/off */ LightAnim_Flicker, /** Interpolate smoothly between on/off */ LightAnim_Pulse, /** Like flicker, but the pattern is constant and repeating */ LightAnim_Strobe, /** Light remains off mostly except when it flickers on */ LightAnim_ChaoticFlicker, /** Light remains on mostly except when it flickers off */ LightAnim_InverseChaoticFlicker }; /** The maximum brightness value for this light. Default is 1.0 */ var(LightAnimation) const float MaxBrightness; /** The minimum brightness override value for this light. If 0, it uses the global value for the light animation type specified in WorldInfo. */ var(LightAnimation) const float MinBrightness; /** Light animation type used by this light */ var(LightAnimation) ELightAnimationTechnique AnimationType; /** The rate at which the LightAnimation is played. Default is 1.0. Must be greater than 0 */ var(LightAnimation) float AnimationFrequency; /** Time offset into the LightAnimation. This is used to add variation so that all the animations are not in perfect sync. default is 0.0. Note: This value will not have any effect it is a multiple of the inverse of the AnimationFrequency. Eg. If the AnimationFrequency is 0.5, AnimationTimeOffsets of 2, 4, 6 ... will have same effect at 0 */ var(LightAnimation) float AnimationTimeOffset; /** The static mesh represtation of the light fixture */ var(LightAnimation) StaticMeshComponent LightMesh; /** The MICs used by the light fixture that need modification */ var transient array LightMeshMICs; /** The MICs used by the base mesh (actor we're standing on) that need modification */ var transient array BaseMeshMICs; /** Lens flare component for the light */ var(LightAnimation) LensFlareComponent LensFlareComp; /** The MICs used by the lens flare that need modification */ var transient array LensFlareMICs; /** Animation output from previous frame */ var transient float CurveOutputValue; `endif // Light Animation cpptext { public: // AActor interface. /** * Function that gets called from within Map_Check to allow this actor to check itself * for any potential errors and register them with map check dialog. */ #if WITH_EDITOR virtual void CheckForErrors(); #endif /** * This will determine which icon should be displayed for this light. **/ virtual void DetermineAndSetEditorIcon(); /** * For this type of light, set the values which would make it affect Dynamic Primitives. **/ virtual void SetValuesForLight_DynamicAffecting(); /** * For this type of light, set the values which would make it affect Static Primitives. **/ virtual void SetValuesForLight_StaticAffecting(); /** * For this type of light, set the values which would make it affect Dynamic and Static Primitives. **/ virtual void SetValuesForLight_DynamicAndStaticAffecting(); /** * Returns true if the light supports being toggled off and on on-the-fly * * @return For 'toggleable' lights, returns true */ virtual UBOOL IsToggleable() const { // By default, lights are not toggleable. You can override this in derived classes. return FALSE; } /** Invalidates lighting for a lighting rebuild. */ void InvalidateLightingForRebuild(UBOOL bOnlyVisible = FALSE); #if __TW_LIGHTING_MODIFICATIONS_ // Light Animation /** ticks the light * @return TRUE if the actor was ticked, FALSE if it was aborted (e.g. because it's in stasis) */ virtual UBOOL Tick(FLOAT DeltaTime, enum ELevelTick TickType); /** Returns the material parameter value when synching with this light */ FLOAT GetLightMICParamValue(); virtual void PostLoad(); /** Process change of property value for the light */ virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent); #endif } /** replicated copy of LightComponent's bEnabled property */ var repnotify bool bEnabled; replication { if (Role == ROLE_Authority) bEnabled; } `if(`__TW_LIGHTING_MODIFICATIONS_) /** @return whether light volumetrics is supported */ native static final function bool IsVolumetricLightingSupported(); /** @return whether light functions are supported */ native static final function bool AreLightFunctionsSupported(); `endif simulated event ReplicatedEvent(name VarName) { if (VarName == 'bEnabled') { LightComponent.SetEnabled(bEnabled); `if(`__TW_LIGHTING_MODIFICATIONS_) // Update the state of the lens flare component attached to the light LensFlareComp.SetIsActive(bEnabled); LensFlareComp.LastRenderTime = WorldInfo.TimeSeconds; `endif } else { Super.ReplicatedEvent(VarName); } } /* epic =============================================== * ::OnToggle * * Scripted support for toggling a light, checks which * operation to perform by looking at the action input. * * Input 1: turn on * Input 2: turn off * Input 3: toggle * * ===================================================== */ simulated function OnToggle(SeqAct_Toggle action) { if (!bStatic) { if (action.InputLinks[0].bHasImpulse) { // turn on LightComponent.SetEnabled(TRUE); `if(`__TW_LIGHTING_MODIFICATIONS_) LensFlareComp.SetIsActive(TRUE); `endif } else if (action.InputLinks[1].bHasImpulse) { // turn off LightComponent.SetEnabled(FALSE); `if(`__TW_LIGHTING_MODIFICATIONS_) LensFlareComp.SetIsActive(FALSE); `endif } else if (action.InputLinks[2].bHasImpulse) { // toggle LightComponent.SetEnabled(!LightComponent.bEnabled); `if(`__TW_LIGHTING_MODIFICATIONS_) LensFlareComp.SetIsActive(LightComponent.bEnabled); `endif } bEnabled = LightComponent.bEnabled; ForceNetRelevant(); SetForcedInitialReplicatedProperty(Property'Engine.Light.bEnabled', (bEnabled == default.bEnabled)); `if(`__TW_LIGHTING_MODIFICATIONS_) LensFlareComp.LastRenderTime = WorldInfo.TimeSeconds; `endif } } `if(`__TW_LIGHTING_MODIFICATIONS_) // Light Animation /** returns true if the light mesh is a volumetric light cone */ native function bool HasVolumetricLightMesh(); event PostBeginPlay() { local int i; local MaterialInterface ParentMat; local MaterialInstanceConstant NewMIC; local float DummyValue; local bool bVolumetricLightMesh; if (WorldInfo.NetMode == NM_DedicatedServer) { SetTickIsDisabled(true); return; } // Disable and destroy light if the light has a light function // and light functions are not supported if( !AreLightFunctionsSupported() && LightComponent.Function != none ) { // disable tick must come first to ensure component reattach SetTickIsDisabled(true); LightComponent.SetEnabled(false); return; } // Check to see if the light mesh attached is a volumetric light cone mesh // All the materials used by the light mesh need to be translucent for it to // be considered as a volumetric light mesh if( LightMesh != none ) { bVolumetricLightMesh = HasVolumetricLightMesh(); } if( !bVolumetricLightMesh || IsVolumetricLightingSupported() ) { // Create and cache the MICs that need modification (for the static mesh attachment) LightMeshMICs.Remove(0, LightMeshMICs.length); if( LightMesh != none ) { for( i=0; i