1 //
2 // Copyright(C) 1993-1996 Id Software, Inc.
3 // Copyright(C) 2005-2014 Simon Howard
4 //
5 // This program is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU General Public License
7 // as published by the Free Software Foundation; either version 2
8 // of the License, or (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 // GNU General Public License for more details.
14 //
15 // DESCRIPTION:
16 //	Handle Sector base lighting effects.
17 //	Muzzle flash?
18 //
19 
20 
21 
22 #include "z_zone.h"
23 #include "m_random.h"
24 
25 #include "doomdef.h"
26 #include "p_local.h"
27 
28 
29 // State.
30 #include "r_state.h"
31 #include "a11y.h" // [crispy] A11Y
32 
33 //
34 // FIRELIGHT FLICKER
35 //
36 
37 //
38 // T_FireFlicker
39 //
T_FireFlicker(fireflicker_t * flick)40 void T_FireFlicker (fireflicker_t* flick)
41 {
42     int	amount;
43 
44     if (--flick->count)
45 	return;
46 
47     amount = (P_Random()&3)*16;
48 
49     if (flick->sector->lightlevel - amount < flick->minlight)
50 	flick->sector->lightlevel = flick->minlight;
51     else
52 	flick->sector->lightlevel = flick->maxlight - amount;
53 
54     flick->count = 4;
55 
56     // [crispy] A11Y
57     if (a11y_sector_lighting)
58 	flick->sector->rlightlevel = flick->sector->lightlevel;
59 }
60 
61 
62 
63 //
64 // P_SpawnFireFlicker
65 //
P_SpawnFireFlicker(sector_t * sector)66 void P_SpawnFireFlicker (sector_t*	sector)
67 {
68     fireflicker_t*	flick;
69 
70     // Note that we are resetting sector attributes.
71     // Nothing special about it during gameplay.
72     sector->special = 0;
73 
74     flick = Z_Malloc ( sizeof(*flick), PU_LEVSPEC, 0);
75 
76     P_AddThinker (&flick->thinker);
77 
78     flick->thinker.function.acp1 = (actionf_p1) T_FireFlicker;
79     flick->sector = sector;
80     flick->maxlight = sector->lightlevel;
81     flick->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel)+16;
82     flick->count = 4;
83 }
84 
85 
86 
87 //
88 // BROKEN LIGHT FLASHING
89 //
90 
91 
92 //
93 // T_LightFlash
94 // Do flashing lights.
95 //
T_LightFlash(lightflash_t * flash)96 void T_LightFlash (lightflash_t* flash)
97 {
98     if (--flash->count)
99 	return;
100 
101     if (flash->sector->lightlevel == flash->maxlight)
102     {
103 	flash-> sector->lightlevel = flash->minlight;
104 	flash->count = (P_Random()&flash->mintime)+1;
105     }
106     else
107     {
108 	flash-> sector->lightlevel = flash->maxlight;
109 	flash->count = (P_Random()&flash->maxtime)+1;
110     }
111 
112     // [crispy] A11Y
113     if (a11y_sector_lighting)
114 	flash->sector->rlightlevel = flash->sector->lightlevel;
115 }
116 
117 
118 
119 
120 //
121 // P_SpawnLightFlash
122 // After the map has been loaded, scan each sector
123 // for specials that spawn thinkers
124 //
P_SpawnLightFlash(sector_t * sector)125 void P_SpawnLightFlash (sector_t*	sector)
126 {
127     lightflash_t*	flash;
128 
129     // nothing special about it during gameplay
130     sector->special = 0;
131 
132     flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
133 
134     P_AddThinker (&flash->thinker);
135 
136     flash->thinker.function.acp1 = (actionf_p1) T_LightFlash;
137     flash->sector = sector;
138     flash->maxlight = sector->lightlevel;
139 
140     flash->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
141     flash->maxtime = 64;
142     flash->mintime = 7;
143     flash->count = (P_Random()&flash->maxtime)+1;
144 }
145 
146 
147 
148 //
149 // STROBE LIGHT FLASHING
150 //
151 
152 
153 //
154 // T_StrobeFlash
155 //
T_StrobeFlash(strobe_t * flash)156 void T_StrobeFlash (strobe_t*		flash)
157 {
158     if (--flash->count)
159 	return;
160 
161     if (flash->sector->lightlevel == flash->minlight)
162     {
163 	flash-> sector->lightlevel = flash->maxlight;
164 	flash->count = flash->brighttime;
165     }
166     else
167     {
168 	flash-> sector->lightlevel = flash->minlight;
169 	flash->count =flash->darktime;
170     }
171 
172     // [crispy] A11Y
173     if (a11y_sector_lighting)
174 	flash->sector->rlightlevel = flash->sector->lightlevel;
175 }
176 
177 
178 
179 //
180 // P_SpawnStrobeFlash
181 // After the map has been loaded, scan each sector
182 // for specials that spawn thinkers
183 //
184 void
P_SpawnStrobeFlash(sector_t * sector,int fastOrSlow,int inSync)185 P_SpawnStrobeFlash
186 ( sector_t*	sector,
187   int		fastOrSlow,
188   int		inSync )
189 {
190     strobe_t*	flash;
191 
192     flash = Z_Malloc ( sizeof(*flash), PU_LEVSPEC, 0);
193 
194     P_AddThinker (&flash->thinker);
195 
196     flash->sector = sector;
197     flash->darktime = fastOrSlow;
198     flash->brighttime = STROBEBRIGHT;
199     flash->thinker.function.acp1 = (actionf_p1) T_StrobeFlash;
200     flash->maxlight = sector->lightlevel;
201     flash->minlight = P_FindMinSurroundingLight(sector, sector->lightlevel);
202 
203     if (flash->minlight == flash->maxlight)
204 	flash->minlight = 0;
205 
206     // nothing special about it during gameplay
207     sector->special = 0;
208 
209     if (!inSync)
210 	flash->count = (P_Random()&7)+1;
211     else
212 	flash->count = 1;
213 }
214 
215 
216 //
217 // Start strobing lights (usually from a trigger)
218 //
EV_StartLightStrobing(line_t * line)219 void EV_StartLightStrobing(line_t*	line)
220 {
221     int		secnum;
222     sector_t*	sec;
223 
224     secnum = -1;
225     while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0)
226     {
227 	sec = &sectors[secnum];
228 	if (sec->specialdata)
229 	    continue;
230 
231 	P_SpawnStrobeFlash (sec,SLOWDARK, 0);
232     }
233 }
234 
235 
236 
237 //
238 // TURN LINE'S TAG LIGHTS OFF
239 //
EV_TurnTagLightsOff(line_t * line)240 void EV_TurnTagLightsOff(line_t* line)
241 {
242     int			i;
243     int			j;
244     int			min;
245     sector_t*		sector;
246     sector_t*		tsec;
247     line_t*		templine;
248 
249     sector = sectors;
250 
251     for (j = 0;j < numsectors; j++, sector++)
252     {
253 	if (sector->tag == line->tag)
254 	{
255 	    min = sector->lightlevel;
256 	    for (i = 0;i < sector->linecount; i++)
257 	    {
258 		templine = sector->lines[i];
259 		tsec = getNextSector(templine,sector);
260 		if (!tsec)
261 		    continue;
262 		if (tsec->lightlevel < min)
263 		    min = tsec->lightlevel;
264 	    }
265 	    sector->lightlevel = min;
266 	    // [crispy] A11Y
267 	    sector->rlightlevel = sector->lightlevel;
268 	}
269     }
270 }
271 
272 
273 //
274 // TURN LINE'S TAG LIGHTS ON
275 //
276 void
EV_LightTurnOn(line_t * line,int bright)277 EV_LightTurnOn
278 ( line_t*	line,
279   int		bright )
280 {
281     int		i;
282     int		j;
283     sector_t*	sector;
284     sector_t*	temp;
285     line_t*	templine;
286 
287     sector = sectors;
288 
289     for (i=0;i<numsectors;i++, sector++)
290     {
291 	if (sector->tag == line->tag)
292 	{
293 	    // bright = 0 means to search
294 	    // for highest light level
295 	    // surrounding sector
296 	    if (!bright)
297 	    {
298 		for (j = 0;j < sector->linecount; j++)
299 		{
300 		    templine = sector->lines[j];
301 		    temp = getNextSector(templine,sector);
302 
303 		    if (!temp)
304 			continue;
305 
306 		    if (temp->lightlevel > bright)
307 			bright = temp->lightlevel;
308 		}
309 	    }
310 	    sector-> lightlevel = bright;
311 	    // [crispy] A11Y
312 	    sector->rlightlevel = sector->lightlevel;
313 	}
314     }
315 }
316 
317 
318 //
319 // Spawn glowing light
320 //
321 
T_Glow(glow_t * g)322 void T_Glow(glow_t*	g)
323 {
324     switch(g->direction)
325     {
326       case -1:
327 	// DOWN
328 	g->sector->lightlevel -= GLOWSPEED;
329 	if (g->sector->lightlevel <= g->minlight)
330 	{
331 	    g->sector->lightlevel += GLOWSPEED;
332 	    g->direction = 1;
333 	}
334 	break;
335 
336       case 1:
337 	// UP
338 	g->sector->lightlevel += GLOWSPEED;
339 	if (g->sector->lightlevel >= g->maxlight)
340 	{
341 	    g->sector->lightlevel -= GLOWSPEED;
342 	    g->direction = -1;
343 	}
344 	break;
345     }
346 
347     // [crispy] A11Y
348     if (a11y_sector_lighting)
349 	g->sector->rlightlevel = g->sector->lightlevel;
350 }
351 
352 
P_SpawnGlowingLight(sector_t * sector)353 void P_SpawnGlowingLight(sector_t*	sector)
354 {
355     glow_t*	g;
356 
357     g = Z_Malloc( sizeof(*g), PU_LEVSPEC, 0);
358 
359     P_AddThinker(&g->thinker);
360 
361     g->sector = sector;
362     g->minlight = P_FindMinSurroundingLight(sector,sector->lightlevel);
363     g->maxlight = sector->lightlevel;
364     g->thinker.function.acp1 = (actionf_p1) T_Glow;
365     g->direction = -1;
366 
367     sector->special = 0;
368 }
369 
370