#include "wolfdef.h" #include /* static object info*/ /* List of bad guy sprites */ static Word DKnightSprs[] = { S_DKNIGHT_ATK1, S_DKNIGHT_ATK2, S_DKNIGHT_ATK3, S_DKNIGHT_ATK4, S_DKNIGHT_WLK1, S_DKNIGHT_WLK2, S_DKNIGHT_WLK3, S_DKNIGHT_WLK4, S_DKNIGHT_DTH1, S_DKNIGHT_DTH2, S_DKNIGHT_DTH3,S_G_KEY,0}; static Word DogSprs[] = { S_DOG_ATK1, S_DOG_ATK2, S_DOG_ATK3, S_DOG_WLK1, S_DOG_WLK2, S_DOG_WLK3, S_DOG_WLK4, S_DOG_DTH1, S_DOG_DTH2, S_DOG_DTH3,0}; static Word NaziSprs[] = { S_GUARD_ATK1, S_GUARD_ATK2, S_GUARD_ATK3, S_GUARD_WLK1, S_GUARD_WLK2, S_GUARD_WLK3, S_GUARD_WLK4, S_GUARD_PAIN, S_GUARD_DTH1, S_GUARD_DTH2, S_GUARD_DTH3,S_AMMO,0}; static Word HansSprs[] = { S_HANS_ATK1, S_HANS_ATK2, S_HANS_ATK3, S_HANS_WLK1, S_HANS_WLK2, S_HANS_WLK3, S_HANS_WLK4, S_HANS_DTH1, S_HANS_DTH2, S_HANS_DTH3,S_G_KEY,0}; static Word HitlerSprs[] = { S_HITLER_ATK1, S_HITLER_ATK2, S_HITLER_ATK3, S_HITLER_WLK1, S_HITLER_WLK2, S_HITLER_WLK3, S_HITLER_WLK4, S_HITLER_DTH1, S_HITLER_DTH2, S_HITLER_DTH3, S_MHITLER_ATK1, S_MHITLER_ATK2, S_MHITLER_ATK3, S_MHITLER_DIE1, S_MHITLER_DIE2, S_MHITLER_DIE3, S_MHITLER_DIE4, S_MHITLER_WLK1, S_MHITLER_WLK2, S_MHITLER_WLK3, S_MHITLER_WLK4,0}; static Word UberSprs[] = { S_UBER_ATK1, S_UBER_ATK2, S_UBER_ATK3, S_UBER_ATK4, S_UBER_WLK1, S_UBER_WLK2, S_UBER_WLK3, S_UBER_WLK4, S_UBER_DTH1, S_UBER_DTH2, S_UBER_DTH3,S_G_KEY,0}; static Word MutantSprs[] = { S_MUTANT_ATK1, S_MUTANT_ATK2, S_MUTANT_ATK3, S_MUTANT_WLK1, S_MUTANT_WLK2, S_MUTANT_WLK3, S_MUTANT_WLK4, S_MUTANT_PAIN, S_MUTANT_DTH1, S_MUTANT_DTH2, S_MUTANT_DTH3,S_AMMO,0}; static Word OfficerSprs[] = { S_OFFICER_ATK1, S_OFFICER_ATK2, S_OFFICER_ATK3, S_OFFICER_WLK1, S_OFFICER_WLK2, S_OFFICER_WLK3, S_OFFICER_WLK4, S_OFFICER_PAIN, S_OFFICER_DTH1, S_OFFICER_DTH2, S_OFFICER_DTH3,S_AMMO,0}; static Word SchabbsSpr[] = { S_SCHABBS_ATK1, S_SCHABBS_ATK2, S_SCHABBS_WLK1, S_SCHABBS_WLK2, S_SCHABBS_WLK3, S_SCHABBS_WLK4, S_SCHABBS_DTH1, S_SCHABBS_DTH2, S_SCHABBS_DTH3,S_G_KEY,0}; static Word SSSprs[] = { S_SS_ATK1, S_SS_ATK2, S_SS_ATK3, S_SS_WLK1, S_SS_WLK2, S_SS_WLK3, S_SS_WLK4, S_SS_PAIN, S_SS_DTH1, S_SS_DTH2, S_SS_DTH3,S_MACHINEGUN,S_AMMO,0}; static Word TransSprs[] = { S_TRANS_ATK1, S_TRANS_ATK2, S_TRANS_ATK3, S_TRANS_WLK1, S_TRANS_WLK2, S_TRANS_WLK3, S_TRANS_WLK4, S_TRANS_DTH1, S_TRANS_DTH2, S_TRANS_DTH3,S_G_KEY,0}; static Byte EnemyHits[16]; static Word *EnemySprs[] = { /* This list MUST match class_t! */ NaziSprs, OfficerSprs, SSSprs, DogSprs, MutantSprs, HansSprs, SchabbsSpr, TransSprs, UberSprs, DKnightSprs, HitlerSprs, HitlerSprs }; static Byte WallHits[256]; Word staticflags[] = { 0, /*S_WATER_PUDDLE,*/ TI_BLOCKMOVE, /*S_GREEN_BARREL,*/ TI_BLOCKMOVE, /*S_CHAIR_TABLE,*/ TI_BLOCKMOVE, /*S_FLOOR_LAMP,*/ 0, /*S_CHANDELIER,*/ TI_GETABLE, /*S_DOG_FOOD,*/ TI_BLOCKMOVE, /*S_COLUMN,*/ TI_BLOCKMOVE, /*S_POTTED_TREE,*/ TI_BLOCKMOVE, /*S_FLAG,*/ TI_BLOCKMOVE, /*S_POTTED_PLANT,*/ TI_BLOCKMOVE, /*S_BLUE_POT,*/ 0, /*S_DEBRIS1,*/ 0, /*S_LIGHT,*/ 0, /*S_BUCKET,*/ TI_BLOCKMOVE, /*S_ARMOUR,*/ TI_BLOCKMOVE, /*S_CAGE,*/ TI_GETABLE, /*S_G_KEY,*/ TI_GETABLE, /*S_S_KEY,*/ TI_GETABLE, /*S_BANDOLIER*/ TI_GETABLE, /*S_AMMOCASE,*/ TI_GETABLE, /*S_FOOD,*/ TI_GETABLE, /*S_HEALTH,*/ TI_GETABLE, /*S_AMMO,*/ TI_GETABLE, /*S_MACHINEGUN,*/ TI_GETABLE, /*S_CHAINGUN,*/ TI_GETABLE, /*S_CROSS,*/ TI_GETABLE, /*S_CHALICE,*/ TI_GETABLE, /*S_CHEST,*/ TI_GETABLE, /*S_CROWN,*/ TI_GETABLE, /*S_ONEUP,*/ TI_BLOCKMOVE, /*S_WOOD_BARREL,*/ TI_BLOCKMOVE, /*S_WATER_WELL,*/ TI_GETABLE, /*S_FLAMETHROWER */ TI_GETABLE, /*S_GASCAN */ TI_GETABLE, /*S_LAUNCHER */ TI_GETABLE /*S_MISSILES */ }; /********************************** Spawn a static object at x,y **********************************/ void SpawnStatic(Word x,Word y,Word shape) { Word *TilePtr; static_t *StatPtr; if (numstatics>=MAXSTATICS) { return; /* Oh oh!! */ } TilePtr = &tilemap[y][x]; /* Precalc tile pointer */ StatPtr = &statics[numstatics]; StatPtr->x = (x<y = (y<areanumber = TilePtr[0] & TI_NUMMASK; /* Mask off the area number */ TilePtr[0] |= staticflags[shape]; shape += S_WATER_PUDDLE; /* Init the shape number */ WallHits[shape] = 1; /* Load in this shape */ StatPtr->pic = shape; /* Set the object's shape */ switch (shape) { case S_CROSS: case S_CHALICE: case S_CHEST: case S_CROWN: case S_ONEUP: ++gamestate.treasuretotal; /* Mark this as treasure */ } ++numstatics; /* I have one more item */ } /********************************** Spawn the player at x,y **********************************/ void SpawnPlayer(Word x,Word y,Word dir) { gamestate.viewangle = (1-dir)*ANGLES/4; /* Get the basic viewing angle */ actors[0].x = (x<standstate; /* Get the state logic value */ ActorPtr = &actors[numactors]; /* Get the pointer to the new actor entry */ TilePtr = &tilemap[y][x]; /* Pointer to the current tile */ tile = TilePtr[0]; /* What's in the tile? */ ActorPtr->x = (x<y = (y<pic = states[state].shapenum; /* What picture to display? */ ActorPtr->ticcount = states[state].tictime; /* Initial tick count */ ActorPtr->state = state; ActorPtr->flags = FL_SHOOTABLE | FL_NOTMOVING; /* You can shoot it */ ActorPtr->distance = 0; /* No distance to travel */ ActorPtr->dir = nodir; /* No direction of travel */ ActorPtr->areanumber = tile&TI_NUMMASK; /* Area in */ ActorPtr->reacttime = 0; /* Reaction time */ TilePtr[0] = tile | TI_ACTOR; /* Mark as a bad guy */ MapPtr->tilemap[y][x] = numactors; /* Save the actor # */ ActorPtr->goalx = x; /* Don't travel anywhere */ ActorPtr->goaly = y; ActorPtr->class = which; /* Actor type */ ActorPtr->speed = info->speed; /* Basic speed */ ActorPtr->hitpoints = info->hitpoints; /* Starting hit points */ ++numactors; /* I now add one more actor to the list */ ++gamestate.killtotal; /* Another critter must die! */ } /********************************** Spawn an actor at a specific x,y and ALSO set the ambush flag **********************************/ void SpawnAmbush(Word x,Word y,class_t which) { actor_t *ActorPtr; ActorPtr = &actors[numactors]; /* Get the pointer to the new actor entry */ SpawnStand(x,y,which); /* Fill in all the entries */ ActorPtr->flags |= FL_AMBUSH; /* Set the ambush flag */ } /********************************** Spawn a door at the specified x,y **********************************/ void SpawnDoor(Word x,Word y,Word type) { door_t *door; Word *TilePtr; if (numdoors==MAXDOORS) { return; } TilePtr = &tilemap[y-1][x]; /* Pointer to the tile (-1 y) for door->area index */ door = &doors[numdoors]; /* Pointer to the door record */ door->position = 0; /* doors start out fully closed*/ door->tilex = x; door->tiley = y; door->info = type-90; /* Set the door type */ door->action = DR_CLOSED; /* Mark as closed */ TilePtr[MAPSIZE] = (TI_DOOR|TI_BLOCKMOVE|TI_BLOCKSIGHT)| numdoors; if (type & 1) { /* horizontal*/ door->area1 = TilePtr[MAPSIZE*2] & TI_NUMMASK; /* One cell below */ door->area2 = TilePtr[0] & TI_NUMMASK; /* One cell above */ } else { door->area1 = TilePtr[MAPSIZE-1] & TI_NUMMASK; /* One cell left */ door->area2 = TilePtr[MAPSIZE+1] & TI_NUMMASK; /* One cell right */ } ++numdoors; } /********************************** Spawn a pushwall track at the specified x,y **********************************/ void AddPWallTrack(Word x,Word y,Word tile) { Byte *TextPtr; if (x>=MAPSIZE || y>=MAPSIZE) { return; /* pushwall is off the edge of a map*/ } TextPtr = &textures[MAPSIZE+x][y]; if (TextPtr[0] != 0xff) { /* Already marked? */ return; /* solid wall*/ } TextPtr[0] = tile + 1; /* Save the tile # */ textures[y][x] = tile; /* Mark the texture index */ } /********************************** Spawn a pushwall at the specified x,y **********************************/ void SpawnPushwall(Word x,Word y,Word tile) { ++gamestate.secrettotal; /* Secret area! */ tilemap[y][x] |= (TI_BLOCKMOVE | TI_BLOCKSIGHT | TI_PUSHWALL); /* directly set texture values for rendering*/ tile = (tile-1)<<1; AddPWallTrack(x, y, tile); AddPWallTrack(x-1, y, tile); AddPWallTrack(x-2, y, tile); AddPWallTrack(x+1, y, tile); AddPWallTrack(x+2, y, tile); AddPWallTrack(x, y-1, tile); AddPWallTrack(x, y-2, tile); AddPWallTrack(x, y+1, tile); AddPWallTrack(x, y+2, tile); } /********************************** Spawn an elevator at the specified x,y **********************************/ void SpawnElevator(Word x,Word y) { elevatorx = x; /* for easy mode cheating*/ elevatory = y; tilemap[y][x] |= TI_BLOCKMOVE | TI_SWITCH; } /********************************** Spawn the outside at the specified x,y **********************************/ void SpawnOut(Word x,Word y) { /*tilemap[y][x] |= TI_BLOCKMOVE | TI_SWITCH;*/ } /********************************** Spawn a secret item at the specified x,y **********************************/ void SpawnSecret(Word x,Word y) { tilemap[y][x] |= TI_BLOCKMOVE | TI_SECRET; } /********************************** Spawn all actors and mark down special places A spawn record is (x,y,type) **********************************/ void SpawnThings(void) { Word x,y; /* Temp x,y */ Word type; /* Item to spawn */ Byte *spawn_p; Word Count; /* Number of items to create */ Word *EnemyPtr; memset(EnemyHits,0,sizeof(EnemyHits)); spawn_p = (Byte *)MapPtr+MapPtr->spawnlistofs; /* Point to the spawn table */ Count = MapPtr->numspawn; /* How many items to spawn? */ if (!Count) { return; } do { x = spawn_p[0]; /* Get the X */ y = spawn_p[1]; /* Get the y */ type = spawn_p[2]; /* Get the type */ spawn_p+=3; /* Index past the record */ if (type<19) { continue; } else if (type<23) { /* 19-22 */ SpawnPlayer(x,y,type-19); } else if (type<59) { /* 23-58 */ SpawnStatic(x,y,type-23); } else if (type<90) { /* 59-89 */ continue; } else if (type<98) { /* 90-97 */ SpawnDoor(x,y,type); } else if (type == 98) { /* 98 */ SpawnPushwall(x,y,spawn_p[0]); ++spawn_p; } else if (type == 99) { /* 99 */ SpawnOut(x,y); } else if (type == 100) { /* 100 */ SpawnElevator(x,y); } else if (type == 101) { /* 101 */ SpawnSecret(x,y); } else if (type<108) { /* 102-107 */ continue; } else if (type<123) { /* 108-122 */ SpawnStand(x,y,(class_t) (type-108)); } else if (type<126) { /* 123-125 */ continue; } else if (type<140) { /* 126-139 */ SpawnAmbush(x,y,(class_t) (type-126)); } } while (--Count); Count = 0; do { if (EnemyHits[Count]) { x = 0; EnemyPtr = EnemySprs[Count]; do { WallHits[EnemyPtr[x]] = 1; ++x; } while (EnemyPtr[x]); } } while (++Count<16); } /********************************** Release the map data **********************************/ void ReleaseMap(void) { Word i; if (OldMapNum) { KillAResource(OldMapNum); /* Make SURE it's purged! */ OldMapNum = 0; /* Nothing loaded */ MapPtr = 0; /* No data available */ } i = 0; do { if (ArtData[i]) { FreeSomeMem(ArtData[i]); /* Release the wall art */ ArtData[i] = 0; } } while (++i<64); /* All walls done? */ i = 1; do { if (SpriteArray[i]) { /* Is this sprite loaded? */ FreeSomeMem(SpriteArray[i]); /* Release the memory */ SpriteArray[i] = 0; } } while (++iMapRezNum)+gamestate.mapon; /* Which map to load */ MapPtr = LoadAResource(OldMapNum); /* Load in the map */ if (!MapPtr) { return FALSE; /* Uh.. yeah... */ } DrawPsyched(1); /* First stage done */ #ifdef __BIGENDIAN__ MapPtr->numspawn = SwapUShort(MapPtr->numspawn); /* Fix for 68000 machines */ MapPtr->spawnlistofs = SwapUShort(MapPtr->spawnlistofs); MapPtr->numnodes = SwapUShort(MapPtr->numnodes); MapPtr->nodelistofs = SwapUShort(MapPtr->nodelistofs); #endif numstatics = 0; /* Clear out the static array */ numdoors = 0; /* Clear out the door array */ numactors = 1; /* player has spot 0*/ nummissiles = 0; /* Clear out the missile array */ /* expand the byte width map to word width*/ memset(WallHits,0,sizeof(WallHits)); src = &MapPtr->tilemap[0][0]; dest = &tilemap[0][0]; Count = 0; do { tile = src[Count]; /* Get the byte tile */ if (tile & TI_BLOCKMOVE) { tile |= TI_BLOCKSIGHT; /* Mark as blocking my sight */ WallHits[(tile-1)&0x1F]=1; } dest[Count] = tile; /* Save the new tile */ } while (++Count