1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 See the GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18
19 */
20
21 #include "rt_def.h"
22
23 #ifdef DOS
24 #include <malloc.h>
25 #include <dos.h>
26 #endif
27
28 #include <string.h>
29 #include "sprites.h"
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include "rt_stat.h"
33 #include "z_zone.h"
34 #include "lumpy.h"
35 #include "rt_util.h"
36 #include "rt_draw.h"
37 #include "rt_ted.h"
38 #include "rt_door.h"
39 #include "rt_main.h"
40 #include "w_wad.h"
41 #include "rt_main.h"
42 #include "rt_rand.h"
43 #include "rt_menu.h"
44 #include "rt_sound.h"
45 #include "_rt_stat.h"
46 #include "rt_net.h"
47 #include "rt_view.h"
48 #include "isr.h"
49 //MED
50 #include "memcheck.h"
51
52
53
54 /*
55 =============================================================================
56
57 Global Variables GLOBAL VARIABLES
58
59 =============================================================================
60 */
61
62 statobj_t *firstactivestat,*lastactivestat;
63 statobj_t *firstemptystat,*lastemptystat;
64
65 wall_t switches[MAXSWITCHES],*lastswitch;
66 respawn_t *firstrespawn,*lastrespawn;
67 statobj_t *FIRSTSTAT,*LASTSTAT,*sprites[MAPSIZE][MAPSIZE];
68 animwall_t animwalls[MAXANIMWALLS];
69
70 dirtype opposite[9] =
71 {west,southwest,south,southeast,east,northeast,north,northwest,nodir};
72
73
74
75
76
77
78 statinfo stats[NUMSTATS] =
79 {
80 {0,SPR0_YLIGHT, stat_ylight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
81 {0,SPR1_RLIGHT, stat_rlight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
82 {0,SPR2_GLIGHT, stat_glight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
83 {0,SPR3_BLIGHT, stat_blight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
84 {0,SPR4_CHAND, stat_chandelier,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
85 {0,SPR5_LAMPOFF, stat_lamp,FL_LIGHT|FL_BLOCK|FL_SHOOTABLE,0,0,2,0,0},
86 {0,SPR73_GKEY1, stat_pedgoldkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_orange,0,0},
87 {0,SPR73_GKEY1,stat_pedsilverkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_gray,0,0},
88 {0,SPR73_GKEY1, stat_pedironkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_olive,0,0},
89 {0,SPR73_GKEY1,stat_pedcrystalkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_red,0,0},
90 {0,SPR6_GIBS1, stat_gibs1,0,0,0,0,0,0},
91 {0,SPR7_GIBS2, stat_gibs2,0,0,0,0,0,0},
92 {0,SPR8_GIBS3, stat_gibs3,0,0,0,0,0,0},
93 {0,SPR9_MONKMEAL, stat_monkmeal,FL_BONUS|FL_RESPAWN,0,0,0,0,0},
94 {0,PORRIDGE1, stat_priestporridge,FL_BONUS|FL_RESPAWN,2,6,0,0,0},
95 {0,MONKCRYSTAL11,stat_monkcrystal1,FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,6,0,0,0},
96 {0,MONKCRYSTAL21,stat_monkcrystal2,FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,7,0,0,0},
97 {0,ONEUP01,stat_oneup,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,2,8,0,0,0},
98 {0,THREEUP01,stat_threeup,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,2,8,0,0,0},
99 {0,TORCH1,stat_altbrazier1,FL_HEAT|FL_BLOCK|FL_ACTIVE|FL_LIGHT|FL_SHOOTABLE,2,15,2,0,0},
100 {0,SPR_ABRAZIER2,stat_altbrazier2,FL_HEAT|FL_BLOCK|FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0},
101 {0,FBASIN1,stat_healingbasin,FL_BONUS|FL_CHANGES|FL_ACTIVE|FL_BLOCK,2,3,0,0,0},
102 {20,EBASIN,stat_emptybasin,FL_BLOCK|FL_SHOOTABLE,0,0,0,0,0},
103 {0,BAT1,stat_bat,FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_WEAPON,1,16,0,0,10},
104 {0,KNIFE_STATUE1,stat_knifestatue,FL_BONUS|FL_CHANGES|FL_BLOCK,0,0,0,0,0},
105 {0,SPR_TWOPIST,stat_twopistol,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
106 {0,SPR_MP40,stat_mp40,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
107 {0,SPR_BAZOOKA,stat_bazooka,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,10},
108 {0,SPR_FIREBOMB,stat_firebomb,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
109 {0,SPR_HEATSEEK,stat_heatseeker,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
110 {0,SPR_DRUNK,stat_drunkmissile,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
111 {0,SPR_FIREWALL,stat_firewall,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5},
112 {0,SPR_SPLIT,stat_splitmissile,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
113 {0,SPR_KES,stat_kes,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7},
114 {0,LIFEITEMA01,stat_lifeitem1,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0},
115 {0,LIFEITEMB01,stat_lifeitem2,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0},
116 {0,LIFEITEMD01,stat_lifeitem3,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0},
117 {0,LIFEITEMC01,stat_lifeitem4,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,15, 2,0,0},
118 {24,SPR32_EXPLOS,stat_tntcrate,FL_SHOOTABLE|FL_BLOCK|FL_WOODEN,0,0,3,10,0},
119 {12,SPR33_CBARREL,stat_bonusbarrel,FL_METALLIC|FL_SHOOTABLE|FL_BLOCK,0,0,3,10,0},
120 {0,TORCH1,stat_torch,FL_BLOCK|FL_LIGHT|FL_ACTIVE|FL_HEAT|FL_SHOOTABLE,2,15,2,0,0},
121 {30,FFLAME1,stat_floorfire,FL_HEAT|FL_BLOCK|FL_LIGHT|FL_ACTIVE|FL_SHOOTABLE,2,7,30,0,0},
122 {0,DIP11,stat_dipball1,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0},
123 {0,DIP21,stat_dipball2,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0},
124 {0,DIP31,stat_dipball3,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0},
125 {0,SPR34_TOUCH1,stat_touch1,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
126 {0,SPR35_TOUCH2,stat_touch2,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
127 {0,SPR36_TOUCH3,stat_touch3,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
128 {0,SPR37_TOUCH4,stat_touch4,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0},
129 {20,SPR62_ETOUCH1,stat_dariantouch,FL_METALLIC|FL_BANDF|FL_SHOOTABLE|FL_BLOCK,10,3,50,0,0},
130 {0,SCOTHEAD1, stat_scotthead,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,4,7,0,0,0},
131 {0,SPR38_GARBAGE1,stat_garb1,0,0,0,0,0,0},
132 {0,SPR39_GARBAGE2,stat_garb2,0,0,0,0,0,0},
133 {0,SPR40_GARBAGE3,stat_garb3,0,0,0,0,0,0},
134 {0,SPR41_SHIT,stat_shit,0,0,0,0,0,0},
135 {0,SPR42_GRATE,stat_grate,0,0,0,0,0,0},
136 {0,SPR43_MSHARDS,stat_metalshards,0,0,0,0,0,0},
137 {20,SPR44_PEDESTAL,stat_emptypedestal,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,60,0,0},
138 {20,SPR45_ETABLE,stat_emptytable,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,100,0,0},
139 {16,SPR46_STOOL,stat_stool,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,25,0,0},
140 {0,SPR_PUSHCOLUMN1,stat_bcolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
141 {0,SPR_PUSHCOLUMN1,stat_gcolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
142 {0,SPR_PUSHCOLUMN1,stat_icolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
143 {20,SPR50_TREE,stat_tree,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0},
144 {20,SPR51_PLANT,stat_plant,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0},
145 {20,BLUEVASE,stat_urn,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0},
146 {0,SPR54_HAY,stat_haystack,FL_SHOOTABLE|FL_BLOCK,0,0,20,0,0},
147 {12,SPR55_IBARREL,stat_ironbarrel,FL_METALLIC|FL_BLOCK|FL_SHOOTABLE,0,0,50,0,0},
148 {0,HGRATE1,stat_heatgrate,FL_LIGHT|FL_ACTIVE,2,4,0,5,0},
149 {-10,STNPOLE1,stat_standardpole,FL_SHOOTABLE|FL_BLOCK,0,0,25,0,0},
150 {0,PREPIT,stat_pit,FL_CHANGES,0,0,0,0,0},
151 {0,GODPOWERUP1,stat_godmode,FL_WEAPON|FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
152 {0,DOGPOWERUP1,stat_dogmode,FL_WEAPON|FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
153 {0,FLEETFEETPOWERUP1,stat_fleetfeet,FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
154 {0,ELASTICPOWERUP1, stat_elastic, FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
155 {0,MUSHROOMPOWERUP1, stat_mushroom, FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0},
156 {0,GASMASKPOWERUP, stat_gasmask, FL_BONUS|FL_RESPAWN,0,0,0,0,0},
157 {0,BULLETPROOFPOWERUP, stat_bulletproof, FL_BONUS|FL_RESPAWN,0,0,0,0,0},
158 {0,ASBESTOSPOWERUP, stat_asbesto, FL_BONUS|FL_RESPAWN,0,0,0,0,0},
159 {0,RANDOMPOWERUP1, stat_random, FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,8,0,0,0},
160 {0,RUBBLE1, stat_rubble, FL_ACTIVE,2,10,0,0,0},
161 {0,WOODFRAG1, stat_woodfrag, FL_ACTIVE,2,14,0,0,0},
162 {0,ROBOGRDDIE1, stat_metalfrag, FL_ACTIVE,2,10,0,0,0},
163 {0,EMPTY_STATUE1,stat_emptystatue,FL_BLOCK|FL_SHOOTABLE,0,0,50,0,0},
164 {16,TOMLARVA1,stat_tomlarva,FL_ACTIVE|FL_SHOOTABLE|FL_BLOCK,2,4,150,0,0},
165 {0,BULLETHOLE,stat_bullethole,FL_TRANSLUCENT,0,0,0,0,0},
166 //MED
167 #if (SHAREWARE == 1)
168 {0,COLLECTOR1,stat_collector,FL_ACTIVE|FL_BONUS,2,8,-1,0,0},
169 #else
170 {0,DOPE1,stat_collector,FL_ACTIVE|FL_BONUS,2,8,-1,0,0},
171 #endif
172 {0,SPR_MINE1,stat_mine,FL_BONUS|FL_SHOOTABLE|FL_RESPAWN,0,0,10,0,0},
173 {0,MISSMOKE1,stat_missmoke,FL_ACTIVE,6,4,0,0,0},
174 {0,PLATFORM1,stat_disk,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0},
175 {-1,0,0,0,0,0,0,0,0}
176 };
177
178
179 dirtype diagonal[9][9] =
180 {
181 /* east */ {nodir,nodir,northeast,nodir,nodir,nodir,southeast,nodir,nodir},
182 {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
183 /* north */ {northeast,nodir,nodir,nodir,northwest,nodir,nodir,nodir,nodir},
184 {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
185 /* west */ {nodir,nodir,northwest,nodir,nodir,nodir,southwest,nodir,nodir},
186 {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
187 /* south */ {southeast,nodir,nodir,nodir,southwest,nodir,nodir,nodir,nodir},
188 {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir},
189 {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}
190 };
191
192 /*
193 =============================================================================
194
195 Local Variables GLOBAL VARIABLES
196
197 =============================================================================
198 */
199 static awallinfo_t animwallsinfo[MAXANIMWALLS] =
200 {{3,4,"FPLACE1\0"}, //lava wall
201 {3,6,"ANIMY1\0"}, //anim red
202 {3,6,"ANIMR1\0"}, //anim yellow
203 {40,4,"ANIMFAC1\0"}, //anim face
204 {3,4,"ANIMONE1\0"}, //anim one
205 {3,4,"ANIMTWO1\0"}, //anim two
206 {3,4,"ANIMTHR1\0"}, //anim three
207 {3,4,"ANIMFOR1\0"}, //anim four
208 {3,6,"ANIMGW1\0"}, //anim grey water
209 {3,6,"ANIMYOU1\0"}, //anim you do not belong
210 {3,6,"ANIMBW1\0"}, //anim brown water
211 {3,6,"ANIMBP1\0"}, //anim brown piston
212 {3,6,"ANIMCHN1\0"}, //anim chain
213 {3,6,"ANIMFW1\0"}, //anim firewall
214 {3,6,"ANIMLAT1\0"}, //anim little blips
215 {3,6,"ANIMST1\0"}, //anim light streams left
216 {3,6,"ANIMRP1\0"}};//anim light streams right
217
218 int statcount;
219
220 void AddRespawnStatic(respawn_t*stat);
221 void DoLights (int tilex, int tiley);
222
AddToFreeStaticList(statobj_t * stat)223 void AddToFreeStaticList(statobj_t*stat)
224 { if (!firstemptystat)
225 firstemptystat = stat;
226 else
227 {stat->statprev = lastemptystat;
228 lastemptystat->statnext = stat;
229 }
230 lastemptystat = stat;
231
232 }
233
234
RemoveFromFreeStaticList(statobj_t * stat)235 void RemoveFromFreeStaticList(statobj_t*stat)
236 {
237 if (stat == lastemptystat)
238 lastemptystat = stat->statprev;
239 else
240 stat->statnext->statprev = stat->statprev;
241
242 if (stat == firstemptystat)
243 firstemptystat = stat->statnext;
244 else
245 stat->statprev->statnext = stat->statnext;
246
247 stat->statprev = NULL;
248 stat->statnext = NULL;
249
250 }
251
252
253
254
255 /*
256 ===============
257 =
258 = MakeStatActive
259 =
260 ===============
261 */
262
MakeStatActive(statobj_t * x)263 void MakeStatActive(statobj_t*x)
264 {if (!firstactivestat)
265 firstactivestat = x;
266 else
267 {x->prevactive = lastactivestat;
268 lastactivestat->nextactive = x;
269 }
270 lastactivestat = x;
271 }
272
273
274 /*
275 ===============
276 =
277 = MakeStatInactive
278 =
279 ===============
280 */
281
MakeStatInactive(statobj_t * stat)282 void MakeStatInactive(statobj_t*stat)
283 {
284 if (stat == lastactivestat)
285 lastactivestat = stat->prevactive;
286 else
287 stat->nextactive->prevactive = stat->prevactive;
288
289 if (stat == firstactivestat)
290 firstactivestat = stat->nextactive;
291 else
292 stat->prevactive->nextactive = stat->nextactive;
293
294 stat->prevactive = NULL;
295 stat->nextactive = NULL;
296
297 }
298 /*
299 ===============
300 =
301 = AddStatic
302 =
303 ===============
304 */
305
AddStatic(statobj_t * stat)306 void AddStatic(statobj_t *stat)
307 {if (FIRSTSTAT)
308 {stat->statprev = LASTSTAT;
309 LASTSTAT->statnext = stat;
310 }
311 else
312 FIRSTSTAT = stat;
313 LASTSTAT = stat;
314 }
315
316
317
RemoveStatic(statobj_t * stat)318 void RemoveStatic(statobj_t*stat)
319 {
320 if (stat->flags & FL_ABP) //remove from active list
321 MakeStatInactive(stat);
322
323 if (stat == LASTSTAT) // remove from master list
324 LASTSTAT = stat->statprev;
325 else
326 stat->statnext->statprev = stat->statprev;
327
328 if (stat == FIRSTSTAT)
329 FIRSTSTAT = stat->statnext;
330 else
331 stat->statprev->statnext = stat->statnext;
332
333 stat->statprev = NULL;
334 stat->statnext = NULL;
335
336 if (stat->flags & FL_WEAPON)
337 MISCVARS->NUMWEAPONS --;
338
339 if ((stat->flags & FL_RESPAWN) &&
340 gamestate.BattleOptions.RespawnItems &&
341 (!((stat->flags & FL_WEAPON ) &&
342 (gamestate.BattleOptions.WeaponPersistence)
343 )
344 )
345 )
346 {
347 respawn_t*temp;
348 // if ( !( (stat->flags & FL_WEAPON) &&
349 // (MISCVARS->NUMWEAPONS >= (numplayers+10))
350 // )
351 // )
352 {
353 temp = (respawn_t*)Z_LevelMalloc(sizeof(respawn_t),PU_LEVELSTRUCT,NULL);
354
355 memset (temp,0,sizeof(*temp));
356 temp->ticcount = GetRespawnTimeForItem(stat->itemnumber);
357 temp->tilex = stat->tilex;
358 temp->tiley = stat->tiley;
359 temp->itemnumber = stat->itemnumber;
360 temp->spawnz = stat->z;
361 temp->linked_to = stat->linked_to;
362 //SoftError("\nrespawn obj created for stattype %d with z = %d",stat->itemnumber,temp->spawnz);
363 AddRespawnStatic(temp);
364 }
365 }
366 //Z_Free(stat);
367 AddToFreeStaticList(stat);
368
369 //Add_To_Delete_Array(stat);
370 statcount --;
371 }
372
373
RemoveRespawnStatic(respawn_t * stat)374 void RemoveRespawnStatic(respawn_t*stat)
375 {
376 if (stat == lastrespawn)
377 lastrespawn = stat->prev;
378 else
379 stat->next->prev = stat->prev;
380
381 if (stat == firstrespawn)
382 firstrespawn = stat->next;
383 else
384 stat->prev->next = stat->next;
385
386 stat->prev = NULL;
387 stat->next = NULL;
388 Z_Free(stat);
389 }
390
391
TurnOffLight(int tilex,int tiley)392 void TurnOffLight(int tilex,int tiley)
393 {
394 DoLights(tilex,tiley);
395 LightsInArea[MAPSPOT(tilex,tiley,0)-AREATILE]--;
396
397 }
398
399
ActivateLight(int light)400 void ActivateLight(int light)
401 {statobj_t*tstat;
402
403 tstat = (statobj_t*)light;
404
405 tstat->shapenum ++;
406 tstat->flags |= FL_LIGHTON;
407 TurnOnLight(tstat->tilex,tstat->tiley);
408
409 }
410
411
DeactivateLight(int light)412 void DeactivateLight(int light)
413 {statobj_t*tstat;
414
415 tstat = (statobj_t*)light;
416
417 tstat->shapenum --;
418 tstat->flags &= ~(FL_LIGHTON);
419 TurnOffLight(tstat->tilex,tstat->tiley);
420
421 }
422
TurnOnLight(int i,int j)423 void TurnOnLight(int i,int j)
424 {
425
426 LightsInArea[MAPSPOT(i,j,0)-AREATILE]++;
427
428 if (lightsource==0)
429 return;
430
431 if ((!(tilemap[i+1][j])) && (!(tilemap[i-1][j])))
432 {
433 SetLight(i,j,0xcdeffedc);
434 SetLight(i+1,j,0x135789ab);
435 SetLight(i-1,j,0xba987351);
436 SetLight(i,j+1,0xcdeffedc);
437 SetLight(i,j-1,0xcdeffedc);
438 SetLight(i-1,j-1,0xba987351);
439 SetLight(i+1,j+1,0xba987351);
440 SetLight(i+1,j-1,0x135789ab);
441 SetLight(i-1,j+1,0x135789ab);
442 }
443 else if ((!(tilemap[i][j+1])) && (!(tilemap[i][j-1])))
444 {
445 SetLight(i,j,0xcdeffedc);
446 SetLight(i+1,j,0xcdeffedc);
447 SetLight(i-1,j,0xcdeffedc);
448 SetLight(i,j+1,0x135789ab);
449 SetLight(i,j-1,0xba987531);
450 SetLight(i-1,j-1,0x135789ab);
451 SetLight(i+1,j-1,0xba987531);
452 SetLight(i+1,j+1,0x135789ab);
453 SetLight(i-1,j+1,0xba987531);
454 }
455 // |
456 //__|
457 else if ((tilemap[i][j+1]) && (tilemap[i+1][j]))
458 {
459 SetLight(i,j,0xcdeffedc);
460 SetLight(i+1,j,0xcdeffedc);
461 SetLight(i-1,j,0xcdeffedc);
462 SetLight(i,j+1,0xcdeffedc);
463 SetLight(i,j-1,0xcdeffedc);
464 SetLight(i-1,j-1,0xba987351);
465 SetLight(i+1,j-1,0xba987351);
466 SetLight(i+1,j+1,0xba987351);
467 SetLight(i-1,j+1,0x135789ab);
468 }
469 //|
470 //|_
471 else if ((tilemap[i][j+1]) && (tilemap[i-1][j]))
472 {
473 SetLight(i,j,0xcdeffedc);
474 SetLight(i+1,j,0xcdeffedc);
475 SetLight(i-1,j,0xcdeffedc);
476 SetLight(i,j+1,0xcdeffedc);
477 SetLight(i,j-1,0xcdeffedc);
478 SetLight(i-1,j-1,0x135789ab);
479 SetLight(i+1,j-1,0xba987531);
480 SetLight(i+1,j+1,0xba987531);
481 SetLight(i-1,j+1,0xba987531);
482 }
483 //_
484 // |
485 else if ((tilemap[i][j-1]) && (tilemap[i+1][j]))
486 {
487 SetLight(i,j,0xcdeffedc);
488 SetLight(i+1,j,0xcdeffedc);
489 SetLight(i-1,j,0xcdeffedc);
490 SetLight(i,j+1,0xcdeffedc);
491 SetLight(i,j-1,0xcdeffedc);
492 SetLight(i-1,j-1,0xba987531);
493 SetLight(i+1,j-1,0x135789ab);
494 SetLight(i+1,j+1,0x135789ab);
495 SetLight(i-1,j+1,0xba987531);
496 }
497 //__
498 //|
499 else if ((tilemap[i][j-1]) && (tilemap[i-1][j]))
500 {
501 SetLight(i,j,0xcdeffedc);
502 SetLight(i+1,j,0xcdeffedc);
503 SetLight(i-1,j,0xcdeffedc);
504 SetLight(i,j+1,0xcdeffedc);
505 SetLight(i,j-1,0xcdeffedc);
506 SetLight(i-1,j-1,0x135789ab);
507 SetLight(i+1,j-1,0x135789ab);
508 SetLight(i+1,j+1,0xba987531);
509 SetLight(i-1,j+1,0xba987531);
510 }
511 else if (tilemap[i][j])
512 {
513 SetLight(i,j,0x58bffb85);
514 }
515 else
516 {
517 SetLight(i,j,0xcdeffedc);
518 SetLight(i+1,j,0xba987654);
519 SetLight(i-1,j,0x456789ab);
520 SetLight(i,j+1,0xba987654);
521 SetLight(i,j-1,0x456789ab);
522 SetLight(i-1,j+1,0x33322211);
523 SetLight(i+1,j+1,0x33322211);
524 SetLight(i+1,j-1,0x11222333);
525 SetLight(i-1,j-1,0x11222333);
526 }
527
528
529 }
530
531
532
533
534 /*===============
535 =
536 = AddRespawnStatic
537 =
538 ===============
539 */
540
AddRespawnStatic(respawn_t * stat)541 void AddRespawnStatic(respawn_t*stat)
542 {
543 if (firstrespawn)
544 {stat->prev = lastrespawn;
545 lastrespawn->next = stat;
546 }
547 else
548 firstrespawn = stat;
549 lastrespawn = stat;
550 }
551
552
553 /*
554 ===============
555 =
556 = InitStaticList
557 =
558 ===============
559 */
560
InitStaticList(void)561 void InitStaticList (void)
562 {
563 FIRSTSTAT = NULL;
564 LASTSTAT = NULL;
565 lastactivestat = NULL;
566 firstactivestat = NULL;
567 firstrespawn = NULL;
568 lastrespawn = NULL;
569 lastemptystat = NULL;
570 firstemptystat = NULL;
571
572 memset(&BulletHoles[0],0,sizeof(BulletHoles));
573 MISCVARS->BulletHoleNum = 0;
574
575
576 memset(sprites,0,sizeof(sprites));
577 if (loadedgame==false)
578 {
579 memset(switches,0,sizeof(switches));
580 lastswitch = &switches[0];
581 }
582 statcount = 0;
583
584 }
585
586
587 /*
588 ===============
589 =
590 = InitAnimatedWallList
591 =
592 ===============
593 */
594
InitAnimatedWallList(void)595 void InitAnimatedWallList(void)
596 {
597 int i;
598
599 for (i=0;i<MAXANIMWALLS;i++)
600 animwalls[i].active=0;
601 }
602
603 /*
604 ===============
605 =
606 = SetupAnimatedWall
607 =
608 ===============
609 */
610
SetupAnimatedWall(int which)611 void SetupAnimatedWall(int which)
612 {
613 animwall_t * aw;
614 int i;
615 int texture;
616
617 aw = &animwalls[which];
618
619 aw->active=1;
620 aw->ticcount=animwallsinfo[which].tictime;
621 aw->count = 1;
622
623 texture=W_GetNumForName(animwallsinfo[which].firstlump);
624
625 aw->basetexture=texture;
626 aw->texture=texture;
627
628 if (DoPanicMapping()==true)
629 {
630 PreCacheLump(aw->basetexture,PU_CACHEWALLS);
631 }
632 else
633 {
634 for (i=aw->basetexture;i<aw->basetexture+animwallsinfo[which].numanims;i++)
635 PreCacheLump(i,PU_CACHEWALLS);
636 }
637 }
638
639
640 /*
641 ===============
642 =
643 = SaveStatics
644 =
645 ===============
646 */
647
SaveStatics(byte ** buffer,int * size)648 void SaveStatics (byte **buffer, int * size)
649 {statobj_t * temp;
650 saved_stat_type dummy;
651 byte * tptr;
652 int count;
653
654 if (statcount==0)
655 {
656 *size=0;
657 *buffer=SafeMalloc(16);
658 return;
659 }
660 *size = statcount*sizeof(saved_stat_type);
661 *buffer = (byte *)SafeMalloc(*size);
662 tptr = *buffer;
663
664 for(count=0,temp=FIRSTSTAT;temp;temp=temp->statnext)
665 {dummy.x = temp->x;
666 dummy.y = temp->y;
667 dummy.z = temp->z;
668 dummy.flags = temp->flags;
669 dummy.ticcount = temp->ticcount;
670 dummy.hitpoints = temp->hitpoints;
671 dummy.shapenum = temp->shapenum;
672 dummy.ammo = temp->ammo;
673 dummy.count = temp->count;
674 dummy.numanims = temp->numanims;
675 dummy.itemnumber = temp->itemnumber;
676 dummy.areanumber = temp->areanumber;
677 temp->whichstat = count;
678 dummy.whichstat = count++;
679 dummy.linked_to = temp->linked_to;
680
681 memcpy(tptr,&(dummy.x),sizeof(saved_stat_type));
682 tptr += sizeof(saved_stat_type);
683
684 }
685
686 }
687
688 /*
689 ===============
690 =
691 = DoLights
692 =
693 ===============
694 */
695
DoLights(int tilex,int tiley)696 void DoLights (int tilex, int tiley)
697 {
698 if (lightsource==0)
699 return;
700 if (TurnOffLight0 (tilex, tiley))
701 LightSourceAt(tilex,tiley) = 0;
702
703 if (TurnOffLight1 (tilex, tiley, -1, -1))
704 LightSourceAt(tilex-1,tiley-1) = 0;
705
706 if (TurnOffLight2 (tilex, tiley, -1))
707 LightSourceAt(tilex,tiley-1) = 0;
708
709 if (TurnOffLight1 (tilex, tiley, 1, -1))
710 LightSourceAt(tilex+1,tiley-1) = 0;
711
712 if (TurnOffLight3 (tilex, tiley, 1))
713 LightSourceAt(tilex+1,tiley) = 0;
714
715 if (TurnOffLight1 (tilex, tiley, 1, 1))
716 LightSourceAt(tilex+1,tiley+1) = 0;
717
718 if (TurnOffLight2 (tilex, tiley, 1))
719 LightSourceAt(tilex,tiley+1) = 0;
720
721 if (TurnOffLight1 (tilex, tiley, -1, 1))
722 LightSourceAt(tilex-1,tiley+1) = 0;
723
724 if (TurnOffLight3 (tilex, tiley, -1))
725 LightSourceAt(tilex-1,tiley) = 0;
726 }
727
728
729 /*
730 ===============
731 =
732 = TurnOffLight0
733 =
734 ===============
735 */
736
TurnOffLight0(int tilex,int tiley)737 boolean TurnOffLight0 (int tilex, int tiley)
738 {
739 if ( IsLight(tilex-1,tiley ) ||
740 IsLight(tilex-1,tiley-1) ||
741 IsLight(tilex ,tiley-1) ||
742 IsLight(tilex+1,tiley-1) ||
743 IsLight(tilex+1,tiley ) ||
744 IsLight(tilex+1,tiley+1) ||
745 IsLight(tilex ,tiley+1) ||
746 IsLight(tilex-1,tiley+1) )
747 return (false);
748 else
749 return (true);
750 }
751
752 /*
753 ===============
754 =
755 = TurnOffLight1
756 =
757 ===============
758 */
759
TurnOffLight1(int tilex,int tiley,int i,int j)760 boolean TurnOffLight1 (int tilex, int tiley, int i, int j)
761 {
762 int tempi = 2*i;
763 int tempy = 2*j;
764
765 if ( IsLight(tilex+i ,tiley ) ||
766 IsLight(tilex+i ,tiley+j) ||
767 IsLight(tilex ,tiley+j) ||
768 IsLight(tilex ,tiley+tempy) ||
769 IsLight(tilex+i ,tiley+tempy) ||
770 IsLight(tilex+tempi,tiley+tempy) ||
771 IsLight(tilex+tempi,tiley+j) ||
772 IsLight(tilex+tempi,tiley))
773 return (false);
774 else
775 return (true);
776 }
777
778
779 /*
780 ===============
781 =
782 = TurnOffLight2
783 =
784 ===============
785 */
786
TurnOffLight2(int tilex,int tiley,int j)787 boolean TurnOffLight2 (int tilex, int tiley, int j)
788 {
789 int tempy = 2*j;
790
791 if ( IsLight(tilex-1 ,tiley ) ||
792 IsLight(tilex-1 ,tiley+j) ||
793 IsLight(tilex-1 ,tiley+tempy) ||
794 IsLight(tilex ,tiley+j) ||
795 IsLight(tilex ,tiley+tempy) ||
796 IsLight(tilex+1 ,tiley) ||
797 IsLight(tilex+1 ,tiley+j) ||
798 IsLight(tilex+1 ,tiley+tempy))
799 return (false);
800 else
801 return (true);
802 }
803
804
805 /*
806 ===============
807 =
808 = TurnOffLight3
809 =
810 ===============
811 */
812
TurnOffLight3(int tilex,int tiley,int i)813 boolean TurnOffLight3 (int tilex, int tiley, int i)
814 {
815 int tempx = 2*i;
816
817 if ( IsLight(tilex ,tiley-1) ||
818 IsLight(tilex+1 ,tiley-1) ||
819 IsLight(tilex+tempx,tiley-1) ||
820 IsLight(tilex+i ,tiley) ||
821 IsLight(tilex+tempx,tiley) ||
822 IsLight(tilex ,tiley+1) ||
823 IsLight(tilex+i ,tiley+1) ||
824 IsLight(tilex+tempx,tiley+1))
825 return (false);
826 else
827 return (true);
828 }
829
830
831
832
833 /*
834 ======================
835 =
836 = PreCacheStaticFrames
837 =
838 ======================
839 */
840
841
842
843
PreCacheStaticFrames(statobj_t * temp)844 void PreCacheStaticFrames(statobj_t*temp)
845 {
846 int z,start,stop;
847 int female=0,black=0;
848
849 PreCacheLump(temp->shapenum+shapestart,PU_CACHESPRITES);
850 for (z=0;z<temp->numanims;z++)
851 PreCacheLump(temp->shapenum+shapestart+z,PU_CACHESPRITES);
852
853 if (temp->flags & FL_ROTATING)
854 {
855 for (z=1;z<8;z++)
856 PreCacheLump(temp->shapenum+shapestart+z,PU_CACHESPRITES);
857 }
858
859 if (temp->flags & FL_WOODEN)
860 {
861 start = W_GetNumForName("WFRAG1");
862 stop = W_GetNumForName("WFRAG14");
863 PreCacheGroup(start,stop);
864 }
865
866 if (temp->flags & FL_METALLIC)
867 {
868 PreCacheLump(W_GetNumForName("MSHARDS"),PU_CACHESPRITES);
869 start = W_GetNumForName("ROBODIE1");
870 stop = W_GetNumForName("ROBODEAD");
871 PreCacheGroup(start,stop);
872 }
873
874 female = ((locplayerstate->player == 1) || (locplayerstate->player == 3));
875 black = (locplayerstate->player == 2);
876
877 if (female)
878 {
879 start = W_GetNumForName("FPIST11");
880 stop = W_GetNumForName("FPIST13");
881 }
882 else if (black)
883 {
884 start = W_GetNumForName("BMPIST1");
885 stop = W_GetNumForName("BMPIST3");
886 }
887 else
888 {
889 start = W_GetNumForName("MPIST11");
890 stop = W_GetNumForName("MPIST13");
891 }
892
893 PreCacheGroup(start,stop);
894
895 switch (temp->itemnumber)
896 {
897
898 case stat_pedgoldkey:
899 case stat_pedsilverkey:
900 case stat_pedironkey:
901 case stat_pedcrystalkey:
902 PreCacheLump(W_GetNumForName("PEDESTA"),PU_CACHESPRITES);
903 break;
904
905 case stat_bat:
906 start = W_GetNumForName("EXBAT1");
907 stop = W_GetNumForName("EXBAT7");
908 PreCacheGroup(start,stop);
909 break;
910 case stat_knifestatue:
911 start = W_GetNumForName("KNIFE1");
912 stop = W_GetNumForName("KNIFE10");
913 PreCacheGroup(start,stop);
914 break;
915 case stat_twopistol:
916 if (female)
917 {
918 start = W_GetNumForName("RFPIST1");
919 stop = W_GetNumForName("LFPIST3");
920 }
921 else if (black)
922 {
923 start = W_GetNumForName("RBMPIST1");
924 stop = W_GetNumForName("LBMPIST3");
925 }
926 else
927 {
928 start = W_GetNumForName("RMPIST1");
929 stop = W_GetNumForName("LMPIST3");
930 }
931 PreCacheGroup(start,stop);
932 break;
933 case stat_mp40:
934 start = W_GetNumForName("MP401");
935 stop = W_GetNumForName("MP403");
936 PreCacheGroup(start,stop);
937 break;
938 case stat_bazooka:
939 start = W_GetNumForName("BAZOOKA1");
940 stop = W_GetNumForName("BAZOOKA4");
941 PreCacheGroup(start,stop);
942 break;
943 case stat_firebomb:
944 start = W_GetNumForName("FBOMB1");
945 stop = W_GetNumForName("FBOMB4");
946 PreCacheGroup(start,stop);
947 break;
948 case stat_heatseeker:
949 start = W_GetNumForName("HSEEK1");
950 stop = W_GetNumForName("HSEEK4");
951 PreCacheGroup(start,stop);
952 break;
953 case stat_drunkmissile:
954 start = W_GetNumForName("DRUNK1");
955 stop = W_GetNumForName("DRUNK4");
956 PreCacheGroup(start,stop);
957 break;
958 case stat_firewall:
959 start = W_GetNumForName("FIREW1");
960 stop = W_GetNumForName("FIREW3");
961 PreCacheGroup(start,stop);
962 break;
963 case stat_splitmissile:
964 start = W_GetNumForName("SPLIT1");
965 stop = W_GetNumForName("SPLIT4");
966 PreCacheGroup(start,stop);
967 break;
968 case stat_kes:
969 start = W_GetNumForName("KES1");
970 stop = W_GetNumForName("KES6");
971 PreCacheGroup(start,stop);
972 break;
973 case stat_godmode:
974 start = W_GetNumForName("GODHAND1");
975 stop = W_GetNumForName("GODHAND8");
976 PreCacheGroup(start,stop);
977
978 PreCacheGroup(W_GetNumForName("VAPO1"),
979 W_GetNumForName("LITSOUL"));
980
981 PreCacheGroup(W_GetNumForName("GODFIRE1"),
982 W_GetNumForName("GODFIRE4"));
983
984 break;
985 case stat_dogmode:
986 start = W_GetNumForName("DOGNOSE1");
987 stop = W_GetNumForName("DOGPAW4");
988 PreCacheGroup(start,stop);
989 break;
990
991 default:
992 ;
993 }
994
995
996
997 }
998
999
1000
1001 /*
1002 ===============
1003 =
1004 = LoadStatics
1005 =
1006 ===============
1007 */
1008
1009
1010
1011
LoadStatics(byte * buffer,int size)1012 void LoadStatics( byte * buffer, int size)
1013 {saved_stat_type dummy;
1014 int stcount,i;
1015 statobj_t*temp;
1016
1017 stcount = size/sizeof(saved_stat_type);
1018 InitStaticList();
1019
1020 for(i=0;i<stcount;i++)
1021 {
1022 temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
1023 if (!temp)
1024 Error("LoadStatics: Failed on allocation of static %ld of %ld",i,stcount);
1025 memset(temp,0,sizeof(*temp));
1026 memcpy(&(dummy.x),buffer,sizeof(saved_stat_type));
1027 temp->whichstat = statcount++;
1028 temp->x = dummy.x;
1029 temp->y = dummy.y;
1030 temp->z = dummy.z;
1031 temp->flags = dummy.flags;
1032 temp->ticcount = dummy.ticcount;
1033 temp->hitpoints = dummy.hitpoints;
1034 temp->shapenum = dummy.shapenum;
1035 temp->ammo = dummy.ammo;
1036 temp->count = dummy.count;
1037 temp->numanims = dummy.numanims;
1038 temp->itemnumber = dummy.itemnumber;
1039 temp->areanumber = dummy.areanumber;
1040 temp->linked_to = dummy.linked_to;
1041
1042 temp->which = SPRITE;
1043 temp->tilex = temp->x >> TILESHIFT;
1044 temp->tiley = temp->y >> TILESHIFT;
1045 temp->flags &= ~FL_ABP;
1046 temp->visspot = &spotvis[temp->tilex][temp->tiley];
1047
1048 if ((temp->itemnumber >= stat_touch1) &&
1049 (temp->itemnumber <= stat_touch4))
1050 {touchindices[temp->tilex][temp->tiley] = lasttouch + 1;
1051 lasttouch ++;
1052 SD_PreCacheSoundGroup(SD_TOUCHPLATESND,SD_BADTOUCHSND);
1053 }
1054
1055 AddStatic(temp);
1056 if (temp->shapenum != -1)
1057 {
1058 if (temp->itemnumber == stat_bullethole)
1059 {
1060 SetupBulletHoleLink(temp->linked_to,temp);
1061 }
1062
1063 else if (temp->flags & FL_DEADBODY)
1064 {
1065 if ( actorat[temp->tilex][temp->tiley] == NULL )
1066 actorat[temp->tilex][temp->tiley] = temp;
1067 }
1068
1069 else if (!(temp->flags & FL_NONMARK))
1070 {
1071 sprites[temp->tilex][temp->tiley] = temp;
1072 }
1073
1074 PreCacheStaticFrames(temp);
1075
1076
1077 }
1078 PreCacheStaticSounds(temp->itemnumber);
1079
1080 buffer += sizeof(saved_stat_type);
1081 }
1082 }
1083
1084
Set_NewZ_to_MapValue(fixed * newz,int zoffset,const char * errorstr,int tilex,int tiley)1085 void Set_NewZ_to_MapValue(fixed *newz,int zoffset,const char*errorstr,int tilex,int tiley)
1086 {
1087 int zf,z;
1088
1089 zoffset&=0xff;
1090 z=zoffset>>4;
1091 zf=zoffset&0xf;
1092 if (z==0xf)
1093 *newz = nominalheight+64-(zf<<2);
1094 else
1095 {
1096 if (z>levelheight)
1097 Error ("You specified a height of %lx for the %s at tilex=%ld tiley=%ld when\n the level is only %ld high\n",
1098 zoffset,errorstr,tilex,tiley,levelheight);
1099 else
1100 *newz = nominalheight-(z<<6)-(zf<<2);
1101 }
1102
1103 }
1104
1105
1106
1107 /*
1108 ===============
1109 =
1110 = SpawnStatic
1111 =
1112 ===============
1113 */
1114
1115
1116
1117
SpawnStatic(int tilex,int tiley,int mtype,int zoffset)1118 void SpawnStatic (int tilex, int tiley, int mtype, int zoffset)
1119 {statobj_t * temp;
1120 boolean onetimer;
1121
1122
1123
1124 #if (SHAREWARE == 1)
1125 switch(mtype)
1126 {
1127 case stat_rlight:
1128 case stat_glight:
1129 case stat_ylight:
1130 case stat_chandelier:
1131 mtype = stat_blight;
1132 break;
1133
1134 case stat_garb1:
1135 case stat_garb2:
1136 case stat_garb3:
1137 case stat_shit:
1138 mtype = stat_metalshards;
1139 break;
1140
1141 case stat_lamp:
1142 mtype = stat_altbrazier2;
1143 break;
1144
1145 }
1146 #endif
1147
1148
1149
1150 if ( BATTLEMODE )
1151 {
1152 if ( !gamestate.BattleOptions.SpawnWeapons )
1153 {
1154 if ( stats[ mtype ].flags & FL_WEAPON )
1155 {
1156 return;
1157 }
1158 }
1159
1160 if (mtype == stat_pit)
1161 return;
1162
1163 // Change lifeitems and extra lives to health
1164 switch( mtype )
1165 {
1166 case stat_lifeitem1 :
1167 case stat_lifeitem2 :
1168 mtype = stat_monkcrystal1;
1169 break;
1170
1171 case stat_lifeitem3 :
1172 case stat_lifeitem4 :
1173 case stat_oneup :
1174 case stat_threeup :
1175 mtype = stat_monkcrystal2;
1176 break;
1177 }
1178
1179 switch( mtype )
1180 {
1181 case stat_monkmeal :
1182 case stat_priestporridge :
1183 case stat_monkcrystal1 :
1184 case stat_monkcrystal2 :
1185 case stat_healingbasin :
1186 if ( ( gamestate.Product != ROTT_SHAREWARE ) &&
1187 ( gamestate.BattleOptions.SpawnMines ) &&
1188 ( !IsPlatform( tilex, tiley ) &&
1189 ( ( zoffset & 0xff00 ) != 0xb000 ) ) &&
1190 ( zoffset == -1 ) )
1191 {
1192 mtype = stat_mine;
1193 }
1194 else if ( !gamestate.BattleOptions.SpawnHealth )
1195 {
1196 return;
1197 }
1198 break;
1199 }
1200 }
1201
1202 if (!firstemptystat)
1203 {temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
1204 //SoftError("\nMalloc-ing actor");
1205 //if (insetupgame)
1206 // SoftError("in setup");
1207 }
1208
1209 else
1210 {temp = lastemptystat;
1211 //SoftError("\nfree actor available");
1212 RemoveFromFreeStaticList(lastemptystat);
1213 }
1214
1215 // Standard pole hack
1216
1217 if ((zoffset>=14) && (zoffset<=17))
1218 zoffset=-1;
1219
1220 if (temp)
1221 { memset(temp,0,sizeof(*temp));
1222 temp->shapenum = stats[mtype].picnum;
1223 temp->whichstat = statcount ++;
1224 temp->tilex = tilex;
1225 temp->tiley = tiley;
1226 temp->x = ((long)tilex << TILESHIFT) + 0x8000;
1227 temp->y = ((long)tiley << TILESHIFT) + 0x8000;
1228 temp->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
1229 temp->linked_to = -1;
1230 if ((temp->areanumber<=0) || (temp->areanumber>NUMAREAS))
1231 Error ("Sprite at x=%ld y=%ld type=%ld has an illegal areanumber\n",tilex,tiley,mtype);
1232 if ( mtype == stat_mine )
1233 {
1234 temp->z = nominalheight;
1235 }
1236 else if (zoffset!=-1)
1237 {
1238 if ((zoffset&0xff00)==0xb000)
1239 Set_NewZ_to_MapValue(&(temp->z),zoffset,"static",tilex,tiley);
1240 else if (IsPlatform(tilex,tiley))
1241 temp->z = PlatformHeight(tilex,tiley);
1242 else if (zoffset==11)
1243 temp->z=-65;
1244 else if (zoffset==12)
1245 temp->z=-66;
1246 else
1247 temp->z = nominalheight;
1248 // Error ("You didn't specify a valid height over the sprite at tilex=%ld tiley=%ld\n",tilex,tiley);
1249 }
1250 else if (mtype>stat_chandelier)
1251 temp->z = nominalheight;
1252
1253 temp->visspot = &spotvis[tilex][tiley];
1254 temp->which = SPRITE;
1255 temp->ticcount = stats[mtype].tictime;
1256 temp->hitpoints = stats[mtype].hitpoints;
1257 temp->itemnumber = stats[mtype].type;
1258 temp->flags = stats[mtype].flags;
1259 temp->ammo = stats[mtype].ammo;
1260 temp->numanims = stats[mtype].numanims;
1261
1262
1263
1264
1265 if (temp->flags & FL_BONUS)
1266 switch (stats[mtype].type)
1267 {case stat_lifeitem1:
1268 case stat_lifeitem2:
1269 case stat_lifeitem3:
1270 case stat_lifeitem4:
1271 gamestate.treasuretotal++;
1272 break;
1273 default:
1274 ;
1275 }
1276
1277
1278
1279
1280 AddStatic(temp);
1281
1282 onetimer = ((mtype == stat_rubble) || (mtype == stat_woodfrag) ||
1283 (mtype == stat_metalfrag) || (mtype == stat_missmoke)
1284 );
1285
1286 if (DoPanicMapping())
1287 {
1288 if (temp->numanims && (!onetimer))
1289 {
1290 temp->flags &= ~FL_ACTIVE;
1291 temp->numanims = 0;
1292 GameRandomNumber("SpawnStatic",mtype);
1293 }
1294 }
1295
1296 else
1297 {
1298 if (temp->numanims)
1299 {
1300 if (!onetimer)
1301 temp->count = (int)(((int)GameRandomNumber("SpawnStatic",mtype) % stats[mtype].numanims) + 1);
1302 else
1303 temp->count = 0;
1304 }
1305 else if (temp->itemnumber == stat_standardpole)
1306 {
1307 if (MAPSPOT(temp->tilex,temp->tiley,2))
1308 temp->count = 2*(MAPSPOT(temp->tilex,temp->tiley,2)-14);
1309 else
1310 temp->count = 0;
1311 }
1312
1313 if ((temp->itemnumber == stat_knifestatue) ||
1314 (temp->itemnumber == stat_emptystatue) ||
1315 (temp->itemnumber == stat_standardpole))
1316 temp->flags|=FL_ROTATING;
1317 }
1318
1319
1320
1321
1322 if (mtype != stat_missmoke)
1323 sprites[tilex][tiley] = temp;
1324 else
1325 temp->flags |= FL_NONMARK;
1326
1327
1328 //================ check special junk ==================================//
1329
1330 if (temp->itemnumber == stat_dariantouch)
1331 {_2Dpoint *tdptr;
1332
1333 tdptr = &(MISCVARS->ETOUCH[MISCVARS->nexttouch]);
1334
1335 tdptr->x = tilex;
1336 tdptr->y = tiley;
1337 sprites[tilex][tiley]->linked_to = MISCVARS->nexttouch;
1338 MISCVARS->nexttouch ++;
1339 }
1340 else if ((temp->itemnumber >= stat_touch1) &&
1341 (temp->itemnumber <= stat_touch4))
1342 {touchindices[tilex][tiley] = lasttouch + 1;
1343 SD_PreCacheSoundGroup(SD_TOUCHPLATESND,SD_BADTOUCHSND);
1344 lasttouch ++;
1345 }
1346
1347 //=====================================================================//
1348
1349 PreCacheStaticFrames(temp);
1350
1351 PreCacheStaticSounds(temp->itemnumber);
1352
1353 if (temp->flags & FL_WEAPON)
1354 MISCVARS->NUMWEAPONS ++;
1355 }
1356 else
1357 Error("Z_LevelMalloc failed in SpawnStatic!");
1358
1359 }
1360
1361 /*
1362 ===============
1363 =
1364 = SpawnInertStatic
1365 =
1366 ===============
1367 */
1368
SpawnInertStatic(int x,int y,int z,int mtype)1369 void SpawnInertStatic (int x, int y, int z, int mtype)
1370 {statobj_t * temp;
1371
1372
1373
1374
1375 if (!firstemptystat)
1376 {temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL);
1377 //SoftError("\nMalloc-ing actor");
1378 //if (insetupgame)
1379 // SoftError("in setup");
1380 }
1381
1382 else
1383 {temp = lastemptystat;
1384 //SoftError("\nfree actor available");
1385 RemoveFromFreeStaticList(lastemptystat);
1386 }
1387
1388 if (temp)
1389 { memset(temp,0,sizeof(*temp));
1390 temp->shapenum = stats[mtype].picnum;
1391
1392 temp->whichstat = statcount ++;
1393 temp->tilex = x>>16;
1394 temp->tiley = y>>16;
1395 temp->x = x;
1396 temp->y = y;
1397 temp->areanumber = MAPSPOT(temp->tilex,temp->tiley,0)-AREATILE;
1398 temp->linked_to = -1;
1399 if ((temp->areanumber<=0) || (temp->areanumber>NUMAREAS))
1400 {
1401 int tilex=temp->tilex;
1402 int tiley=temp->tiley;
1403
1404 FindEmptyTile(&tilex,&tiley);
1405 temp->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE;
1406 }
1407 temp->z=z;
1408 temp->visspot = &spotvis[temp->tilex][temp->tiley];
1409 temp->which = SPRITE;
1410 temp->ticcount = stats[mtype].tictime;
1411 temp->hitpoints = stats[mtype].hitpoints;
1412 temp->itemnumber = stats[mtype].type;
1413 temp->flags = (stats[mtype].flags|FL_ABP|FL_NONMARK);
1414 if (fog)
1415 {temp->shapenum++;
1416 temp->flags &= ~FL_TRANSLUCENT;
1417 }
1418
1419 temp->ammo = stats[mtype].ammo;
1420 temp->numanims = stats[mtype].numanims;
1421 AddStatic(temp);
1422 MakeStatActive(temp);
1423 }
1424 else
1425 Error("Z_LevelMalloc failed in SpawnStatic!");
1426
1427 }
1428
1429 /*
1430 ===============
1431 =
1432 = SpawnSolidStatic
1433 =
1434 ===============
1435 */
1436
SpawnSolidStatic(statobj_t * temp)1437 void SpawnSolidStatic (statobj_t * temp)
1438 {
1439 if (temp->flags & FL_ACTIVE)
1440 temp->flags &= ~FL_ACTIVE;
1441 temp->hitpoints = INITIALFIRECOLOR;
1442 temp->flags = FL_SOLIDCOLOR|FL_SEEN|FL_ABP;
1443 if ((gamestate.BattleOptions.RespawnItems) &&
1444 (temp->itemnumber == stat_tntcrate)
1445 )
1446 temp->flags |= FL_RESPAWN;
1447
1448 temp->ticcount = SOLIDCOLORTICTIME;
1449 }
1450
1451
1452 /*
1453 ======================
1454 =
1455 = PreCacheStaticSounds
1456 =
1457 ======================
1458 */
1459
1460
1461
PreCacheStaticSounds(int itemnumber)1462 void PreCacheStaticSounds (int itemnumber)
1463 {
1464
1465 if (stats[itemnumber].flags & FL_SHOOTABLE)
1466 SD_PreCacheSound(SD_ITEMBLOWSND);
1467
1468
1469 switch(itemnumber)
1470
1471 {
1472 case stat_pit:
1473 SD_PreCacheSound(SD_PITTRAPSND);
1474 break;
1475
1476 case stat_bonusbarrel:
1477 SD_PreCacheSound(SD_BONUSBARRELSND);
1478 break;
1479
1480 case stat_knifestatue:
1481 SD_PreCacheSound(SD_GETKNIFESND);
1482 break;
1483 case stat_gibs1:
1484 case stat_gibs2:
1485 case stat_gibs3:
1486 SD_PreCacheSound (SD_ACTORSQUISHSND);
1487 break;
1488 case stat_pedgoldkey:
1489 case stat_pedsilverkey:
1490 case stat_pedironkey:
1491 case stat_pedcrystalkey:
1492 SD_PreCacheSound (SD_GETKEYSND);
1493
1494 break;
1495 case stat_monkmeal:
1496 SD_PreCacheSound (SD_GETHEALTH1SND);
1497 break;
1498 case stat_monkcrystal1:
1499 SD_PreCacheSound (SD_GETHEALTH2SND);
1500 break;
1501 case stat_monkcrystal2:
1502 SD_PreCacheSound (SD_GETHEALTH2SND);
1503 break;
1504 case stat_priestporridge:
1505 SD_PreCacheSound (SD_GETHEALTH1SND);
1506 SD_PreCacheSound(SD_COOKHEALTHSND);
1507
1508 break;
1509
1510 case stat_healingbasin:
1511 SD_PreCacheSound (SD_GETHEALTH2SND);
1512 break;
1513
1514 case stat_oneup:
1515 SD_PreCacheSound(SD_GET1UPSND);
1516 break;
1517 case stat_threeup:
1518 SD_PreCacheSound(SD_GET3UPSND);
1519 break;
1520
1521 case stat_scotthead:
1522 SD_PreCacheSound(SD_GETHEADSND);
1523 break;
1524
1525 case stat_twopistol:
1526 case stat_mp40:
1527 case stat_bazooka:
1528 case stat_firebomb:
1529 case stat_heatseeker:
1530 case stat_drunkmissile:
1531 case stat_firewall:
1532 case stat_splitmissile:
1533 case stat_kes:
1534 SD_PreCacheSound(SD_GETWEAPONSND);
1535 break;
1536
1537 case stat_bat:
1538 SD_PreCacheSound(SD_GETBATSND);
1539 break;
1540
1541 case stat_lifeitem1:
1542 case stat_lifeitem2:
1543 case stat_lifeitem3:
1544 case stat_lifeitem4:
1545 SD_PreCacheSound(SD_GETBONUSSND);
1546 break;
1547
1548
1549 case stat_random:
1550 SD_PreCacheSound(SD_GETGODSND);
1551 SD_PreCacheSound(SD_GETDOGSND);
1552 SD_PreCacheSound(SD_GETELASTSND);
1553 SD_PreCacheSound(SD_GETSHROOMSSND);
1554 SD_PreCacheSound(SD_LOSEMODESND);
1555
1556 break;
1557 case stat_bulletproof:
1558 SD_PreCacheSound(SD_GETBVESTSND);
1559 SD_PreCacheSound(SD_LOSEMODESND);
1560 break;
1561
1562 case stat_gasmask:
1563 SD_PreCacheSound(SD_GETMASKSND);
1564 SD_PreCacheSound(SD_LOSEMODESND);
1565 break;
1566
1567 case stat_asbesto:
1568 SD_PreCacheSound(SD_GETAVESTSND);
1569 SD_PreCacheSound(SD_LOSEMODESND);
1570 break;
1571
1572 case stat_elastic:
1573 SD_PreCacheSound(SD_GETELASTSND);
1574 SD_PreCacheSound(SD_LOSEMODESND);
1575 break;
1576
1577 case stat_fleetfeet:
1578 SD_PreCacheSound(SD_GETFLEETSND);
1579 SD_PreCacheSound(SD_LOSEMODESND);
1580 break;
1581
1582 case stat_godmode:
1583 SD_PreCacheSound(SD_GETGODSND);
1584 SD_PreCacheSound(SD_GODMODE1SND);
1585
1586 break;
1587
1588 case stat_dogmode:
1589 SD_PreCacheSound(SD_GETDOGSND);
1590 break;
1591
1592 case stat_mushroom:
1593 SD_PreCacheSound(SD_GETSHROOMSSND);
1594 SD_PreCacheSound(SD_LOSEMODESND);
1595
1596 break;
1597
1598 case stat_dipball1:
1599 case stat_dipball2:
1600 case stat_dipball3:
1601 SD_PreCacheSound(SD_GETBONUSSND);
1602 break;
1603
1604 default:
1605 SD_PreCacheSound(SD_GETBONUSSND);
1606 break;
1607 }
1608
1609 }
1610
1611
1612
1613
1614
1615 /*
1616 ===============
1617 =
1618 = SaveSwitches
1619 =
1620 ===============
1621 */
1622
SaveSwitches(byte ** buffer,int * size)1623 void SaveSwitches(byte ** buffer, int * size)
1624 {int numswitches,i;
1625 byte * tptr;
1626
1627 numswitches = lastswitch-&switches[0];
1628 if (numswitches==0)
1629 {
1630 *size=0;
1631 *buffer=SafeMalloc(16);
1632 return;
1633 }
1634 *size = numswitches*sizeof(wall_t);
1635
1636 *buffer = (byte *)SafeMalloc(*size);
1637 tptr = *buffer;
1638
1639 for(i=0;i<numswitches;i++)
1640 {memcpy(tptr,&switches[i],sizeof(wall_t));
1641 tptr += sizeof(wall_t);
1642 }
1643
1644 }
1645
1646
1647 /*
1648 ===============
1649 =
1650 = LoadSwitches
1651 =
1652 ===============
1653 */
1654
LoadSwitches(byte * buffer,int size)1655 void LoadSwitches (byte * buffer, int size)
1656 {int numswitches,i,tilex,tiley;
1657
1658 numswitches = size/sizeof(wall_t);
1659
1660 for(i=0;i<numswitches;i++)
1661 {memcpy(&switches[i],buffer,sizeof(wall_t));
1662 tilex = switches[i].tilex;
1663 tiley = switches[i].tiley;
1664 actorat[tilex][tiley]=&switches[i];
1665 if (MAPSPOT(tilex,tiley,0) == 79) // On by default
1666 {
1667 if (!(switches[i].flags & FL_ON))
1668 tilemap[tilex][tiley]--;
1669 }
1670 else if (switches[i].flags & FL_W_INVERTED) // Hi masked wall
1671 {
1672 maskedwallobj_t * lastmaskobj;
1673
1674 lastmaskobj=maskobjlist[tilemap[tilex][tiley]&0x3ff];
1675 if (switches[i].flags & FL_ON)
1676 lastmaskobj->toptexture++;
1677 }
1678 else if (switches[i].flags & FL_ON)
1679 tilemap[tilex][tiley]++;
1680 buffer += sizeof(wall_t);
1681 touchindices[tilex][tiley] = lasttouch + 1;
1682 lasttouch ++;
1683 }
1684 lastswitch=&switches[numswitches];
1685
1686 }
1687
1688
1689
1690 /*
1691 ===============
1692 =
1693 = SpawnSwitchThingy
1694 =
1695 ===============
1696 */
1697
SpawnSwitchThingy(int tilex,int tiley)1698 void SpawnSwitchThingy(int tilex, int tiley)
1699 {
1700 lastswitch->flags |= FL_SWITCH;
1701 lastswitch->which = WALL;
1702 lastswitch->tilex = tilex;
1703 lastswitch->tiley = tiley;
1704 touchindices[tilex][tiley] = lasttouch + 1;
1705 lasttouch ++;
1706 actorat[tilex][tiley] = lastswitch;
1707 lastswitch ++;
1708
1709 }
1710
1711 /*
1712 ===============
1713 =
1714 = AnimateWalls
1715 =
1716 ===============
1717 */
1718
AnimateWalls(void)1719 void AnimateWalls(void)
1720 {
1721 int i;
1722 animwall_t * aw;
1723
1724 if (DoPanicMapping()==true)
1725 return;
1726
1727 for(i=0;i<MAXANIMWALLS;i++)
1728 {
1729 aw=&animwalls[i];
1730 if (aw->active==0)
1731 continue;
1732 if (aw->ticcount <= 0)
1733 {
1734 if (aw->count < animwallsinfo[i].numanims)
1735 {
1736 aw->texture = aw->basetexture + aw->count;
1737 aw->count++;
1738 }
1739 else
1740 {
1741 aw->texture = aw->basetexture;
1742 aw->count = 1;
1743 }
1744
1745 while (aw->ticcount<=0)
1746 aw->ticcount+=animwallsinfo[i].tictime;
1747 }
1748 else
1749 aw->ticcount -= tics;
1750 }
1751 }
1752
1753
1754 #define M_ResetSprites(x) \
1755 { if ((index == stat_dariantouch) && (!x->count))\
1756 {x->shapenum = stats[index].picnum; \
1757 x->count = 1; \
1758 x->ticcount = stats[index].tictime; \
1759 x->flags &= ~FL_BACKWARDS; \
1760 x->flags &= ~FL_ACTIVE; \
1761 } \
1762 }
1763
1764
1765
1766
CheckCriticalStatics(void)1767 void CheckCriticalStatics(void)
1768 {respawn_t *rtemp,*ddt;
1769 int i,stilex,stiley;
1770 statobj_t*temp,*stat;
1771
1772 for(rtemp = firstrespawn;rtemp;)
1773 {rtemp->ticcount --;
1774 ddt = rtemp->next;
1775
1776 if (rtemp->ticcount <=0)
1777 {int stype;
1778
1779 stilex = rtemp->tilex;
1780 stiley = rtemp->tiley;
1781
1782 // if another weapon is there, nuke it
1783 if (sprites[stilex][stiley])
1784 {RemoveStatic(sprites[stilex][stiley]);
1785 sprites[stilex][stiley] = NULL;
1786 }
1787
1788 if (rtemp->itemnumber == stat_tntcrate)
1789 {
1790 RemoveStatic((statobj_t*)(rtemp->linked_to));
1791 stype = stat_tntcrate;
1792 }
1793 else
1794 {
1795 for(i=0;i<NUMSTATS;i++)
1796 {
1797 if (rtemp->itemnumber == stats[i].type)
1798 {
1799 stype = i;
1800 break;
1801 }
1802 }
1803
1804 }
1805
1806 SpawnStatic(stilex,stiley,stype,-1);
1807 LASTSTAT->z = rtemp->spawnz;
1808 LASTSTAT->flags |= FL_ABP;
1809 MakeStatActive(LASTSTAT);
1810 SpawnNewObj(stilex,stiley,&s_itemspawn1,inertobj);
1811 SD_PlaySoundRTP(SD_RESPAWNSND,new->x,new->y);
1812 new->flags |= FL_ABP;
1813 MakeActive(new);
1814 new->z = LASTSTAT->z;
1815 RemoveRespawnStatic(rtemp);
1816 }
1817
1818 rtemp = ddt;
1819 }
1820
1821 for (temp = firstactivestat ; temp; )
1822 {stat = temp->nextactive;
1823
1824 if (temp->flags & FL_SOLIDCOLOR)
1825 {temp->ticcount--;
1826 if (temp->ticcount<=0)
1827 {temp->hitpoints+=SOLIDCOLORINCREMENT;
1828 if (temp->hitpoints>MAXFIRECOLOR)
1829 RemoveStatic(temp);
1830 else
1831 temp->ticcount = SOLIDCOLORTICTIME;
1832 }
1833 }
1834 temp = stat;
1835 }
1836
1837
1838 }
1839
1840
1841
1842 /*
1843 ===============
1844 =
1845 = DoSprites
1846 =
1847 ===============
1848 */
1849
DoSprites(void)1850 void DoSprites(void)
1851 {int index,i;
1852 statobj_t *temp,*tempnext;
1853
1854
1855 #if (0)
1856 Debug("\n");
1857 #endif
1858 i=0;
1859 for(temp = firstactivestat;temp;)
1860 {tempnext = temp->nextactive;
1861
1862 #if (0)
1863 Debug("\nid: %d, shapenum: %d, numanims: %d",i++,temp->shapenum,temp->numanims);
1864 #endif
1865
1866 if ((temp->shapenum != NOTHING) && (temp->flags & FL_ACTIVE))
1867 {index = temp->itemnumber;
1868 temp->ticcount -= tics;
1869 while (temp->ticcount <= 0)
1870 {if (temp->count < temp->numanims)
1871 {temp->shapenum = stats[index].picnum + temp->count;
1872 if (index == stat_missmoke)
1873 {RemoveStatic(temp);
1874 break;
1875 }
1876
1877 if (((index == stat_rubble) && (temp->count == 9)) ||
1878 ((index == stat_woodfrag) && (temp->count == 13)) ||
1879 ((index == stat_metalfrag) && (temp->count == 9)))
1880 {temp->flags &= ~FL_ACTIVE;
1881 break;
1882 }
1883
1884 if (temp->flags & FL_BACKWARDS)
1885 {temp->count--;
1886 M_ResetSprites(temp);
1887 }
1888 else
1889 temp->count ++;
1890 }
1891 else if (!(temp->flags & FL_BANDF))
1892 {temp->shapenum = stats[index].picnum;
1893 temp->count=1;
1894 }
1895 else
1896 {temp->flags |= FL_BACKWARDS;
1897 temp->count --;
1898 }
1899 temp->ticcount += stats[index].tictime;
1900 }
1901 }
1902 temp = tempnext;
1903
1904 }
1905
1906 }
1907
SpawnStaticDamage(statobj_t * stat,int angle)1908 void SpawnStaticDamage(statobj_t * stat, int angle)
1909 {
1910 GetNewActor ();
1911 MakeActive(new);
1912 NewState(new,&s_gunsmoke1);
1913
1914 new->obclass = inertobj;
1915 new->which = ACTOR;
1916 new->x = (stat->x)-(costable[angle]>>4);
1917 new->y = (stat->y)+(sintable[angle]>>4);
1918 new->z = (stat->z)+stats[stat->itemnumber].heightoffset;
1919 new->drawx = new->x;
1920 new->drawy = new->y;
1921 new->tilex = (new->x >> TILESHIFT);
1922 new->tiley = (new->y >> TILESHIFT);
1923 new->dir = 0;
1924 new->speed = 0;
1925 new->flags = (FL_NEVERMARK|FL_ABP);
1926 if ((new->x<=0) || (new->y<=0))
1927 Error("SpawnStaticDamage: bad x,y itemnumber=%ld\n",stat->itemnumber);
1928 }
1929