How do I add "dynamic" light to an actor?

Ask about ACS, DECORATE, ZScript, or any other scripting questions here!

Moderator: GZDoom 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.

How do I add "dynamic" light to an actor?

Postby Graaicko » Mon Jan 11, 2021 1:17 pm

So, I'm back at it working hard on my first mod. I have added ALOT of destructable objects in. One thing is lights, weither they are desk lights or ceiling lights. I have made most of them destructable to give you that splinter cell feel. My question is, how do I add dynamic lights to these actors? Also Might aswell ask how this as it falls in the same subject (I think). How could I apply this effect to the player and enemies when their weapons are fired?
User avatar
Graaicko
I don't do requests. Working on Shadow Elite. I miss Windows 7. :(
 
Joined: 18 Jun 2014
Location: Somewhere, somehow.
Discord: private
Twitch ID: lol why?
Github ID: gitgud, pleb
Operating System: Windows 10/8.1/8/201x 64-bit
Graphics Processor: nVidia (Legacy GZDoom)

Re: How do I add "dynamic" light to an actor?

Postby Cherno » Mon Jan 11, 2021 1:33 pm

In DECORATE, you are limited to A_AttachLightDef.
In the actor's Spawn state, you simply call something like

Code: Select allExpand view
A_AttachLightDef("light","Lightprop1Light");


for a light prop. In GLDEFS, you define the dynamic light, like this:

Code: Select allExpand view
pointlight Lightprop1Light
{
    color 1.0 0.94 0.0
    size 192
    offset 0 60 0//The offset for the light in map units.
   //This is relative to a thing's sprite, not the world, so the Y axis is height and the Z axis is depth. Defaults to 0,0,0.
   dontlightself 1
   attenuate 1// Attenuated lights illuminate surfaces depending on surface angle — surfaces that are not facing the light will get progressively less illuminated.

}


EDIT: You can also use the Light("lightname") keyword with an actor frame, which works the same way as A_AttachLightDef, but automatically removes the light after the frame's duration.

If at all possible, do not use this method, because the offsets will only work properly for the z (up-down) axis, meaning that you won't be able to have your lights be offset on the xy axis and turn along with the actor; here, the xy offsets are in world space. To make this more clear: When you set an x offset of 32, the light will always be 32 units to the "East" of the map, no matter which direction the actor is facing.

This means going the ZScript route, which has the added benefit that you can use randomization as much as you like (note that you can of course use the DECORATE method in ZScript as well, but it will have the same limits).

A_AttachLight.

For a muzzleflash light, you call something like

Code: Select allExpand view
A_AttachLight
      (
         "mflight",//Name lightid
         DynamicLight.PointLight,//int type
         "fff8bd",//Color lightcolor
         frandom(56,64),//int radius1
         0,//int radius2
         DYNAMICLIGHT.LF_ATTENUATE|DYNAMICLIGHT.LF_DONTLIGHTSELF|DYNAMICLIGHT.LF_ATTENUATE|DYNAMICLIGHT.LF_ADDITIVE,//int flags
         (16,0,height * 0.6)//Vector3 ofs
      );


when the actor fires. With A_AttachLight, no GLDEFS entry is neccessary. Note the randomized radius and offset which will turn with the actor. The x offset is 16 so the light is offset 16 units to the front of the actor, approximately where the muzzle of a rifle would be. This will always be towards the actor's front since it follows the actor's angle.

In both cases (A_AttachLightDef and A_AttachLight), it is neccessary to call A_RemoveLight when the light should be removed, otherwise it will stay with the actor.

Code: Select allExpand view
A_RemoveLight("mflight")


The lightid parameter values can be freely chosen by you. Just remember to use the same for both attaching and removing lights.

So typically, for a monster or weapon, you would call A_AttachLight when firing, and then after about two tics call A_RemoveLight. It it also a good idea to call A_RemoveLight at the start of the Pain and Death states to make sure a light is properly removed when a monster enteres it's Pain state, or killed, between attaching the light and removing it after firing. If a prop can be destroyed so the light should turn off, the same principle applies.

Thanks to Ash for bringing up the possibilities of A_AttachLight :oops:
Last edited by Cherno on Fri Jan 15, 2021 8:27 pm, edited 1 time in total.
User avatar
Cherno
 
Joined: 06 Dec 2016

Re: How do I add "dynamic" light to an actor?

Postby inkoalawetrust » Tue Jan 12, 2021 6:32 pm

There is also the Light keyword which you can use, it does about the same thing as A_AttachLightDef but only lasts for the duration of the frame and sub-frames* its' called on. You can use it like how you use keywords such Bright, so instead of this:

Code: Select allExpand view
SPRT ABCBA 16 Bright A_AttachlightDef ("lightname","gldefslightname");


You can just do this:

Code: Select allExpand view
SPRT ABCBA 16 Bright Light ("gldefslightname");


The latter will only last for the duration of that line/frame/whatever you want to call it before being removed.

*For example if SPRT is the frame, then the letters after it are the sub-frames.
User avatar
inkoalawetrust
 
Joined: 26 Aug 2019
Discord: inkoalawetrust #9783
Operating System: Windows Vista/7/2008 32-bit
OS Test Version: No (Using Stable Public Version)
Graphics Processor: Intel (Legacy GZDoom)


Return to Scripting

Who is online

Users browsing this forum: No registered users and 0 guests