How are spotlights defined for use?

Ask about editing graphics, sounds, models, music, etc here!
Shaders (GLSL) and SNDINFO questions also go here!

Moderators: GZDoom Developers, Raze Developers

Forum rules
Before asking on how to use a ZDoom feature, read the ZDoom wiki first. If you still don't understand how to use a feature, then ask here.
Post Reply
User avatar
crowbars82
Posts: 40
Joined: Sun Nov 05, 2017 6:22 pm
Contact:

How are spotlights defined for use?

Post by crowbars82 »

Hi everyone!

Can spotlights be defined similarly to the other dynamic lights?

For example a light that I have made to illuminate an actor when it fires their gun is:

Code: Select all

pointlight CROWENEMYFIRE
{
    color 1.00 0.50 0.25
    size 30
    offset 0 32 0
}
... which then I can attach to the animation frame like this:

Code: Select all

	Missile:
		RTLG E 8 A_FaceTarget
		RTLG F 8 
		RTLG G 8 Light("CROWENEMYFIRE") A_PosAttack
		RTLG H 8
		goto See
I am attempting to create a simple spotlight that will emit from a static actor's facing direction and simply point towards whatever is in front of it.

Can a spotlight be created like the other lights in GLDEFS?

I have downloaded and extracted Steve's Flashlight Mod which I can see that the spotlight has been defined within the ZSCRIPT.txt, and I can identify how the spotlight is being attached to the player, however I am uncertain how to proceed for creating a standalone spotlight without using ZScript unless this is impossible at this stage?

Many thanks!
~Crow

Steve's Flashlight Mod ZSCRIPT.txt contents:

Code: Select all

version "3.3"


class Util {

    play static void setupFlashlight (int playerID, int flashID) {
        
        PlayerPawn act = PlayerPawn(ActorIterator.Create(playerID).Next());
        
        if (act) {
        
            ActorHeadLight light = ActorHeadLight(Actor.Spawn("ActorHeadLight"));
        
            light.ChangeTid(flashID);

            light.toFollow = act;
           
            light.activate(null);
            
            Util.LogDebug("Light created and 'attached'");
            
        }
    
    }
    
    static void LogDebug (String text) {
    
        if (CVar.GetCvar("debug")) {        
            Console.printf("[ZScript]  "..text);
        }
    
    }
    
    static int round (double num) {
    
        int result = (num - floor(num) > 0.5) ? ceil(num) : floor(num);
        return result;
    
    }
    

}

class ActorHeadLight : Spotlight {

    enum ELocation
	{
		HELMET = 0,
		RIGHT_SHOULDER = 1,
		LEFT_SHOULDER = 2,
        CAMERA = 3
	};

    PlayerPawn toFollow;

    Vector3 offset;
    
    Vector3 finalOffset;
    
    double zBump; // z offset for locations that are not CAMERA
    
    double angleDiff;    
    double turnAnglePerTic;
    bool ready;
    bool on;
    
    ELocation location;
    
    void updateFromCvars () {
    
        Color c = CVar.FindCVar("flashlight_color").GetString();
    
        args[0] = c.r;
        args[1] = c.g;
        args[2] = c.b;    
        args[3] = CVar.FindCVar("flashlight_intensity").GetInt();
        
        self.SpotInnerAngle = CVar.FindCVar("flashlight_inner").GetFloat();        
        self.SpotOuterAngle = CVar.FindCVar("flashlight_outer").GetFloat();
        
        self.location = CVar.FindCVar("flashlight_location").GetInt();       
       
        
        Util.LogDebug("Light loc offset: "..self.offset);
        
        
                      
    }
    
    
    override void Activate(Actor activator) {
        
        updateFromCvars();
        on = true;
        super.Activate(activator);        

    }
    
    
    override void DeActivate(Actor activator) {
    
        on = false;
        super.DeActivate(activator);
    
    }
        
    
    override void Tick() {
    
        if (ready && on) {

            switch (location) {
            
                case HELMET:
                    offset = (0, 0, toFollow.player.viewheight + zBump);
                    break;
                    
                case RIGHT_SHOULDER:
                    offset = (toFollow.radius, 0, toFollow.player.viewheight + zBump);
                    break;
                    
                case LEFT_SHOULDER:
                    offset = (toFollow.radius * -1, 0, toFollow.player.viewheight + zBump);
                    break;
                    
                case CAMERA:
                    offset = (0, 0, toFollow.ViewHeight);
                    break;
                    
                default:
                    offset = (0, 0, 0);
            
            }
                         
            A_SetAngle(toFollow.angle, 0);
            
            Vector2 finalOffset2D = RotateVector ((offset.x, offset.y), toFollow.angle - 90.0); 
                        
            finalOffset = (finalOffset2D.x, finalOffset2D.y, offset.z);
            
            A_SetPitch(toFollow.pitch, SPF_INTERPOLATE);
            
            SetOrigin(self.toFollow.pos + finalOffset, true);
    
        } else if (on && self.toFollow) {

            ready = true;
            
            zBump = (toFollow.height - toFollow.viewheight) / 2;
            
            Util.LogDebug('zBump assigned: '..zBump);
        
        }
        
        Super.Tick();    
             
    }
    
}
User avatar
crowbars82
Posts: 40
Joined: Sun Nov 05, 2017 6:22 pm
Contact:

