]> icculus.org git repositories - theoddone33/hhexen.git/blob - base/p_lights.c
Fix stupid wadfile problem
[theoddone33/hhexen.git] / base / p_lights.c
1
2 //**************************************************************************
3 //**
4 //** p_lights.c : Heretic 2 : Raven Software, Corp.
5 //**
6 //** $RCSfile$
7 //** $Revision$
8 //** $Date$
9 //** $Author$
10 //**
11 //**************************************************************************
12
13 #include "h2def.h"
14 #include "p_local.h"
15
16 //============================================================================
17 //
18 //      T_Light
19 //
20 //============================================================================
21
22 void T_Light(light_t *light)
23 {
24         if(light->count)
25         {
26                 light->count--; 
27                 return;
28         }
29         switch(light->type)
30         {
31                 case LITE_FADE:
32                         light->sector->lightlevel = ((light->sector->lightlevel<<FRACBITS)
33                                 +light->value2)>>FRACBITS;
34                         if(light->tics2 == 1)
35                         {
36                                 if(light->sector->lightlevel >= light->value1)
37                                 {
38                                         light->sector->lightlevel = light->value1;
39                                         P_RemoveThinker(&light->thinker);
40                                 }
41                         }
42                         else if(light->sector->lightlevel <= light->value1)
43                         {
44                                 light->sector->lightlevel = light->value1;
45                                 P_RemoveThinker(&light->thinker);
46                         }
47                         break;
48                 case LITE_GLOW:
49                         light->sector->lightlevel = ((light->sector->lightlevel<<FRACBITS)
50                                 +light->tics1)>>FRACBITS;
51                         if(light->tics2 == 1)
52                         {
53                                 if(light->sector->lightlevel >= light->value1)
54                                 {
55                                         light->sector->lightlevel = light->value1;
56                                         light->tics1 = -light->tics1;
57                                         light->tics2 = -1; // reverse direction
58                                 }
59                         }
60                         else if(light->sector->lightlevel <= light->value2)
61                         {
62                                 light->sector->lightlevel = light->value2;
63                                 light->tics1 = -light->tics1;
64                                 light->tics2 = 1; // reverse direction
65                         }
66                         break;
67                 case LITE_FLICKER:
68                         if(light->sector->lightlevel == light->value1)
69                         {
70                                 light->sector->lightlevel = light->value2;
71                                 light->count = (P_Random()&7)+1;
72                         }
73                         else
74                         {
75                                 light->sector->lightlevel = light->value1;
76                                 light->count = (P_Random()&31)+1;
77                         }
78                         break;
79                 case LITE_STROBE:
80                         if(light->sector->lightlevel == light->value1)
81                         {
82                                 light->sector->lightlevel = light->value2;
83                                 light->count = light->tics2;
84                         }
85                         else
86                         {
87                                 light->sector->lightlevel = light->value1;
88                                 light->count = light->tics1;
89                         }
90                         break;
91                 default:
92                         break;
93         }
94 }
95
96 //============================================================================
97 //
98 //      EV_SpawnLight
99 //
100 //============================================================================
101
102 boolean EV_SpawnLight(line_t *line, byte *arg, lighttype_t type)
103 {
104         light_t *light;
105         sector_t *sec;
106         int secNum;     
107         int arg1, arg2, arg3, arg4;
108         boolean think;
109         boolean rtn;
110         
111         arg1 = arg[1] > 255 ? 255 : arg[1];
112         arg1 = arg1 < 0 ? 0 : arg1;
113         arg2 = arg[2] > 255 ? 255 : arg[2];
114         arg2 = arg2 < 0 ? 0 : arg2;
115         arg3 = arg[3] > 255 ? 255 : arg[3];
116         arg3 = arg3 < 0 ? 0 : arg3;
117         arg4 = arg[4] > 255 ? 255 : arg[4];
118         arg4 = arg4 < 0 ? 0 : arg4;
119
120         secNum = -1;
121         rtn = false;
122         think = false;
123         while((secNum = P_FindSectorFromTag(arg[0], secNum)) >= 0)
124         {
125                 think = false;
126                 sec = &sectors[secNum];
127
128                 light = (light_t *)Z_Malloc(sizeof(light_t), PU_LEVSPEC, 0);
129                 light->type = type;
130                 light->sector = sec;
131                 light->count = 0;
132                 rtn = true;
133                 switch(type)
134                 {
135                         case LITE_RAISEBYVALUE:
136                                 sec->lightlevel += arg1;
137                                 if(sec->lightlevel > 255)
138                                 {
139                                         sec->lightlevel = 255;
140                                 }
141                                 break;
142                         case LITE_LOWERBYVALUE:
143                                 sec->lightlevel -= arg1;
144                                 if(sec->lightlevel < 0)
145                                 {
146                                         sec->lightlevel = 0;
147                                 }
148                                 break;
149                         case LITE_CHANGETOVALUE:
150                                 sec->lightlevel = arg1;
151                                 if(sec->lightlevel < 0)
152                                 {
153                                         sec->lightlevel = 0;
154                                 }
155                                 else if(sec->lightlevel > 255)
156                                 {
157                                         sec->lightlevel = 255;
158                                 }
159                                 break;
160                         case LITE_FADE:
161                                 think = true;
162                                 light->value1 = arg1; // destination lightlevel
163                                 light->value2 = FixedDiv((arg1-sec->lightlevel)<<FRACBITS,
164                                         arg2<<FRACBITS);  // delta lightlevel
165                                 if(sec->lightlevel <= arg1)
166                                 {
167                                         light->tics2 = 1; // get brighter
168                                 }
169                                 else
170                                 {
171                                         light->tics2 = -1;
172                                 }
173                                 break;
174                         case LITE_GLOW:
175                                 think = true;
176                                 light->value1 = arg1; // upper lightlevel
177                                 light->value2 = arg2; // lower lightlevel
178                                 light->tics1 = FixedDiv((arg1-sec->lightlevel)<<FRACBITS,
179                                         arg3<<FRACBITS);  // lightlevel delta
180                                 if(sec->lightlevel <= arg1)
181                                 {
182                                         light->tics2 = 1; // get brighter
183                                 }
184                                 else
185                                 {
186                                         light->tics2 = -1;
187                                 }
188                                 break;
189                         case LITE_FLICKER:
190                                 think = true;
191                                 light->value1 = arg1; // upper lightlevel
192                                 light->value2 = arg2; // lower lightlevel
193                                 sec->lightlevel = light->value1;
194                                 light->count = (P_Random()&64)+1;
195                                 break;
196                         case LITE_STROBE:
197                                 think = true;
198                                 light->value1 = arg1; // upper lightlevel
199                                 light->value2 = arg2; // lower lightlevel
200                                 light->tics1 = arg3;  // upper tics
201                                 light->tics2 = arg4;  // lower tics
202                                 light->count = arg3;
203                                 sec->lightlevel = light->value1;
204                                 break;
205                         default:
206                                 rtn = false;
207                                 break;
208                 }
209                 if(think)
210                 {
211                         P_AddThinker(&light->thinker);
212                         light->thinker.function = T_Light;
213                 }
214                 else
215                 {
216                         Z_Free(light);
217                 }
218         }
219         return rtn;
220 }
221
222 //============================================================================
223 //
224 //      T_Phase
225 //
226 //============================================================================
227
228 int PhaseTable[64] =
229 {
230         128, 112, 96, 80, 64, 48, 32, 32,
231         16, 16, 16, 0, 0, 0, 0, 0,
232         0, 0, 0, 0, 0, 0, 0, 0,
233         0, 0, 0, 0, 0, 0, 0, 0,
234         0, 0, 0, 0, 0, 0, 0, 0,
235         0, 0, 0, 0, 0, 0, 0, 0,
236         0, 0, 0, 0, 0, 16, 16, 16,
237         32, 32, 48, 64, 80, 96, 112, 128
238 };
239
240 void T_Phase(phase_t *phase)
241 {
242         phase->index = (phase->index+1)&63;
243         phase->sector->lightlevel = phase->base+PhaseTable[phase->index];
244 }
245
246 //==========================================================================
247 //
248 // P_SpawnPhasedLight
249 //
250 //==========================================================================
251
252 void P_SpawnPhasedLight(sector_t *sector, int base, int index)
253 {
254         phase_t *phase;
255
256         phase = Z_Malloc(sizeof(*phase), PU_LEVSPEC, 0);
257         P_AddThinker(&phase->thinker);
258         phase->sector = sector;
259         if(index == -1)
260         { // sector->lightlevel as the index
261                 phase->index = sector->lightlevel&63;
262         }
263         else
264         {
265                 phase->index = index&63;
266         }
267         phase->base = base&255;
268         sector->lightlevel = phase->base+PhaseTable[phase->index];
269         phase->thinker.function = T_Phase;
270
271         sector->special = 0;
272 }
273
274 //==========================================================================
275 //
276 // P_SpawnLightSequence
277 //
278 //==========================================================================
279
280 void P_SpawnLightSequence(sector_t *sector, int indexStep)
281 {
282         sector_t *sec;
283         sector_t *nextSec;
284         sector_t *tempSec;
285         int seqSpecial;
286         int i;
287         int count;
288         fixed_t index;
289         fixed_t indexDelta;
290         int base;
291
292         seqSpecial = LIGHT_SEQUENCE; // look for Light_Sequence, first
293         sec = sector;
294         count = 1;
295         do
296         {
297                 nextSec = NULL;
298                 sec->special = LIGHT_SEQUENCE_START; // make sure that the search doesn't back up.
299                 for(i = 0; i < sec->linecount; i++)
300                 {
301                         tempSec = getNextSector(sec->lines[i], sec);
302                         if(!tempSec)
303                         {
304                                 continue;
305                         }
306                         if(tempSec->special == seqSpecial)
307                         {
308                                 if(seqSpecial == LIGHT_SEQUENCE)
309                                 {
310                                         seqSpecial = LIGHT_SEQUENCE_ALT;
311                                 }
312                                 else
313                                 {
314                                         seqSpecial = LIGHT_SEQUENCE;
315                                 }
316                                 nextSec = tempSec;
317                                 count++;
318                         }
319                 }
320                 sec = nextSec;
321         } while(sec);
322
323         sec = sector;
324         count *= indexStep;
325         index = 0;
326         indexDelta = FixedDiv(64*FRACUNIT, count*FRACUNIT);
327         base = sector->lightlevel;
328         do
329         {
330                 nextSec = NULL;
331                 if(sec->lightlevel)
332                 {
333                         base = sec->lightlevel;
334                 }
335                 P_SpawnPhasedLight(sec, base, index>>FRACBITS);
336                 index += indexDelta;
337                 for(i = 0; i < sec->linecount; i++)
338                 {
339                         tempSec = getNextSector(sec->lines[i], sec);
340                         if(!tempSec)
341                         {
342                                 continue;
343                         }
344                         if(tempSec->special == LIGHT_SEQUENCE_START)
345                         {
346                                 nextSec = tempSec;
347                         }
348                 }
349                 sec = nextSec;
350         } while(sec);
351 }