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