Update the discussion of themeing in the manual, and put a note in the wps tags appen...
[kugel-rb.git] / apps / plugins / doom / p_lights.c
blob44d151b7b5a5130bc0ba8ff6cb9229a9a0e8e9b3
1 /* Emacs style mode select -*- C++ -*-
2 *-----------------------------------------------------------------------------
5 * PrBoom a Doom port merged with LxDoom and LSDLDoom
6 * based on BOOM, a modified and improved DOOM engine
7 * Copyright (C) 1999 by
8 * id Software, Chi Hoang, Lee Killough, Jim Flynn, Rand Phares, Ty Halderman
9 * Copyright (C) 1999-2000 by
10 * Jess Haas, Nicolas Kalkhof, Colin Phipps, Florian Schulze
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
25 * 02111-1307, USA.
27 * DESCRIPTION:
28 * Action routines for lighting thinkers
29 * Spawn sector based lighting effects.
30 * Handle lighting linedef types
32 *-----------------------------------------------------------------------------*/
34 #include "doomstat.h" //jff 5/18/98
35 #include "doomdef.h"
36 #include "m_random.h"
37 #include "r_main.h"
38 #include "p_spec.h"
39 #include "p_tick.h"
41 //////////////////////////////////////////////////////////
43 // Lighting action routines, called once per tick
45 //////////////////////////////////////////////////////////
48 // T_FireFlicker()
50 // Firelight flicker action routine, called once per tick
52 // Passed a fireflicker_t structure containing light levels and timing
53 // Returns nothing
55 void T_FireFlicker (fireflicker_t* flick)
57 int amount;
59 if (--flick->count)
60 return;
62 amount = (P_Random(pr_lights)&3)*16;
64 if (flick->sector->lightlevel - amount < flick->minlight)
65 flick->sector->lightlevel = flick->minlight;
66 else
67 flick->sector->lightlevel = flick->maxlight - amount;
69 flick->count = 4;
73 // T_LightFlash()
75 // Broken light flashing action routine, called once per tick
77 // Passed a lightflash_t structure containing light levels and timing
78 // Returns nothing
80 void T_LightFlash (lightflash_t* flash)
82 if (--flash->count)
83 return;
85 if (flash->sector->lightlevel == flash->maxlight)
87 flash-> sector->lightlevel = flash->minlight;
88 flash->count = (P_Random(pr_lights)&flash->mintime)+1;
90 else
92 flash-> sector->lightlevel = flash->maxlight;
93 flash->count = (P_Random(pr_lights)&flash->maxtime)+1;
99 // T_StrobeFlash()
101 // Strobe light flashing action routine, called once per tick
103 // Passed a strobe_t structure containing light levels and timing
104 // Returns nothing
106 void T_StrobeFlash (strobe_t* flash)
108 if (--flash->count)
109 return;
111 if (flash->sector->lightlevel == flash->minlight)
113 flash-> sector->lightlevel = flash->maxlight;
114 flash->count = flash->brighttime;
116 else
118 flash-> sector->lightlevel = flash->minlight;
119 flash->count =flash->darktime;
124 // T_Glow()
126 // Glowing light action routine, called once per tick
128 // Passed a glow_t structure containing light levels and timing
129 // Returns nothing
132 void T_Glow(glow_t* g)
134 switch(g->direction)
136 case -1:
137 // light dims
138 g->sector->lightlevel -= GLOWSPEED;
139 if (g->sector->lightlevel <= g->minlight)
141 g->sector->lightlevel += GLOWSPEED;
142 g->direction = 1;
144 break;
146 case 1:
147 // light brightens
148 g->sector->lightlevel += GLOWSPEED;
149 if (g->sector->lightlevel >= g->maxlight)
151 g->sector->lightlevel -= GLOWSPEED;
152 g->direction = -1;
154 break;
158 //////////////////////////////////////////////////////////
160 // Sector lighting type spawners
162 // After the map has been loaded, each sector is scanned
163 // for specials that spawn thinkers
165 //////////////////////////////////////////////////////////
168 // P_SpawnFireFlicker()
170 // Spawns a fire flicker lighting thinker
172 // Passed the sector that spawned the thinker
173 // Returns nothing
175 void P_SpawnFireFlicker (sector_t* sector)
177 fireflicker_t* flick;
179 // Note that we are resetting sector attributes.
180 // Nothing special about it during gameplay.
181 sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
183 flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0);
185 P_AddThinker (&flick->thinker);
187 flick->thinker.function = T_FireFlicker;
188 flick->sector = sector;
189 flick->maxlight = sector->lightlevel;
190 flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16;
191 flick->count = 4;
195 // P_SpawnLightFlash()
197 // Spawns a broken light flash lighting thinker
199 // Passed the sector that spawned the thinker
200 // Returns nothing
202 void P_SpawnLightFlash (sector_t* sector)
204 lightflash_t* flash;
206 // nothing special about it during gameplay
207 sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
209 flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
211 P_AddThinker (&flash->thinker);
213 flash->thinker.function = T_LightFlash;
214 flash->sector = sector;
215 flash->maxlight = sector->lightlevel;
217 flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
218 flash->maxtime = 64;
219 flash->mintime = 7;
220 flash->count = (P_Random(pr_lights)&flash->maxtime)+1;
224 // P_SpawnStrobeFlash
226 // Spawns a blinking light thinker
228 // Passed the sector that spawned the thinker, speed of blinking
229 // and whether blinking is to by syncrhonous with other sectors
231 // Returns nothing
233 void P_SpawnStrobeFlash
234 ( sector_t* sector,
235 int fastOrSlow,
236 int inSync )
238 strobe_t* flash;
240 flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
242 P_AddThinker (&flash->thinker);
244 flash->sector = sector;
245 flash->darktime = fastOrSlow;
246 flash->brighttime = STROBEBRIGHT;
247 flash->thinker.function = T_StrobeFlash;
248 flash->maxlight = sector->lightlevel;
249 flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);
251 if (flash->minlight == flash->maxlight)
252 flash->minlight = 0;
254 // nothing special about it during gameplay
255 sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
257 if (!inSync)
258 flash->count = (P_Random(pr_lights)&7)+1;
259 else
260 flash->count = 1;
264 // P_SpawnGlowingLight()
266 // Spawns a glowing light (smooth oscillation from min to max) thinker
268 // Passed the sector that spawned the thinker
269 // Returns nothing
271 void P_SpawnGlowingLight(sector_t* sector)
273 glow_t* g;
275 g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0);
277 P_AddThinker(&g->thinker);
279 g->sector = sector;
280 g->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
281 g->maxlight = sector->lightlevel;
282 g->thinker.function = T_Glow;
283 g->direction = -1;
285 sector->special &= ~31; //jff 3/14/98 clear non-generalized sector type
288 //////////////////////////////////////////////////////////
290 // Linedef lighting function handlers
292 //////////////////////////////////////////////////////////
295 // EV_StartLightStrobing()
297 // Start strobing lights (usually from a trigger)
299 // Passed the line that activated the strobing
300 // Returns true
302 // jff 2/12/98 added int return value, fixed return
304 int EV_StartLightStrobing(line_t* line)
306 int secnum;
307 sector_t* sec;
309 secnum = -1;
310 // start lights strobing in all sectors tagged same as line
311 while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
313 sec = &sectors[secnum];
314 // if already doing a lighting function, don't start a second
315 if (P_SectorActive(lighting_special,sec)) //jff 2/22/98
316 continue;
318 P_SpawnStrobeFlash (sec,SLOWDARK, 0);
320 return 1;
324 // EV_TurnTagLightsOff()
326 // Turn line's tagged sector's lights to min adjacent neighbor level
328 // Passed the line that activated the lights being turned off
329 // Returns true
331 // jff 2/12/98 added int return value, fixed return
333 int EV_TurnTagLightsOff(line_t* line)
335 int j;
337 // search sectors for those with same tag as activating line
339 // killough 10/98: replaced inefficient search with fast search
340 for (j = -1; (j = P_FindSectorFromLineTag(line,j)) >= 0;)
342 sector_t *sector = sectors + j, *tsec;
343 int i, min = sector->lightlevel;
344 // find min neighbor light level
345 for (i = 0;i < sector->linecount; i++)
346 if ((tsec = getNextSector(sector->lines[i], sector)) &&
347 tsec->lightlevel < min)
348 min = tsec->lightlevel;
349 sector->lightlevel = min;
351 return 1;
355 // EV_LightTurnOn()
357 // Turn sectors tagged to line lights on to specified or max neighbor level
359 // Passed the activating line, and a level to set the light to
360 // If level passed is 0, the maximum neighbor lighting is used
361 // Returns true
363 // jff 2/12/98 added int return value, fixed return
365 int EV_LightTurnOn(line_t *line, int bright)
367 int i;
369 // search all sectors for ones with same tag as activating line
371 // killough 10/98: replace inefficient search with fast search
372 for (i = -1; (i = P_FindSectorFromLineTag(line,i)) >= 0;)
374 sector_t *temp, *sector = sectors+i;
375 int j, tbright = bright; //jff 5/17/98 search for maximum PER sector
377 // bright = 0 means to search for highest light level surrounding sector
379 if (!bright)
380 for (j = 0;j < sector->linecount; j++)
381 if ((temp = getNextSector(sector->lines[j],sector)) &&
382 temp->lightlevel > tbright)
383 tbright = temp->lightlevel;
385 sector->lightlevel = tbright;
387 //jff 5/17/98 unless compatibility optioned
388 //then maximum near ANY tagged sector
389 if (comp[comp_model])
390 bright = tbright;
392 return 1;
395 /* killough 10/98:
397 * EV_LightTurnOnPartway()
399 * Turn sectors tagged to line lights on to specified or max neighbor level
401 * Passed the activating line, and a light level fraction between 0 and 1.
402 * Sets the light to min on 0, max on 1, and interpolates in-between.
403 * Used for doors with gradual lighting effects.
405 * Returns true
408 int EV_LightTurnOnPartway(line_t *line, fixed_t level)
410 int i;
412 if (level < 0) // clip at extremes
413 level = 0;
414 if (level > FRACUNIT)
415 level = FRACUNIT;
417 // search all sectors for ones with same tag as activating line
418 for (i = -1; (i = P_FindSectorFromLineTag(line,i)) >= 0;)
420 sector_t *temp, *sector = sectors+i;
421 int j, bright = 0, min = sector->lightlevel;
423 for (j = 0; j < sector->linecount; j++)
424 if ((temp = getNextSector(sector->lines[j],sector)))
426 if (temp->lightlevel > bright)
427 bright = temp->lightlevel;
428 if (temp->lightlevel < min)
429 min = temp->lightlevel;
432 sector->lightlevel = // Set level in-between extremes
433 (level * bright + (FRACUNIT-level) * min) >> FRACBITS;
435 return 1;