How are spotlights defined for use?

Ask about editing graphics, sounds, models, music, etc here!
Shaders (GLSL) and SNDINFO questions also go here!
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.

How are spotlights defined for use?

Postby crowbars82 » Sat Jan 19, 2019 11:42 am

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 allExpand view
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 allExpand view
   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 allExpand view
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
 
Joined: 05 Nov 2017

Re: How are spotlights defined for use?

Postby crowbars82 » Wed Feb 13, 2019 4:57 pm

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 allExpand view
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
crowbars82
 
Joined: 05 Nov 2017

Re: How are spotlights defined for use?

Postby Caligari87 » Wed Feb 13, 2019 6:44 pm

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

Code: Select allExpand view
args[LIGHT_RED] = Red;
args[LIGHT_GREEN] = Green;
args[LIGHT_BLUE] = Blue;
args[LIGHT_INTENSITY] = Intensity;
SpotInnerAngle = InnerAngle;
SpotOuterAngle = OuterAngle;


8-)
User avatar
Caligari87
I'm just here for the community
User Accounts Assistant
 
Joined: 26 Feb 2004
Location: Salt Lake City, Utah, USA
Discord: Caligari87#3089

Re: How are spotlights defined for use?

Postby crowbars82 » Mon Feb 18, 2019 4:43 pm

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

Code: Select allExpand view
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 allExpand view
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
User avatar
crowbars82
 
Joined: 05 Nov 2017


Return to Assets (and other stuff)

Who is online

Users browsing this forum: No registered users and 0 guests