1 // Emacs style mode select	 -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // $Id:$
5 //
6 // Copyright (C) 1993-1996 by id Software, Inc.
7 //
8 // This source is available for distribution and/or modification
9 // only under the terms of the DOOM Source Code License as
10 // published by id Software. All rights reserved.
11 //
12 // The source is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
15 // for more details.
16 //
17 // $Log:$
18 //
19 // DESCRIPTION:
20 //		Handle Sector base lighting effects.
21 //
22 //-----------------------------------------------------------------------------
23 
24 
25 #include "templates.h"
26 #include "m_random.h"
27 
28 #include "doomdef.h"
29 #include "p_local.h"
30 
31 #include "p_lnspec.h"
32 
33 // State.
34 #include "r_state.h"
35 #include "statnums.h"
36 #include "farchive.h"
37 
38 static FRandom pr_flicker ("Flicker");
39 static FRandom pr_lightflash ("LightFlash");
40 static FRandom pr_strobeflash ("StrobeFlash");
41 static FRandom pr_fireflicker ("FireFlicker");
42 
43 //-----------------------------------------------------------------------------
44 //
45 //
46 //
47 //-----------------------------------------------------------------------------
48 
IMPLEMENT_CLASS(DLighting)49 IMPLEMENT_CLASS (DLighting)
50 
51 DLighting::DLighting ()
52 {
53 }
54 
DLighting(sector_t * sector)55 DLighting::DLighting (sector_t *sector)
56 	: DSectorEffect (sector)
57 {
58 	ChangeStatNum (STAT_LIGHT);
59 }
60 
61 //-----------------------------------------------------------------------------
62 //
63 // FIRELIGHT FLICKER
64 //
65 //-----------------------------------------------------------------------------
66 
IMPLEMENT_CLASS(DFireFlicker)67 IMPLEMENT_CLASS (DFireFlicker)
68 
69 DFireFlicker::DFireFlicker ()
70 {
71 }
72 
Serialize(FArchive & arc)73 void DFireFlicker::Serialize (FArchive &arc)
74 {
75 	Super::Serialize (arc);
76 	arc << m_Count << m_MaxLight << m_MinLight;
77 }
78 
79 
80 //-----------------------------------------------------------------------------
81 //
82 // T_FireFlicker
83 //
84 //-----------------------------------------------------------------------------
85 
Tick()86 void DFireFlicker::Tick ()
87 {
88 	int amount;
89 
90 	if (--m_Count == 0)
91 	{
92 		amount = (pr_fireflicker() & 3) << 4;
93 
94 		// [RH] Shouldn't this be (m_MaxLight - amount < m_MinLight)?
95 		if (m_Sector->lightlevel - amount < m_MinLight)
96 			m_Sector->SetLightLevel(m_MinLight);
97 		else
98 			m_Sector->SetLightLevel(m_MaxLight - amount);
99 
100 		m_Count = 4;
101 	}
102 }
103 
104 //-----------------------------------------------------------------------------
105 //
106 // P_SpawnFireFlicker
107 //
108 //-----------------------------------------------------------------------------
109 
DFireFlicker(sector_t * sector)110 DFireFlicker::DFireFlicker (sector_t *sector)
111 	: DLighting (sector)
112 {
113 	m_MaxLight = sector->lightlevel;
114 	m_MinLight = sector_t::ClampLight(sector->FindMinSurroundingLight(sector->lightlevel) + 16);
115 	m_Count = 4;
116 }
117 
DFireFlicker(sector_t * sector,int upper,int lower)118 DFireFlicker::DFireFlicker (sector_t *sector, int upper, int lower)
119 	: DLighting (sector)
120 {
121 	m_MaxLight = sector_t::ClampLight(upper);
122 	m_MinLight = sector_t::ClampLight(lower);
123 	m_Count = 4;
124 }
125 
126 //-----------------------------------------------------------------------------
127 //
128 // [RH] flickering light like Hexen's
129 //
130 //-----------------------------------------------------------------------------
131 
IMPLEMENT_CLASS(DFlicker)132 IMPLEMENT_CLASS (DFlicker)
133 
134 DFlicker::DFlicker ()
135 {
136 }
137 
Serialize(FArchive & arc)138 void DFlicker::Serialize (FArchive &arc)
139 {
140 	Super::Serialize (arc);
141 	arc << m_Count << m_MaxLight << m_MinLight;
142 }
143 
144 //-----------------------------------------------------------------------------
145 //
146 //
147 //
148 //-----------------------------------------------------------------------------
149 
Tick()150 void DFlicker::Tick ()
151 {
152 	if (m_Count)
153 	{
154 		m_Count--;
155 	}
156 	else if (m_Sector->lightlevel == m_MaxLight)
157 	{
158 		m_Sector->SetLightLevel(m_MinLight);
159 		m_Count = (pr_flicker()&7)+1;
160 	}
161 	else
162 	{
163 		m_Sector->SetLightLevel(m_MaxLight);
164 		m_Count = (pr_flicker()&31)+1;
165 	}
166 }
167 
168 //-----------------------------------------------------------------------------
169 //
170 //
171 //
172 //-----------------------------------------------------------------------------
173 
DFlicker(sector_t * sector,int upper,int lower)174 DFlicker::DFlicker (sector_t *sector, int upper, int lower)
175 	: DLighting (sector)
176 {
177 	m_MaxLight = upper;
178 	m_MinLight = lower;
179 	sector->lightlevel = upper;
180 	m_Count = (pr_flicker()&64)+1;
181 }
182 
183 //-----------------------------------------------------------------------------
184 //
185 //
186 //
187 //-----------------------------------------------------------------------------
188 
EV_StartLightFlickering(int tag,int upper,int lower)189 void EV_StartLightFlickering (int tag, int upper, int lower)
190 {
191 	int secnum;
192 	FSectorTagIterator it(tag);
193 	while ((secnum = it.Next()) >= 0)
194 	{
195 		new DFlicker (&sectors[secnum], upper, lower);
196 	}
197 }
198 
199 
200 //-----------------------------------------------------------------------------
201 //
202 // BROKEN LIGHT FLASHING
203 //
204 //-----------------------------------------------------------------------------
205 
IMPLEMENT_CLASS(DLightFlash)206 IMPLEMENT_CLASS (DLightFlash)
207 
208 DLightFlash::DLightFlash ()
209 {
210 }
211 
Serialize(FArchive & arc)212 void DLightFlash::Serialize (FArchive &arc)
213 {
214 	Super::Serialize (arc);
215 	arc << m_Count << m_MaxLight << m_MaxTime << m_MinLight << m_MinTime;
216 }
217 
218 //-----------------------------------------------------------------------------
219 //
220 // T_LightFlash
221 // Do flashing lights.
222 //
223 //-----------------------------------------------------------------------------
224 
Tick()225 void DLightFlash::Tick ()
226 {
227 	if (--m_Count == 0)
228 	{
229 		if (m_Sector->lightlevel == m_MaxLight)
230 		{
231 			m_Sector->SetLightLevel(m_MinLight);
232 			m_Count = (pr_lightflash() & m_MinTime) + 1;
233 		}
234 		else
235 		{
236 			m_Sector->SetLightLevel(m_MaxLight);
237 			m_Count = (pr_lightflash() & m_MaxTime) + 1;
238 		}
239 	}
240 }
241 
242 //-----------------------------------------------------------------------------
243 //
244 // P_SpawnLightFlash
245 //
246 //-----------------------------------------------------------------------------
247 
DLightFlash(sector_t * sector)248 DLightFlash::DLightFlash (sector_t *sector)
249 	: DLighting (sector)
250 {
251 	// Find light levels like Doom.
252 	m_MaxLight = sector->lightlevel;
253 	m_MinLight = sector->FindMinSurroundingLight (sector->lightlevel);
254 	m_MaxTime = 64;
255 	m_MinTime = 7;
256 	m_Count = (pr_lightflash() & m_MaxTime) + 1;
257 }
258 
DLightFlash(sector_t * sector,int min,int max)259 DLightFlash::DLightFlash (sector_t *sector, int min, int max)
260 	: DLighting (sector)
261 {
262 	// Use specified light levels.
263 	m_MaxLight = sector_t::ClampLight(max);
264 	m_MinLight = sector_t::ClampLight(min);
265 	m_MaxTime = 64;
266 	m_MinTime = 7;
267 	m_Count = (pr_lightflash() & m_MaxTime) + 1;
268 }
269 
270 
271 //-----------------------------------------------------------------------------
272 //
273 // STROBE LIGHT FLASHING
274 //
275 //-----------------------------------------------------------------------------
276 
IMPLEMENT_CLASS(DStrobe)277 IMPLEMENT_CLASS (DStrobe)
278 
279 DStrobe::DStrobe ()
280 {
281 }
282 
Serialize(FArchive & arc)283 void DStrobe::Serialize (FArchive &arc)
284 {
285 	Super::Serialize (arc);
286 	arc << m_Count << m_MaxLight << m_MinLight << m_DarkTime << m_BrightTime;
287 }
288 
289 //-----------------------------------------------------------------------------
290 //
291 // T_StrobeFlash
292 //
293 //-----------------------------------------------------------------------------
294 
Tick()295 void DStrobe::Tick ()
296 {
297 	if (--m_Count == 0)
298 	{
299 		if (m_Sector->lightlevel == m_MinLight)
300 		{
301 			m_Sector->SetLightLevel(m_MaxLight);
302 			m_Count = m_BrightTime;
303 		}
304 		else
305 		{
306 			m_Sector->SetLightLevel(m_MinLight);
307 			m_Count = m_DarkTime;
308 		}
309 	}
310 }
311 
312 //-----------------------------------------------------------------------------
313 //
314 // Hexen-style constructor
315 //
316 //-----------------------------------------------------------------------------
317 
DStrobe(sector_t * sector,int upper,int lower,int utics,int ltics)318 DStrobe::DStrobe (sector_t *sector, int upper, int lower, int utics, int ltics)
319 	: DLighting (sector)
320 {
321 	m_DarkTime = ltics;
322 	m_BrightTime = utics;
323 	m_MaxLight = sector_t::ClampLight(upper);
324 	m_MinLight = sector_t::ClampLight(lower);
325 	m_Count = 1;	// Hexen-style is always in sync
326 }
327 
328 //-----------------------------------------------------------------------------
329 //
330 // Doom-style constructor
331 //
332 //-----------------------------------------------------------------------------
333 
DStrobe(sector_t * sector,int utics,int ltics,bool inSync)334 DStrobe::DStrobe (sector_t *sector, int utics, int ltics, bool inSync)
335 	: DLighting (sector)
336 {
337 	m_DarkTime = ltics;
338 	m_BrightTime = utics;
339 
340 	m_MaxLight = sector->lightlevel;
341 	m_MinLight = sector->FindMinSurroundingLight (sector->lightlevel);
342 
343 	if (m_MinLight == m_MaxLight)
344 		m_MinLight = 0;
345 
346 	m_Count = inSync ? 1 : (pr_strobeflash() & 7) + 1;
347 }
348 
349 
350 
351 //-----------------------------------------------------------------------------
352 //
353 // Start strobing lights (usually from a trigger)
354 // [RH] Made it more configurable.
355 //
356 //-----------------------------------------------------------------------------
357 
EV_StartLightStrobing(int tag,int upper,int lower,int utics,int ltics)358 void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics)
359 {
360 	int secnum;
361 	FSectorTagIterator it(tag);
362 	while ((secnum = it.Next()) >= 0)
363 	{
364 		sector_t *sec = &sectors[secnum];
365 		if (sec->lightingdata)
366 			continue;
367 
368 		new DStrobe (sec, upper, lower, utics, ltics);
369 	}
370 }
371 
EV_StartLightStrobing(int tag,int utics,int ltics)372 void EV_StartLightStrobing (int tag, int utics, int ltics)
373 {
374 	int secnum;
375 	FSectorTagIterator it(tag);
376 	while ((secnum = it.Next()) >= 0)
377 	{
378 		sector_t *sec = &sectors[secnum];
379 		if (sec->lightingdata)
380 			continue;
381 
382 		new DStrobe (sec, utics, ltics, false);
383 	}
384 }
385 
386 
387 //-----------------------------------------------------------------------------
388 //
389 // TURN LINE'S TAG LIGHTS OFF
390 // [RH] Takes a tag instead of a line
391 //
392 //-----------------------------------------------------------------------------
393 
EV_TurnTagLightsOff(int tag)394 void EV_TurnTagLightsOff (int tag)
395 {
396 	int secnum;
397 	FSectorTagIterator it(tag);
398 	while ((secnum = it.Next()) >= 0)
399 	{
400 		sector_t *sector = sectors + secnum;
401 		int min = sector->lightlevel;
402 
403 		for (int i = 0; i < sector->linecount; i++)
404 		{
405 			sector_t *tsec = getNextSector (sector->lines[i],sector);
406 			if (!tsec)
407 				continue;
408 			if (tsec->lightlevel < min)
409 				min = tsec->lightlevel;
410 		}
411 		sector->SetLightLevel(min);
412 	}
413 }
414 
415 
416 //-----------------------------------------------------------------------------
417 //
418 // TURN LINE'S TAG LIGHTS ON
419 // [RH] Takes a tag instead of a line
420 //
421 //-----------------------------------------------------------------------------
422 
EV_LightTurnOn(int tag,int bright)423 void EV_LightTurnOn (int tag, int bright)
424 {
425 	int secnum;
426 	FSectorTagIterator it(tag);
427 	while ((secnum = it.Next()) >= 0)
428 	{
429 		sector_t *sector = sectors + secnum;
430 		int tbright = bright; //jff 5/17/98 search for maximum PER sector
431 
432 		// bright = -1 means to search ([RH] Not 0)
433 		// for highest light level
434 		// surrounding sector
435 		if (bright < 0)
436 		{
437 			int j;
438 
439 			for (j = 0; j < sector->linecount; j++)
440 			{
441 				sector_t *temp = getNextSector (sector->lines[j], sector);
442 
443 				if (!temp)
444 					continue;
445 
446 				if (temp->lightlevel > tbright)
447 					tbright = temp->lightlevel;
448 			}
449 		}
450 		sector->SetLightLevel(tbright);
451 
452 		//jff 5/17/98 unless compatibility optioned
453 		//then maximum near ANY tagged sector
454 		if (i_compatflags & COMPATF_LIGHT)
455 		{
456 			bright = tbright;
457 		}
458 	}
459 }
460 
461 //-----------------------------------------------------------------------------
462 //
463 // killough 10/98
464 //
465 // EV_LightTurnOnPartway
466 //
467 // Turn sectors tagged to line lights on to specified or max neighbor level
468 //
469 // Passed the tag of sector(s) to light and a light level fraction between 0 and 1.
470 // Sets the light to min on 0, max on 1, and interpolates in-between.
471 // Used for doors with gradual lighting effects.
472 //
473 //-----------------------------------------------------------------------------
474 
EV_LightTurnOnPartway(int tag,fixed_t frac)475 void EV_LightTurnOnPartway (int tag, fixed_t frac)
476 {
477 	frac = clamp<fixed_t> (frac, 0, FRACUNIT);
478 
479 	// Search all sectors for ones with same tag as activating line
480 	int secnum;
481 	FSectorTagIterator it(tag);
482 	while ((secnum = it.Next()) >= 0)
483 	{
484 		sector_t *temp, *sector = &sectors[secnum];
485 		int j, bright = 0, min = sector->lightlevel;
486 
487 		for (j = 0; j < sector->linecount; ++j)
488 		{
489 			if ((temp = getNextSector (sector->lines[j], sector)) != NULL)
490 			{
491 				if (temp->lightlevel > bright)
492 				{
493 					bright = temp->lightlevel;
494 				}
495 				if (temp->lightlevel < min)
496 				{
497 					min = temp->lightlevel;
498 				}
499 			}
500 		}
501 		sector->SetLightLevel(DMulScale16 (frac, bright, FRACUNIT-frac, min));
502 	}
503 }
504 
505 
506 //-----------------------------------------------------------------------------
507 //
508 // [RH] New function to adjust tagged sectors' light levels
509 //		by a relative amount. Light levels are clipped to
510 //		be within range for sector_t::lightlevel.
511 //
512 //-----------------------------------------------------------------------------
513 
EV_LightChange(int tag,int value)514 void EV_LightChange (int tag, int value)
515 {
516 	int secnum;
517 	FSectorTagIterator it(tag);
518 	while ((secnum = it.Next()) >= 0)
519 	{
520 		sectors[secnum].SetLightLevel(sectors[secnum].lightlevel + value);
521 	}
522 }
523 
524 
525 //-----------------------------------------------------------------------------
526 //
527 // Spawn glowing light
528 //
529 //-----------------------------------------------------------------------------
530 
IMPLEMENT_CLASS(DGlow)531 IMPLEMENT_CLASS (DGlow)
532 
533 DGlow::DGlow ()
534 {
535 }
536 
Serialize(FArchive & arc)537 void DGlow::Serialize (FArchive &arc)
538 {
539 	Super::Serialize (arc);
540 	arc << m_Direction << m_MaxLight << m_MinLight;
541 }
542 
543 //-----------------------------------------------------------------------------
544 //
545 //
546 //
547 //-----------------------------------------------------------------------------
548 
Tick()549 void DGlow::Tick ()
550 {
551 	int newlight = m_Sector->lightlevel;
552 
553 	switch (m_Direction)
554 	{
555 	case -1:
556 		// DOWN
557 		newlight -= GLOWSPEED;
558 		if (newlight <= m_MinLight)
559 		{
560 			newlight += GLOWSPEED;
561 			m_Direction = 1;
562 		}
563 		break;
564 
565 	case 1:
566 		// UP
567 		newlight += GLOWSPEED;
568 		if (newlight >= m_MaxLight)
569 		{
570 			newlight -= GLOWSPEED;
571 			m_Direction = -1;
572 		}
573 		break;
574 	}
575 	m_Sector->SetLightLevel(newlight);
576 }
577 
578 //-----------------------------------------------------------------------------
579 //
580 //
581 //
582 //-----------------------------------------------------------------------------
583 
DGlow(sector_t * sector)584 DGlow::DGlow (sector_t *sector)
585 	: DLighting (sector)
586 {
587 	m_MinLight = sector->FindMinSurroundingLight (sector->lightlevel);
588 	m_MaxLight = sector->lightlevel;
589 	m_Direction = -1;
590 }
591 
592 //-----------------------------------------------------------------------------
593 //
594 // [RH] More glowing light, this time appropriate for Hexen-ish uses.
595 //
596 //-----------------------------------------------------------------------------
597 
IMPLEMENT_CLASS(DGlow2)598 IMPLEMENT_CLASS (DGlow2)
599 
600 DGlow2::DGlow2 ()
601 {
602 }
603 
Serialize(FArchive & arc)604 void DGlow2::Serialize (FArchive &arc)
605 {
606 	Super::Serialize (arc);
607 	arc << m_End << m_MaxTics << m_OneShot << m_Start << m_Tics;
608 }
609 
610 //-----------------------------------------------------------------------------
611 //
612 //
613 //
614 //-----------------------------------------------------------------------------
615 
Tick()616 void DGlow2::Tick ()
617 {
618 	if (m_Tics++ >= m_MaxTics)
619 	{
620 		if (m_OneShot)
621 		{
622 			m_Sector->SetLightLevel(m_End);
623 			Destroy ();
624 			return;
625 		}
626 		else
627 		{
628 			int temp = m_Start;
629 			m_Start = m_End;
630 			m_End = temp;
631 			m_Tics -= m_MaxTics;
632 		}
633 	}
634 
635 	m_Sector->SetLightLevel(((m_End - m_Start) * m_Tics) / m_MaxTics + m_Start);
636 }
637 
638 //-----------------------------------------------------------------------------
639 //
640 //
641 //
642 //-----------------------------------------------------------------------------
643 
DGlow2(sector_t * sector,int start,int end,int tics,bool oneshot)644 DGlow2::DGlow2 (sector_t *sector, int start, int end, int tics, bool oneshot)
645 	: DLighting (sector)
646 {
647 	m_Start = sector_t::ClampLight(start);
648 	m_End = sector_t::ClampLight(end);
649 	m_MaxTics = tics;
650 	m_Tics = -1;
651 	m_OneShot = oneshot;
652 }
653 
654 //-----------------------------------------------------------------------------
655 //
656 //
657 //
658 //-----------------------------------------------------------------------------
659 
EV_StartLightGlowing(int tag,int upper,int lower,int tics)660 void EV_StartLightGlowing (int tag, int upper, int lower, int tics)
661 {
662 	int secnum;
663 
664 	// If tics is non-positive, then we can't really do anything.
665 	if (tics <= 0)
666 	{
667 		return;
668 	}
669 
670 	if (upper < lower)
671 	{
672 		int temp = upper;
673 		upper = lower;
674 		lower = temp;
675 	}
676 
677 	FSectorTagIterator it(tag);
678 	while ((secnum = it.Next()) >= 0)
679 	{
680 		sector_t *sec = &sectors[secnum];
681 		if (sec->lightingdata)
682 			continue;
683 
684 		new DGlow2 (sec, upper, lower, tics, false);
685 	}
686 }
687 
688 //-----------------------------------------------------------------------------
689 //
690 //
691 //
692 //-----------------------------------------------------------------------------
693 
EV_StartLightFading(int tag,int value,int tics)694 void EV_StartLightFading (int tag, int value, int tics)
695 {
696 	int secnum;
697 	FSectorTagIterator it(tag);
698 	while ((secnum = it.Next()) >= 0)
699 	{
700 		sector_t *sec = &sectors[secnum];
701 		if (sec->lightingdata)
702 			continue;
703 
704 		if (tics <= 0)
705 		{
706 			sec->SetLightLevel(value);
707 		}
708 		else
709 		{
710 			// No need to fade if lightlevel is already at desired value.
711 			if (sec->lightlevel == value)
712 				continue;
713 
714 			new DGlow2 (sec, sec->lightlevel, value, tics, true);
715 		}
716 	}
717 }
718 
719 
720 //-----------------------------------------------------------------------------
721 //
722 // [RH] Phased lighting ala Hexen, but implemented without the help of the Hexen source
723 // The effect is a little different, but close enough, I feel.
724 //
725 //-----------------------------------------------------------------------------
726 
IMPLEMENT_CLASS(DPhased)727 IMPLEMENT_CLASS (DPhased)
728 
729 DPhased::DPhased ()
730 {
731 }
732 
Serialize(FArchive & arc)733 void DPhased::Serialize (FArchive &arc)
734 {
735 	Super::Serialize (arc);
736 	arc << m_BaseLevel << m_Phase;
737 }
738 
739 //-----------------------------------------------------------------------------
740 //
741 //
742 //
743 //-----------------------------------------------------------------------------
744 
Tick()745 void DPhased::Tick ()
746 {
747 	const int steps = 12;
748 
749 	if (m_Phase < steps)
750 		m_Sector->SetLightLevel( ((255 - m_BaseLevel) * m_Phase) / steps + m_BaseLevel);
751 	else if (m_Phase < 2*steps)
752 		m_Sector->SetLightLevel( ((255 - m_BaseLevel) * (2*steps - m_Phase - 1) / steps
753 								+ m_BaseLevel));
754 	else
755 		m_Sector->SetLightLevel(m_BaseLevel);
756 
757 	if (m_Phase == 0)
758 		m_Phase = 63;
759 	else
760 		m_Phase--;
761 }
762 
763 //-----------------------------------------------------------------------------
764 //
765 //
766 //
767 //-----------------------------------------------------------------------------
768 
PhaseHelper(sector_t * sector,int index,int light,sector_t * prev)769 int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev)
770 {
771 	if (!sector)
772 	{
773 		return index;
774 	}
775 	else
776 	{
777 		DPhased *l;
778 		int baselevel = sector->lightlevel ? sector->lightlevel : light;
779 
780 		if (index == 0)
781 		{
782 			l = this;
783 			m_BaseLevel = baselevel;
784 		}
785 		else
786 			l = new DPhased (sector, baselevel);
787 
788 		int numsteps = PhaseHelper (sector->NextSpecialSector (
789 				sector->special == LightSequenceSpecial1 ?
790 					LightSequenceSpecial2 : LightSequenceSpecial1, prev),
791 				index + 1, l->m_BaseLevel, sector);
792 		l->m_Phase = ((numsteps - index - 1) * 64) / numsteps;
793 
794 		sector->special = 0;
795 
796 		return numsteps;
797 	}
798 }
799 
800 //-----------------------------------------------------------------------------
801 //
802 //
803 //
804 //-----------------------------------------------------------------------------
805 
DPhased(sector_t * sector,int baselevel)806 DPhased::DPhased (sector_t *sector, int baselevel)
807 	: DLighting (sector)
808 {
809 	m_BaseLevel = baselevel;
810 }
811 
DPhased(sector_t * sector)812 DPhased::DPhased (sector_t *sector)
813 	: DLighting (sector)
814 {
815 	PhaseHelper (sector, 0, 0, NULL);
816 }
817 
DPhased(sector_t * sector,int baselevel,int phase)818 DPhased::DPhased (sector_t *sector, int baselevel, int phase)
819 	: DLighting (sector)
820 {
821 	m_BaseLevel = baselevel;
822 	m_Phase = phase;
823 }
824 
825 //============================================================================
826 //
827 // EV_StopLightEffect
828 //
829 // Stops a lighting effect that is currently running in a sector.
830 //
831 //============================================================================
832 
EV_StopLightEffect(int tag)833 void EV_StopLightEffect (int tag)
834 {
835 	TThinkerIterator<DLighting> iterator;
836 	DLighting *effect;
837 
838 	while ((effect = iterator.Next()) != NULL)
839 	{
840 		if (tagManager.SectorHasTag(effect->GetSector(), tag))
841 		{
842 			effect->Destroy();
843 		}
844 	}
845 }
846