Re: How are spotlights defined for use?

Post by crowbars82 »

Follow up on an attempt with spotlights:

So I've managed to create a spotlight by editing the ZSCRIPT file and adding the following code (of which I bumbled together using code from "FlashLight.pk3" that I found in some forum somewhere...)

Code: Select all

Class TestingSL : SpotLight
{
	uint8 Red;
	uint8 Green;
	uint8 Blue;
	
	uint16 SpotInnerAngle;
	uint16 SpotOuterAngle;
	
	Property Red:Red;
	Property Green:Green;
	Property Blue:Blue;
	
	Property SpotInnerAngle:SpotInnerAngle;
	Property SpotOuterAngle:SpotOuterAngle;
	
	Default
	{
		TestingSL.Red 220;
		TestingSL.Green 220;
		TestingSL.Blue 220;
		TestingSL.SpotInnerAngle 200;
		TestingSL.SpotOuterAngle 200;		
	}
	
	override void Tick(void)
	{
		args[0] = Red;
		args[1] = Green;
		args[2] = Blue;
		args[3] = SpotInnerAngle;
		args[4] = SpotOuterAngle;
		Super.Tick();
	}
	
	States
	{
	Spawn:
		CRLT A 3;
		CRLT A 3;
		Loop;
	}
}
This all makes a spotlight originate from the actor "TestingSL" and the RGB (arguments 0-2) work, but the args[3] seems to want to control the "distance" of the light.

Not really sure how to define the Inner and Outer angles as yet... but getting there maybe?
User avatar
Caligari87
Admin
Posts: 6174
Joined: Thu Feb 26, 2004 3:02 pm
Preferred Pronouns: He/Him
Contact:

Re: How are spotlights defined for use?

Post by Caligari87 »

When defining in zscript it's better to use the constant references and properties directly:

Code: Select all

args[LIGHT_RED] = Red;
args[LIGHT_GREEN] = Green;
args[LIGHT_BLUE] = Blue;
args[LIGHT_INTENSITY] = Intensity;
SpotInnerAngle = InnerAngle;
SpotOuterAngle = OuterAngle;
8-)
User avatar
crowbars82
Posts: 40
Joined: Sun Nov 05, 2017 6:22 pm
Contact:

Re: How are spotlights defined for use?

Post by crowbars82 »

Caligari87 wrote:When defining in zscript it's better to use the constant references and properties directly:

Code: Select all

args[LIGHT_RED] = Red;
args[LIGHT_GREEN] = Green;
args[LIGHT_BLUE] = Blue;
args[LIGHT_INTENSITY] = Intensity;
SpotInnerAngle = InnerAngle;
SpotOuterAngle = OuterAngle;
8-)
Thanks for getting back on this, I have managed to get something working!

I've a main "sun" actor which is generated into maps facing a certain direction, which spawns another actor ("SunInit") which has the properties +NOGRAVITY and +NOINTERACTION, which then SunInit calls a spawn for the following ZScript defined actor:

Code: Select all

Class TestingSL : Spotlight
{
	override void PostBeginPlay()
	{
		args[LIGHT_RED] = 100;
		args[LIGHT_GREEN] = 100;
		args[LIGHT_BLUE] = 100;
		args[LIGHT_INTENSITY] = 400;
		SpotInnerAngle = 40;
		SpotOuterAngle = 40;
		Super.PostBeginPlay();
	}
	
	Default
	{
		+NOINTERACTION
		+NOGRAVITY
	}
	
	States
	{
	Spawn:
		CRLT B 1;
		CRLT B -1;
		Stop;
	}
}
I couldn't get the "TestingSL : Spotlight" actor to stop falling down with gravity, but this weird work-around was the best I could come up with.

It seems like the Spotlight inherits the properties of the actor that spawns it even though I've told it to use the same flags in the "Default" section, however I don't fully understand what the top section is doing other than allowing the spotlight args to be defined, but I don't understand "override void PostBeginPlay()" or "Super.PostBeginPlay();" yet.

I'll have a further play with this, but you helped point me in the right direction, so much thanks!! :D
Post Reply

Return to “Assets (and other stuff)”