ref: d7f038fe0566c8239ec0b2ca1e56686476e82e09
dir: /src/rt_stat.c/
/* Copyright (C) 1994-1995 Apogee Software, Ltd. Copyright (C) 2002-2015 icculus.org, GNU/Linux port Copyright (C) 2017-2018 Steven LeVesque This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. You should have received a copy of the GNU General Public License along with this program. If not, see <https://www.gnu.org/licenses/>. */ #include "rt_def.h" #include <string.h> #include "sprites.h" #include <stdio.h> #include <stdlib.h> #include "rt_stat.h" #include "z_zone.h" #include "lumpy.h" #include "rt_util.h" #include "rt_draw.h" #include "rt_ted.h" #include "rt_door.h" #include "rt_main.h" #include "w_wad.h" #include "rt_main.h" #include "rt_rand.h" #include "rt_menu.h" #include "rt_sound.h" #include "_rt_stat.h" #include "rt_net.h" #include "rt_view.h" #include "isr.h" /* ============================================================================= Global Variables GLOBAL VARIABLES ============================================================================= */ statobj_t *firstactivestat,*lastactivestat; statobj_t *firstemptystat,*lastemptystat; wall_t switches[MAXSWITCHES],*lastswitch; respawn_t *firstrespawn,*lastrespawn; statobj_t *FIRSTSTAT,*LASTSTAT,*sprites[MAPSIZE][MAPSIZE]; animwall_t animwalls[MAXANIMWALLS]; dirtype opposite[9] = {west,southwest,south,southeast,east,northeast,north,northwest,nodir}; statinfo stats[NUMSTATS] = { {0,SPR0_YLIGHT, stat_ylight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0}, {0,SPR1_RLIGHT, stat_rlight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0}, {0,SPR2_GLIGHT, stat_glight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0}, {0,SPR3_BLIGHT, stat_blight,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0}, {0,SPR4_CHAND, stat_chandelier,FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0}, {0,SPR5_LAMPOFF, stat_lamp,FL_LIGHT|FL_BLOCK|FL_SHOOTABLE,0,0,2,0,0}, {0,SPR73_GKEY1, stat_pedgoldkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_orange,0,0}, {0,SPR73_GKEY1,stat_pedsilverkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_gray,0,0}, {0,SPR73_GKEY1, stat_pedironkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_olive,0,0}, {0,SPR73_GKEY1,stat_pedcrystalkey,FL_COLORED|FL_BONUS|FL_CHANGES|FL_BLOCK|FL_ACTIVE,2,16,pc_red,0,0}, {0,SPR6_GIBS1, stat_gibs1,0,0,0,0,0,0}, {0,SPR7_GIBS2, stat_gibs2,0,0,0,0,0,0}, {0,SPR8_GIBS3, stat_gibs3,0,0,0,0,0,0}, {0,SPR9_MONKMEAL, stat_monkmeal,FL_BONUS|FL_RESPAWN,0,0,0,0,0}, {0,PORRIDGE1, stat_priestporridge,FL_BONUS|FL_RESPAWN,2,6,0,0,0}, {0,MONKCRYSTAL11,stat_monkcrystal1,FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,6,0,0,0}, {0,MONKCRYSTAL21,stat_monkcrystal2,FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,7,0,0,0}, {0,ONEUP01,stat_oneup,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,2,8,0,0,0}, {0,THREEUP01,stat_threeup,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,2,8,0,0,0}, {0,TORCH1,stat_altbrazier1,FL_HEAT|FL_BLOCK|FL_ACTIVE|FL_LIGHT|FL_SHOOTABLE,2,15,2,0,0}, {0,SPR_ABRAZIER2,stat_altbrazier2,FL_HEAT|FL_BLOCK|FL_LIGHT|FL_SHOOTABLE,0,0,2,0,0}, {0,FBASIN1,stat_healingbasin,FL_BONUS|FL_CHANGES|FL_ACTIVE|FL_BLOCK,2,3,0,0,0}, {20,EBASIN,stat_emptybasin,FL_BLOCK|FL_SHOOTABLE,0,0,0,0,0}, {0,BAT1,stat_bat,FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_WEAPON,1,16,0,0,10}, {0,KNIFE_STATUE1,stat_knifestatue,FL_BONUS|FL_CHANGES|FL_BLOCK,0,0,0,0,0}, {0,SPR_TWOPIST,stat_twopistol,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5}, {0,SPR_MP40,stat_mp40,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5}, {0,SPR_BAZOOKA,stat_bazooka,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,10}, {0,SPR_FIREBOMB,stat_firebomb,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5}, {0,SPR_HEATSEEK,stat_heatseeker,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7}, {0,SPR_DRUNK,stat_drunkmissile,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7}, {0,SPR_FIREWALL,stat_firewall,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,5}, {0,SPR_SPLIT,stat_splitmissile,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7}, {0,SPR_KES,stat_kes,FL_BONUS|FL_RESPAWN|FL_WEAPON,0,0,0,0,7}, {0,LIFEITEMA01,stat_lifeitem1,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0}, {0,LIFEITEMB01,stat_lifeitem2,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0}, {0,LIFEITEMD01,stat_lifeitem3,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,8, 2,0,0}, {0,LIFEITEMC01,stat_lifeitem4,FL_BONUS|FL_ACTIVE|FL_SHOOTABLE|FL_FULLLIGHT,2,15, 2,0,0}, {24,SPR32_EXPLOS,stat_tntcrate,FL_SHOOTABLE|FL_BLOCK|FL_WOODEN,0,0,3,10,0}, {12,SPR33_CBARREL,stat_bonusbarrel,FL_METALLIC|FL_SHOOTABLE|FL_BLOCK,0,0,3,10,0}, {0,TORCH1,stat_torch,FL_BLOCK|FL_LIGHT|FL_ACTIVE|FL_HEAT|FL_SHOOTABLE,2,15,2,0,0}, {30,FFLAME1,stat_floorfire,FL_HEAT|FL_BLOCK|FL_LIGHT|FL_ACTIVE|FL_SHOOTABLE,2,7,30,0,0}, {0,DIP11,stat_dipball1,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0}, {0,DIP21,stat_dipball2,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0}, {0,DIP31,stat_dipball3,FL_BONUS|FL_FULLLIGHT,0,0,0,0,0}, {0,SPR34_TOUCH1,stat_touch1,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0}, {0,SPR35_TOUCH2,stat_touch2,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0}, {0,SPR36_TOUCH3,stat_touch3,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0}, {0,SPR37_TOUCH4,stat_touch4,0|FL_TRANSLUCENT|FL_FADING,0,0,0,0,0}, {20,SPR62_ETOUCH1,stat_dariantouch,FL_METALLIC|FL_BANDF|FL_SHOOTABLE|FL_BLOCK,10,3,50,0,0}, {0,SCOTHEAD1, stat_scotthead,FL_BONUS|FL_ACTIVE|FL_FULLLIGHT,4,7,0,0,0}, {0,SPR38_GARBAGE1,stat_garb1,0,0,0,0,0,0}, {0,SPR39_GARBAGE2,stat_garb2,0,0,0,0,0,0}, {0,SPR40_GARBAGE3,stat_garb3,0,0,0,0,0,0}, {0,SPR41_SHIT,stat_shit,0,0,0,0,0,0}, {0,SPR42_GRATE,stat_grate,0,0,0,0,0,0}, {0,SPR43_MSHARDS,stat_metalshards,0,0,0,0,0,0}, {20,SPR44_PEDESTAL,stat_emptypedestal,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,60,0,0}, {20,SPR45_ETABLE,stat_emptytable,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,100,0,0}, {16,SPR46_STOOL,stat_stool,FL_BLOCK|FL_SHOOTABLE|FL_WOODEN,0,0,25,0,0}, {0,SPR_PUSHCOLUMN1,stat_bcolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0}, {0,SPR_PUSHCOLUMN1,stat_gcolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0}, {0,SPR_PUSHCOLUMN1,stat_icolumn,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0}, {20,SPR50_TREE,stat_tree,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0}, {20,SPR51_PLANT,stat_plant,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0}, {20,BLUEVASE,stat_urn,FL_SHOOTABLE|FL_BLOCK,0,0,0,0,0}, {0,SPR54_HAY,stat_haystack,FL_SHOOTABLE|FL_BLOCK,0,0,20,0,0}, {12,SPR55_IBARREL,stat_ironbarrel,FL_METALLIC|FL_BLOCK|FL_SHOOTABLE,0,0,50,0,0}, {0,HGRATE1,stat_heatgrate,FL_LIGHT|FL_ACTIVE,2,4,0,5,0}, {-10,STNPOLE1,stat_standardpole,FL_SHOOTABLE|FL_BLOCK,0,0,25,0,0}, {0,PREPIT,stat_pit,FL_CHANGES,0,0,0,0,0}, {0,GODPOWERUP1,stat_godmode,FL_WEAPON|FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0}, {0,DOGPOWERUP1,stat_dogmode,FL_WEAPON|FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0}, {0,FLEETFEETPOWERUP1,stat_fleetfeet,FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0}, {0,ELASTICPOWERUP1, stat_elastic, FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0}, {0,MUSHROOMPOWERUP1, stat_mushroom, FL_BONUS|FL_ACTIVE|FL_RESPAWN|FL_FULLLIGHT,2,8,0,0,0}, {0,GASMASKPOWERUP, stat_gasmask, FL_BONUS|FL_RESPAWN,0,0,0,0,0}, {0,BULLETPROOFPOWERUP, stat_bulletproof, FL_BONUS|FL_RESPAWN,0,0,0,0,0}, {0,ASBESTOSPOWERUP, stat_asbesto, FL_BONUS|FL_RESPAWN,0,0,0,0,0}, {0,RANDOMPOWERUP1, stat_random, FL_BONUS|FL_ACTIVE|FL_RESPAWN,2,8,0,0,0}, {0,RUBBLE1, stat_rubble, FL_ACTIVE,2,10,0,0,0}, {0,WOODFRAG1, stat_woodfrag, FL_ACTIVE,2,14,0,0,0}, {0,ROBOGRDDIE1, stat_metalfrag, FL_ACTIVE,2,10,0,0,0}, {0,EMPTY_STATUE1,stat_emptystatue,FL_BLOCK|FL_SHOOTABLE,0,0,50,0,0}, {16,TOMLARVA1,stat_tomlarva,FL_ACTIVE|FL_SHOOTABLE|FL_BLOCK,2,4,150,0,0}, {0,BULLETHOLE,stat_bullethole,FL_TRANSLUCENT,0,0,0,0,0}, #if (SHAREWARE == 1) {0,COLLECTOR1,stat_collector,FL_ACTIVE|FL_BONUS,2,8,-1,0,0}, #else {0,DOPE1,stat_collector,FL_ACTIVE|FL_BONUS,2,8,-1,0,0}, #endif {0,SPR_MINE1,stat_mine,FL_BONUS|FL_SHOOTABLE|FL_RESPAWN,0,0,10,0,0}, {0,MISSMOKE1,stat_missmoke,FL_ACTIVE,6,4,0,0,0}, {0,PLATFORM1,stat_disk,FL_BLOCK|FL_HEIGHTFLIPPABLE,0,0,0,0,0}, {-1,0,0,0,0,0,0,0,0} }; dirtype diagonal[9][9] = { /* east */ {nodir,nodir,northeast,nodir,nodir,nodir,southeast,nodir,nodir}, {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, /* north */ {northeast,nodir,nodir,nodir,northwest,nodir,nodir,nodir,nodir}, {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, /* west */ {nodir,nodir,northwest,nodir,nodir,nodir,southwest,nodir,nodir}, {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, /* south */ {southeast,nodir,nodir,nodir,southwest,nodir,nodir,nodir,nodir}, {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir}, {nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir,nodir} }; /* ============================================================================= Local Variables GLOBAL VARIABLES ============================================================================= */ static awallinfo_t animwallsinfo[MAXANIMWALLS] = { {3,4,"FPLACE1\0"}, //lava wall {3,6,"ANIMY1\0"}, //anim red {3,6,"ANIMR1\0"}, //anim yellow {40,4,"ANIMFAC1\0"}, //anim face {3,4,"ANIMONE1\0"}, //anim one {3,4,"ANIMTWO1\0"}, //anim two {3,4,"ANIMTHR1\0"}, //anim three {3,4,"ANIMFOR1\0"}, //anim four {3,6,"ANIMGW1\0"}, //anim grey water {3,6,"ANIMYOU1\0"}, //anim you do not belong {3,6,"ANIMBW1\0"}, //anim brown water {3,6,"ANIMBP1\0"}, //anim brown piston {3,6,"ANIMCHN1\0"}, //anim chain {3,6,"ANIMFW1\0"}, //anim firewall {3,6,"ANIMLAT1\0"}, //anim little blips {3,6,"ANIMST1\0"}, //anim light streams left {3,6,"ANIMRP1\0"} };//anim light streams right int statcount; void AddRespawnStatic(respawn_t*stat); void DoLights (int tilex, int tiley); void AddToFreeStaticList(statobj_t*stat) { if (!firstemptystat) firstemptystat = stat; else { stat->statprev = lastemptystat; lastemptystat->statnext = stat; } lastemptystat = stat; } void RemoveFromFreeStaticList(statobj_t*stat) { if (stat == lastemptystat) lastemptystat = stat->statprev; else stat->statnext->statprev = stat->statprev; if (stat == firstemptystat) firstemptystat = stat->statnext; else stat->statprev->statnext = stat->statnext; stat->statprev = NULL; stat->statnext = NULL; } /* =============== = = MakeStatActive = =============== */ void MakeStatActive(statobj_t*x) { if (!firstactivestat) firstactivestat = x; else { x->prevactive = lastactivestat; lastactivestat->nextactive = x; } lastactivestat = x; } /* =============== = = MakeStatInactive = =============== */ void MakeStatInactive(statobj_t*stat) { if (stat == lastactivestat) lastactivestat = stat->prevactive; else stat->nextactive->prevactive = stat->prevactive; if (stat == firstactivestat) firstactivestat = stat->nextactive; else stat->prevactive->nextactive = stat->nextactive; stat->prevactive = NULL; stat->nextactive = NULL; } /* =============== = = AddStatic = =============== */ void AddStatic(statobj_t *stat) { if (FIRSTSTAT) { stat->statprev = LASTSTAT; LASTSTAT->statnext = stat; } else FIRSTSTAT = stat; LASTSTAT = stat; } void RemoveStatic(statobj_t*stat) { if (stat->flags & FL_ABP) //remove from active list MakeStatInactive(stat); if (stat == LASTSTAT) // remove from master list LASTSTAT = stat->statprev; else stat->statnext->statprev = stat->statprev; if (stat == FIRSTSTAT) FIRSTSTAT = stat->statnext; else stat->statprev->statnext = stat->statnext; stat->statprev = NULL; stat->statnext = NULL; if (stat->flags & FL_WEAPON) MISCVARS->NUMWEAPONS --; if ((stat->flags & FL_RESPAWN) && gamestate.BattleOptions.RespawnItems && (!((stat->flags & FL_WEAPON ) && (gamestate.BattleOptions.WeaponPersistence) ) ) ) { respawn_t*temp; // if ( !( (stat->flags & FL_WEAPON) && // (MISCVARS->NUMWEAPONS >= (numplayers+10)) // ) // ) { temp = (respawn_t*)Z_LevelMalloc(sizeof(respawn_t),PU_LEVELSTRUCT,NULL); memset (temp,0,sizeof(*temp)); temp->ticcount = GetRespawnTimeForItem(stat->itemnumber); temp->tilex = stat->tilex; temp->tiley = stat->tiley; temp->itemnumber = stat->itemnumber; temp->spawnz = stat->z; temp->linked_to = stat->linked_to; //SoftError("\nrespawn obj created for stattype %d with z = %d",stat->itemnumber,temp->spawnz); AddRespawnStatic(temp); } } //Z_Free(stat); AddToFreeStaticList(stat); //Add_To_Delete_Array(stat); statcount --; } void RemoveRespawnStatic(respawn_t*stat) { if (stat == lastrespawn) lastrespawn = stat->prev; else stat->next->prev = stat->prev; if (stat == firstrespawn) firstrespawn = stat->next; else stat->prev->next = stat->next; stat->prev = NULL; stat->next = NULL; Z_Free(stat); } void TurnOffLight(int tilex,int tiley) { DoLights(tilex,tiley); LightsInArea[MAPSPOT(tilex,tiley,0)-AREATILE]--; } void ActivateLight(long light) { statobj_t*tstat; tstat = (statobj_t*)light; tstat->shapenum ++; tstat->flags |= FL_LIGHTON; TurnOnLight(tstat->tilex,tstat->tiley); } void DeactivateLight(long light) { statobj_t*tstat; tstat = (statobj_t*)light; tstat->shapenum --; tstat->flags &= ~(FL_LIGHTON); TurnOffLight(tstat->tilex,tstat->tiley); } void TurnOnLight(int i,int j) { LightsInArea[MAPSPOT(i,j,0)-AREATILE]++; if (lightsource==0) return; if ((!(tilemap[i+1][j])) && (!(tilemap[i-1][j]))) { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0x135789ab); SetLight(i-1,j,0xba987351); SetLight(i,j+1,0xcdeffedc); SetLight(i,j-1,0xcdeffedc); SetLight(i-1,j-1,0xba987351); SetLight(i+1,j+1,0xba987351); SetLight(i+1,j-1,0x135789ab); SetLight(i-1,j+1,0x135789ab); } else if ((!(tilemap[i][j+1])) && (!(tilemap[i][j-1]))) { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0xcdeffedc); SetLight(i-1,j,0xcdeffedc); SetLight(i,j+1,0x135789ab); SetLight(i,j-1,0xba987531); SetLight(i-1,j-1,0x135789ab); SetLight(i+1,j-1,0xba987531); SetLight(i+1,j+1,0x135789ab); SetLight(i-1,j+1,0xba987531); } // | //__| else if ((tilemap[i][j+1]) && (tilemap[i+1][j])) { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0xcdeffedc); SetLight(i-1,j,0xcdeffedc); SetLight(i,j+1,0xcdeffedc); SetLight(i,j-1,0xcdeffedc); SetLight(i-1,j-1,0xba987351); SetLight(i+1,j-1,0xba987351); SetLight(i+1,j+1,0xba987351); SetLight(i-1,j+1,0x135789ab); } //| //|_ else if ((tilemap[i][j+1]) && (tilemap[i-1][j])) { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0xcdeffedc); SetLight(i-1,j,0xcdeffedc); SetLight(i,j+1,0xcdeffedc); SetLight(i,j-1,0xcdeffedc); SetLight(i-1,j-1,0x135789ab); SetLight(i+1,j-1,0xba987531); SetLight(i+1,j+1,0xba987531); SetLight(i-1,j+1,0xba987531); } //_ // | else if ((tilemap[i][j-1]) && (tilemap[i+1][j])) { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0xcdeffedc); SetLight(i-1,j,0xcdeffedc); SetLight(i,j+1,0xcdeffedc); SetLight(i,j-1,0xcdeffedc); SetLight(i-1,j-1,0xba987531); SetLight(i+1,j-1,0x135789ab); SetLight(i+1,j+1,0x135789ab); SetLight(i-1,j+1,0xba987531); } //__ //| else if ((tilemap[i][j-1]) && (tilemap[i-1][j])) { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0xcdeffedc); SetLight(i-1,j,0xcdeffedc); SetLight(i,j+1,0xcdeffedc); SetLight(i,j-1,0xcdeffedc); SetLight(i-1,j-1,0x135789ab); SetLight(i+1,j-1,0x135789ab); SetLight(i+1,j+1,0xba987531); SetLight(i-1,j+1,0xba987531); } else if (tilemap[i][j]) { SetLight(i,j,0x58bffb85); } else { SetLight(i,j,0xcdeffedc); SetLight(i+1,j,0xba987654); SetLight(i-1,j,0x456789ab); SetLight(i,j+1,0xba987654); SetLight(i,j-1,0x456789ab); SetLight(i-1,j+1,0x33322211); SetLight(i+1,j+1,0x33322211); SetLight(i+1,j-1,0x11222333); SetLight(i-1,j-1,0x11222333); } } /*=============== = = AddRespawnStatic = =============== */ void AddRespawnStatic(respawn_t*stat) { if (firstrespawn) { stat->prev = lastrespawn; lastrespawn->next = stat; } else firstrespawn = stat; lastrespawn = stat; } /* =============== = = InitStaticList = =============== */ void InitStaticList (void) { FIRSTSTAT = NULL; LASTSTAT = NULL; lastactivestat = NULL; firstactivestat = NULL; firstrespawn = NULL; lastrespawn = NULL; lastemptystat = NULL; firstemptystat = NULL; memset(&BulletHoles[0],0,sizeof(BulletHoles)); MISCVARS->BulletHoleNum = 0; memset(sprites,0,sizeof(sprites)); if (loadedgame==false) { memset(switches,0,sizeof(switches)); lastswitch = &switches[0]; } statcount = 0; } /* =============== = = InitAnimatedWallList = =============== */ void InitAnimatedWallList(void) { int i; for (i=0; i<MAXANIMWALLS; i++) animwalls[i].active=0; } /* =============== = = SetupAnimatedWall = =============== */ void SetupAnimatedWall(int which) { animwall_t * aw; int i; int texture; aw = &animwalls[which]; aw->active=1; aw->ticcount=animwallsinfo[which].tictime; aw->count = 1; texture=W_GetNumForName(animwallsinfo[which].firstlump); aw->basetexture=texture; aw->texture=texture; if (DoPanicMapping()==true) { PreCacheLump(aw->basetexture,PU_CACHEWALLS,cache_pic_t); } else { for (i=aw->basetexture; i<aw->basetexture+animwallsinfo[which].numanims; i++) PreCacheLump(i,PU_CACHEWALLS,cache_pic_t); } } /* =============== = = SaveStatics = =============== */ void SaveStatics (byte **buffer, int * size) { statobj_t * temp; saved_stat_type dummy; byte * tptr; int count; if (statcount==0) { *size=0; *buffer=SafeMalloc(16); return; } *size = statcount*sizeof(saved_stat_type); *buffer = (byte *)SafeMalloc(*size); tptr = *buffer; for(count=0,temp=FIRSTSTAT; temp; temp=temp->statnext) { dummy.x = temp->x; dummy.y = temp->y; dummy.z = temp->z; dummy.flags = temp->flags; dummy.ticcount = temp->ticcount; dummy.hitpoints = temp->hitpoints; dummy.shapenum = temp->shapenum; dummy.ammo = temp->ammo; dummy.count = temp->count; dummy.numanims = temp->numanims; dummy.itemnumber = temp->itemnumber; dummy.areanumber = temp->areanumber; temp->whichstat = count; dummy.whichstat = count++; dummy.linked_to = temp->linked_to; memcpy(tptr,&(dummy.x),sizeof(saved_stat_type)); tptr += sizeof(saved_stat_type); } } /* =============== = = DoLights = =============== */ void DoLights (int tilex, int tiley) { if (lightsource==0) return; if (TurnOffLight0 (tilex, tiley)) LightSourceAt(tilex,tiley) = 0; if (TurnOffLight1 (tilex, tiley, -1, -1)) LightSourceAt(tilex-1,tiley-1) = 0; if (TurnOffLight2 (tilex, tiley, -1)) LightSourceAt(tilex,tiley-1) = 0; if (TurnOffLight1 (tilex, tiley, 1, -1)) LightSourceAt(tilex+1,tiley-1) = 0; if (TurnOffLight3 (tilex, tiley, 1)) LightSourceAt(tilex+1,tiley) = 0; if (TurnOffLight1 (tilex, tiley, 1, 1)) LightSourceAt(tilex+1,tiley+1) = 0; if (TurnOffLight2 (tilex, tiley, 1)) LightSourceAt(tilex,tiley+1) = 0; if (TurnOffLight1 (tilex, tiley, -1, 1)) LightSourceAt(tilex-1,tiley+1) = 0; if (TurnOffLight3 (tilex, tiley, -1)) LightSourceAt(tilex-1,tiley) = 0; } /* =============== = = TurnOffLight0 = =============== */ boolean TurnOffLight0 (int tilex, int tiley) { if ( IsLight(tilex-1,tiley ) || IsLight(tilex-1,tiley-1) || IsLight(tilex,tiley-1) || IsLight(tilex+1,tiley-1) || IsLight(tilex+1,tiley ) || IsLight(tilex+1,tiley+1) || IsLight(tilex,tiley+1) || IsLight(tilex-1,tiley+1) ) return (false); else return (true); } /* =============== = = TurnOffLight1 = =============== */ boolean TurnOffLight1 (int tilex, int tiley, int i, int j) { int tempi = 2*i; int tempy = 2*j; if ( IsLight(tilex+i,tiley ) || IsLight(tilex+i,tiley+j) || IsLight(tilex,tiley+j) || IsLight(tilex,tiley+tempy) || IsLight(tilex+i,tiley+tempy) || IsLight(tilex+tempi,tiley+tempy) || IsLight(tilex+tempi,tiley+j) || IsLight(tilex+tempi,tiley)) return (false); else return (true); } /* =============== = = TurnOffLight2 = =============== */ boolean TurnOffLight2 (int tilex, int tiley, int j) { int tempy = 2*j; if ( IsLight(tilex-1,tiley ) || IsLight(tilex-1,tiley+j) || IsLight(tilex-1,tiley+tempy) || IsLight(tilex,tiley+j) || IsLight(tilex,tiley+tempy) || IsLight(tilex+1,tiley) || IsLight(tilex+1,tiley+j) || IsLight(tilex+1,tiley+tempy)) return (false); else return (true); } /* =============== = = TurnOffLight3 = =============== */ boolean TurnOffLight3 (int tilex, int tiley, int i) { int tempx = 2*i; if ( IsLight(tilex,tiley-1) || IsLight(tilex+1,tiley-1) || IsLight(tilex+tempx,tiley-1) || IsLight(tilex+i,tiley) || IsLight(tilex+tempx,tiley) || IsLight(tilex,tiley+1) || IsLight(tilex+i,tiley+1) || IsLight(tilex+tempx,tiley+1)) return (false); else return (true); } /* ====================== = = PreCacheStaticFrames = ====================== */ void PreCacheStaticFrames(statobj_t*temp) { int z,start,stop; int female=0,black=0; if (temp->itemnumber != stat_bullethole && ((temp->itemnumber < stat_touch1) || (temp->itemnumber > stat_touch4))) PreCacheLump(temp->shapenum+shapestart,PU_CACHESPRITES,cache_patch_t); else PreCacheLump(temp->shapenum+shapestart,PU_CACHESPRITES,cache_transpatch_t); for (z=0; z<temp->numanims; z++) PreCacheLump(temp->shapenum+shapestart+z,PU_CACHESPRITES,cache_patch_t); if (temp->flags & FL_ROTATING) { for (z=1; z<8; z++) PreCacheLump(temp->shapenum+shapestart+z,PU_CACHESPRITES,cache_patch_t); } if (temp->flags & FL_WOODEN) { start = W_GetNumForName("WFRAG1"); stop = W_GetNumForName("WFRAG14"); PreCacheGroup(start,stop,cache_patch_t); } if (temp->flags & FL_METALLIC) { PreCacheLump(W_GetNumForName("MSHARDS"),PU_CACHESPRITES,cache_patch_t); start = W_GetNumForName("ROBODIE1"); stop = W_GetNumForName("ROBODEAD"); PreCacheGroup(start,stop,cache_patch_t); } female = ((locplayerstate->player == 1) || (locplayerstate->player == 3)); black = (locplayerstate->player == 2); if (female) { start = W_GetNumForName("FPIST11"); stop = W_GetNumForName("FPIST13"); } else if (black) { start = W_GetNumForName("BMPIST1"); stop = W_GetNumForName("BMPIST3"); } else { start = W_GetNumForName("MPIST11"); stop = W_GetNumForName("MPIST13"); } PreCacheGroup(start,stop,cache_patch_t); switch (temp->itemnumber) { case stat_pedgoldkey: case stat_pedsilverkey: case stat_pedironkey: case stat_pedcrystalkey: PreCacheLump(W_GetNumForName("PEDESTA"),PU_CACHESPRITES,cache_patch_t); break; case stat_bat: start = W_GetNumForName("EXBAT1"); stop = W_GetNumForName("EXBAT7"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_knifestatue: start = W_GetNumForName("KNIFE1"); stop = W_GetNumForName("KNIFE10"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_twopistol: if (female) { start = W_GetNumForName("RFPIST1"); stop = W_GetNumForName("LFPIST3"); } else if (black) { start = W_GetNumForName("RBMPIST1"); stop = W_GetNumForName("LBMPIST3"); } else { start = W_GetNumForName("RMPIST1"); stop = W_GetNumForName("LMPIST3"); } PreCacheGroup(start,stop,cache_patch_t); break; case stat_mp40: start = W_GetNumForName("MP401"); stop = W_GetNumForName("MP403"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_bazooka: start = W_GetNumForName("BAZOOKA1"); stop = W_GetNumForName("BAZOOKA4"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_firebomb: start = W_GetNumForName("FBOMB1"); stop = W_GetNumForName("FBOMB4"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_heatseeker: start = W_GetNumForName("HSEEK1"); stop = W_GetNumForName("HSEEK4"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_drunkmissile: start = W_GetNumForName("DRUNK1"); stop = W_GetNumForName("DRUNK4"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_firewall: start = W_GetNumForName("FIREW1"); stop = W_GetNumForName("FIREW3"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_splitmissile: start = W_GetNumForName("SPLIT1"); stop = W_GetNumForName("SPLIT4"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_kes: start = W_GetNumForName("KES1"); stop = W_GetNumForName("KES6"); PreCacheGroup(start,stop,cache_patch_t); break; case stat_godmode: start = W_GetNumForName("GODHAND1"); stop = W_GetNumForName("GODHAND8"); PreCacheGroup(start,stop,cache_patch_t); PreCacheGroup(W_GetNumForName("VAPO1"), W_GetNumForName("LITSOUL"), cache_patch_t); PreCacheGroup(W_GetNumForName("GODFIRE1"), W_GetNumForName("GODFIRE4"), cache_patch_t); break; case stat_dogmode: start = W_GetNumForName("DOGNOSE1"); stop = W_GetNumForName("DOGPAW4"); PreCacheGroup(start,stop,cache_patch_t); break; default: ; } } /* =============== = = LoadStatics = =============== */ void LoadStatics( byte * buffer, int size) { saved_stat_type dummy; int stcount,i; statobj_t*temp; stcount = size/sizeof(saved_stat_type); InitStaticList(); for(i=0; i<stcount; i++) { temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL); if (!temp) Error("LoadStatics: Failed on allocation of static %d of %d",i,stcount); memset(temp,0,sizeof(*temp)); memcpy(&(dummy.x),buffer,sizeof(saved_stat_type)); temp->whichstat = statcount++; temp->x = dummy.x; temp->y = dummy.y; temp->z = dummy.z; temp->flags = dummy.flags; temp->ticcount = dummy.ticcount; temp->hitpoints = dummy.hitpoints; temp->shapenum = dummy.shapenum; temp->ammo = dummy.ammo; temp->count = dummy.count; temp->numanims = dummy.numanims; temp->itemnumber = dummy.itemnumber; temp->areanumber = dummy.areanumber; temp->linked_to = dummy.linked_to; temp->which = SPRITE; temp->tilex = temp->x >> TILESHIFT; temp->tiley = temp->y >> TILESHIFT; temp->flags &= ~FL_ABP; temp->visspot = &spotvis[temp->tilex][temp->tiley]; if ((temp->itemnumber >= stat_touch1) && (temp->itemnumber <= stat_touch4)) { touchindices[temp->tilex][temp->tiley] = lasttouch + 1; lasttouch ++; SD_PreCacheSoundGroup(SD_TOUCHPLATESND,SD_BADTOUCHSND); } AddStatic(temp); if (temp->shapenum != -1) { if (temp->itemnumber == stat_bullethole) { SetupBulletHoleLink(temp->linked_to,temp); } else if (temp->flags & FL_DEADBODY) { if ( actorat[temp->tilex][temp->tiley] == NULL ) actorat[temp->tilex][temp->tiley] = temp; } else if (!(temp->flags & FL_NONMARK)) { sprites[temp->tilex][temp->tiley] = temp; } PreCacheStaticFrames(temp); } PreCacheStaticSounds(temp->itemnumber); buffer += sizeof(saved_stat_type); } } void Set_NewZ_to_MapValue(fixed *newz,int zoffset,const char*errorstr,int tilex,int tiley) { int zf,z; zoffset&=0xff; z=zoffset>>4; zf=zoffset&0xf; if (z==0xf) *newz = nominalheight+64-(zf<<2); else { if (z>levelheight) Error ("You specified a height of %x for the %s at tilex=%d tiley=%d when\n the level is only %d high\n", zoffset,errorstr,tilex,tiley,levelheight); else *newz = nominalheight-(z<<6)-(zf<<2); } } /* =============== = = SpawnStatic = =============== */ int BaseMarkerZ;//bna++ void SpawnStatic (int tilex, int tiley, int mtype, int zoffset) { statobj_t * temp; boolean onetimer; #if (SHAREWARE == 1) switch(mtype) { case stat_rlight: case stat_glight: case stat_ylight: case stat_chandelier: mtype = stat_blight; break; case stat_garb1: case stat_garb2: case stat_garb3: case stat_shit: mtype = stat_metalshards; break; case stat_lamp: mtype = stat_altbrazier2; break; } #endif if ( BATTLEMODE ) { if ( !gamestate.BattleOptions.SpawnWeapons ) { if ( stats[ mtype ].flags & FL_WEAPON ) { return; } } if (mtype == stat_pit) return; // Change lifeitems and extra lives to health switch( mtype ) { case stat_lifeitem1 : case stat_lifeitem2 : mtype = stat_monkcrystal1; break; case stat_lifeitem3 : case stat_lifeitem4 : case stat_oneup : case stat_threeup : mtype = stat_monkcrystal2; break; } switch( mtype ) { case stat_monkmeal : case stat_priestporridge : case stat_monkcrystal1 : case stat_monkcrystal2 : case stat_healingbasin : if ( ( gamestate.Product != ROTT_SHAREWARE ) && ( gamestate.BattleOptions.SpawnMines ) && ( !IsPlatform( tilex, tiley ) && ( ( zoffset & 0xff00 ) != 0xb000 ) ) && ( zoffset == -1 ) ) { mtype = stat_mine; } else if ( !gamestate.BattleOptions.SpawnHealth ) { return; } break; } } if (!firstemptystat) { temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL); //SoftError("\nMalloc-ing actor"); //if (insetupgame) // SoftError("in setup"); } else { temp = lastemptystat; //SoftError("\nfree actor available"); RemoveFromFreeStaticList(lastemptystat); } // Standard pole hack if ((zoffset>=14) && (zoffset<=17)) zoffset=-1; if (temp) { memset(temp,0,sizeof(*temp)); temp->shapenum = stats[mtype].picnum; temp->whichstat = statcount ++; temp->tilex = tilex; temp->tiley = tiley; temp->x = ((long)tilex << TILESHIFT) + 0x8000; temp->y = ((long)tiley << TILESHIFT) + 0x8000; temp->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE; temp->linked_to = -1; if ((temp->areanumber<=0) || (temp->areanumber>NUMAREAS)) Error ("Sprite at x=%d y=%d type=%d has an illegal areanumber\n",tilex,tiley,mtype); if ( mtype == stat_mine ) { temp->z = nominalheight; } else if (zoffset!=-1) { if ((zoffset&0xff00)==0xb000) Set_NewZ_to_MapValue(&(temp->z),zoffset,"static",tilex,tiley); else if (IsPlatform(tilex,tiley)) temp->z = PlatformHeight(tilex,tiley); else if (zoffset==11) temp->z=-65; else if (zoffset==12) temp->z=-66; else temp->z = nominalheight; // Error ("You didn't specify a valid height over the sprite at tilex=%ld tiley=%ld\n",tilex,tiley); } else if (mtype>stat_chandelier) temp->z = nominalheight; temp->visspot = &spotvis[tilex][tiley]; temp->which = SPRITE; temp->ticcount = stats[mtype].tictime; temp->hitpoints = stats[mtype].hitpoints; temp->itemnumber = stats[mtype].type; temp->flags = stats[mtype].flags; temp->ammo = stats[mtype].ammo; temp->numanims = stats[mtype].numanims; if (temp->flags & FL_BONUS) switch (stats[mtype].type) { case stat_lifeitem1: case stat_lifeitem2: case stat_lifeitem3: case stat_lifeitem4: gamestate.treasuretotal++; break; default: ; } AddStatic(temp); onetimer = ((mtype == stat_rubble) || (mtype == stat_woodfrag) || (mtype == stat_metalfrag) || (mtype == stat_missmoke) ); if (DoPanicMapping()) { if (temp->numanims && (!onetimer)) { temp->flags &= ~FL_ACTIVE; temp->numanims = 0; GameRandomNumber("SpawnStatic",mtype); } } else { if (temp->numanims) { if (!onetimer) temp->count = (int)(((int)GameRandomNumber("SpawnStatic",mtype) % stats[mtype].numanims) + 1); else temp->count = 0; } else if (temp->itemnumber == stat_standardpole) { if (MAPSPOT(temp->tilex,temp->tiley,2)) temp->count = 2*(MAPSPOT(temp->tilex,temp->tiley,2)-14); else temp->count = 0; } if ((temp->itemnumber == stat_knifestatue) || (temp->itemnumber == stat_emptystatue) || (temp->itemnumber == stat_standardpole)) temp->flags|=FL_ROTATING; } if (mtype != stat_missmoke) sprites[tilex][tiley] = temp; else temp->flags |= FL_NONMARK; //================ check special junk ==================================// if (temp->itemnumber == stat_dariantouch) { _2Dpoint *tdptr; tdptr = &(MISCVARS->ETOUCH[MISCVARS->nexttouch]); tdptr->x = tilex; tdptr->y = tiley; sprites[tilex][tiley]->linked_to = MISCVARS->nexttouch; MISCVARS->nexttouch ++; } else if ((temp->itemnumber >= stat_touch1) && (temp->itemnumber <= stat_touch4)) { touchindices[tilex][tiley] = lasttouch + 1; SD_PreCacheSoundGroup(SD_TOUCHPLATESND,SD_BADTOUCHSND); lasttouch ++; } //=====================================================================// //bna added // BaseMarkerZ used to adjust height in s_basemarker1 // in SpawnNewObj(i,j,&s_basemarker1,inertobj); BaseMarkerZ=temp->z;//bna++ BaseMarkerZ = spawnz; PreCacheStaticFrames(temp); PreCacheStaticSounds(temp->itemnumber); if (temp->flags & FL_WEAPON) MISCVARS->NUMWEAPONS ++; } else Error("Z_LevelMalloc failed in SpawnStatic!"); } /* =============== = = SpawnInertStatic = =============== */ void SpawnInertStatic (int x, int y, int z, int mtype) { statobj_t * temp; if (!firstemptystat) { temp = (statobj_t*)Z_LevelMalloc(sizeof(statobj_t),PU_LEVELSTRUCT,NULL); //SoftError("\nMalloc-ing actor"); //if (insetupgame) // SoftError("in setup"); } else { temp = lastemptystat; //SoftError("\nfree actor available"); RemoveFromFreeStaticList(lastemptystat); } if (temp) { memset(temp,0,sizeof(*temp)); temp->shapenum = stats[mtype].picnum; temp->whichstat = statcount ++; temp->tilex = x>>16; temp->tiley = y>>16; temp->x = x; temp->y = y; temp->areanumber = MAPSPOT(temp->tilex,temp->tiley,0)-AREATILE; temp->linked_to = -1; if ((temp->areanumber<=0) || (temp->areanumber>NUMAREAS)) { int tilex=temp->tilex; int tiley=temp->tiley; FindEmptyTile(&tilex,&tiley); temp->areanumber = MAPSPOT(tilex,tiley,0)-AREATILE; } temp->z=z; temp->visspot = &spotvis[temp->tilex][temp->tiley]; temp->which = SPRITE; temp->ticcount = stats[mtype].tictime; temp->hitpoints = stats[mtype].hitpoints; temp->itemnumber = stats[mtype].type; temp->flags = (stats[mtype].flags|FL_ABP|FL_NONMARK); if (fog) { temp->shapenum++; temp->flags &= ~FL_TRANSLUCENT; } temp->ammo = stats[mtype].ammo; temp->numanims = stats[mtype].numanims; AddStatic(temp); MakeStatActive(temp); } else Error("Z_LevelMalloc failed in SpawnStatic!"); } /* =============== = = SpawnSolidStatic = =============== */ void SpawnSolidStatic (statobj_t * temp) { if (temp->flags & FL_ACTIVE) temp->flags &= ~FL_ACTIVE; temp->hitpoints = INITIALFIRECOLOR; temp->flags = FL_SOLIDCOLOR|FL_SEEN|FL_ABP; if ((gamestate.BattleOptions.RespawnItems) && (temp->itemnumber == stat_tntcrate) ) temp->flags |= FL_RESPAWN; temp->ticcount = SOLIDCOLORTICTIME; } /* ====================== = = PreCacheStaticSounds = ====================== */ void PreCacheStaticSounds (int itemnumber) { if (stats[itemnumber].flags & FL_SHOOTABLE) SD_PreCacheSound(SD_ITEMBLOWSND); switch(itemnumber) { case stat_pit: SD_PreCacheSound(SD_PITTRAPSND); break; case stat_bonusbarrel: SD_PreCacheSound(SD_BONUSBARRELSND); break; case stat_knifestatue: SD_PreCacheSound(SD_GETKNIFESND); break; case stat_gibs1: case stat_gibs2: case stat_gibs3: SD_PreCacheSound (SD_ACTORSQUISHSND); break; case stat_pedgoldkey: case stat_pedsilverkey: case stat_pedironkey: case stat_pedcrystalkey: SD_PreCacheSound (SD_GETKEYSND); break; case stat_monkmeal: SD_PreCacheSound (SD_GETHEALTH1SND); break; case stat_monkcrystal1: SD_PreCacheSound (SD_GETHEALTH2SND); break; case stat_monkcrystal2: SD_PreCacheSound (SD_GETHEALTH2SND); break; case stat_priestporridge: SD_PreCacheSound (SD_GETHEALTH1SND); SD_PreCacheSound(SD_COOKHEALTHSND); break; case stat_healingbasin: SD_PreCacheSound (SD_GETHEALTH2SND); break; case stat_oneup: SD_PreCacheSound(SD_GET1UPSND); break; case stat_threeup: SD_PreCacheSound(SD_GET3UPSND); break; case stat_scotthead: SD_PreCacheSound(SD_GETHEADSND); break; case stat_twopistol: case stat_mp40: case stat_bazooka: case stat_firebomb: case stat_heatseeker: case stat_drunkmissile: case stat_firewall: case stat_splitmissile: case stat_kes: SD_PreCacheSound(SD_GETWEAPONSND); break; case stat_bat: SD_PreCacheSound(SD_GETBATSND); break; case stat_lifeitem1: case stat_lifeitem2: case stat_lifeitem3: case stat_lifeitem4: SD_PreCacheSound(SD_GETBONUSSND); break; case stat_random: SD_PreCacheSound(SD_GETGODSND); SD_PreCacheSound(SD_GETDOGSND); SD_PreCacheSound(SD_GETELASTSND); SD_PreCacheSound(SD_GETSHROOMSSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_bulletproof: SD_PreCacheSound(SD_GETBVESTSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_gasmask: SD_PreCacheSound(SD_GETMASKSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_asbesto: SD_PreCacheSound(SD_GETAVESTSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_elastic: SD_PreCacheSound(SD_GETELASTSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_fleetfeet: SD_PreCacheSound(SD_GETFLEETSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_godmode: SD_PreCacheSound(SD_GETGODSND); SD_PreCacheSound(SD_GODMODE1SND); break; case stat_dogmode: SD_PreCacheSound(SD_GETDOGSND); break; case stat_mushroom: SD_PreCacheSound(SD_GETSHROOMSSND); SD_PreCacheSound(SD_LOSEMODESND); break; case stat_dipball1: case stat_dipball2: case stat_dipball3: SD_PreCacheSound(SD_GETBONUSSND); break; default: SD_PreCacheSound(SD_GETBONUSSND); break; } } /* =============== = = SaveSwitches = =============== */ void SaveSwitches(byte ** buffer, int * size) { int numswitches,i; byte * tptr; numswitches = lastswitch-&switches[0]; if (numswitches==0) { *size=0; *buffer=SafeMalloc(16); return; } *size = numswitches*sizeof(wall_t); *buffer = (byte *)SafeMalloc(*size); tptr = *buffer; for(i=0; i<numswitches; i++) { memcpy(tptr,&switches[i],sizeof(wall_t)); tptr += sizeof(wall_t); } } /* =============== = = LoadSwitches = =============== */ void LoadSwitches (byte * buffer, int size) { int numswitches,i,tilex,tiley; numswitches = size/sizeof(wall_t); for(i=0; i<numswitches; i++) { memcpy(&switches[i],buffer,sizeof(wall_t)); tilex = switches[i].tilex; tiley = switches[i].tiley; actorat[tilex][tiley]=&switches[i]; if (MAPSPOT(tilex,tiley,0) == 79) // On by default { if (!(switches[i].flags & FL_ON)) tilemap[tilex][tiley]--; } else if (switches[i].flags & FL_W_INVERTED) // Hi masked wall { maskedwallobj_t * lastmaskobj; lastmaskobj=maskobjlist[tilemap[tilex][tiley]&0x3ff]; if (switches[i].flags & FL_ON) lastmaskobj->toptexture++; } else if (switches[i].flags & FL_ON) tilemap[tilex][tiley]++; buffer += sizeof(wall_t); touchindices[tilex][tiley] = lasttouch + 1; lasttouch ++; } lastswitch=&switches[numswitches]; } /* =============== = = SpawnSwitchThingy = =============== */ void SpawnSwitchThingy(int tilex, int tiley) { lastswitch->flags |= FL_SWITCH; lastswitch->which = WALL; lastswitch->tilex = tilex; lastswitch->tiley = tiley; touchindices[tilex][tiley] = lasttouch + 1; lasttouch ++; actorat[tilex][tiley] = lastswitch; lastswitch ++; } /* =============== = = AnimateWalls = =============== */ void AnimateWalls(void) { int i; animwall_t * aw; if (DoPanicMapping()==true) return; for(i=0; i<MAXANIMWALLS; i++) { aw=&animwalls[i]; if (aw->active==0) continue; if (aw->ticcount <= 0) { if (aw->count < animwallsinfo[i].numanims) { aw->texture = aw->basetexture + aw->count; aw->count++; } else { aw->texture = aw->basetexture; aw->count = 1; } while (aw->ticcount<=0) aw->ticcount+=animwallsinfo[i].tictime; } else aw->ticcount -= tics; } } #define M_ResetSprites(x) \ { if ((index == stat_dariantouch) && (!x->count))\ {x->shapenum = stats[index].picnum; \ x->count = 1; \ x->ticcount = stats[index].tictime; \ x->flags &= ~FL_BACKWARDS; \ x->flags &= ~FL_ACTIVE; \ } \ } void CheckCriticalStatics(void) { respawn_t *rtemp,*ddt; int i,stilex,stiley; statobj_t*temp,*stat; for(rtemp = firstrespawn; rtemp;) { rtemp->ticcount --; ddt = rtemp->next; if (rtemp->ticcount <=0) { int stype; stilex = rtemp->tilex; stiley = rtemp->tiley; // if another weapon is there, nuke it if (sprites[stilex][stiley]) { RemoveStatic(sprites[stilex][stiley]); sprites[stilex][stiley] = NULL; } if (rtemp->itemnumber == stat_tntcrate) { RemoveStatic((statobj_t*)(rtemp->linked_to)); stype = stat_tntcrate; } else { for(i=0; i<NUMSTATS; i++) { if (rtemp->itemnumber == stats[i].type) { stype = i; break; } } } SpawnStatic(stilex,stiley,stype,-1); LASTSTAT->z = rtemp->spawnz; LASTSTAT->flags |= FL_ABP; MakeStatActive(LASTSTAT); SpawnNewObj(stilex,stiley,&s_itemspawn1,inertobj); SD_PlaySoundRTP(SD_RESPAWNSND,new->x,new->y); new->flags |= FL_ABP; MakeActive(new); new->z = LASTSTAT->z; RemoveRespawnStatic(rtemp); } rtemp = ddt; } for (temp = firstactivestat ; temp; ) { stat = temp->nextactive; if (temp->flags & FL_SOLIDCOLOR) { temp->ticcount--; if (temp->ticcount<=0) { temp->hitpoints+=SOLIDCOLORINCREMENT; if (temp->hitpoints>MAXFIRECOLOR) RemoveStatic(temp); else temp->ticcount = SOLIDCOLORTICTIME; } } temp = stat; } } /* =============== = = DoSprites = =============== */ void DoSprites(void) { int index; statobj_t *temp,*tempnext; for(temp = firstactivestat; temp;) { tempnext = temp->nextactive; if ((temp->shapenum != NOTHING) && (temp->flags & FL_ACTIVE)) { index = temp->itemnumber; temp->ticcount -= tics; while (temp->ticcount <= 0) { if (temp->count < temp->numanims) { temp->shapenum = stats[index].picnum + temp->count; if (index == stat_missmoke) { RemoveStatic(temp); break; } if (((index == stat_rubble) && (temp->count == 9)) || ((index == stat_woodfrag) && (temp->count == 13)) || ((index == stat_metalfrag) && (temp->count == 9))) { temp->flags &= ~FL_ACTIVE; break; } if (temp->flags & FL_BACKWARDS) { temp->count--; M_ResetSprites(temp); } else temp->count ++; } else if (!(temp->flags & FL_BANDF)) { temp->shapenum = stats[index].picnum; temp->count=1; } else { temp->flags |= FL_BACKWARDS; temp->count --; } temp->ticcount += stats[index].tictime; } } temp = tempnext; } } void SpawnStaticDamage(statobj_t * stat, int angle) { GetNewActor (); MakeActive(new); NewState(new,&s_gunsmoke1); new->obclass = inertobj; new->which = ACTOR; new->x = (stat->x)-(costable[angle]>>4); new->y = (stat->y)+(sintable[angle]>>4); new->z = (stat->z)+stats[stat->itemnumber].heightoffset; new->drawx = new->x; new->drawy = new->y; new->tilex = (new->x >> TILESHIFT); new->tiley = (new->y >> TILESHIFT); new->dir = 0; new->speed = 0; new->flags = (FL_NEVERMARK|FL_ABP); if ((new->x<=0) || (new->y<=0)) Error("SpawnStaticDamage: bad x,y itemnumber=%d\n",stat->itemnumber); }