wolf3d

The original open source release of Wolfenstein 3D
Log | Files | Refs

WL_ACT1.C (16734B)


      1 // WL_ACT1.C
      2 
      3 #include "WL_DEF.H"
      4 #pragma hdrstop
      5 
      6 /*
      7 =============================================================================
      8 
      9 							STATICS
     10 
     11 =============================================================================
     12 */
     13 
     14 
     15 statobj_t	statobjlist[MAXSTATS],*laststatobj;
     16 
     17 
     18 struct
     19 {
     20 	int		picnum;
     21 	stat_t	type;
     22 } statinfo[] =
     23 {
     24 {SPR_STAT_0},					// puddle          spr1v
     25 {SPR_STAT_1,block},				// Green Barrel    "
     26 {SPR_STAT_2,block},				// Table/chairs    "
     27 {SPR_STAT_3,block},				// Floor lamp      "
     28 {SPR_STAT_4},					// Chandelier      "
     29 {SPR_STAT_5,block},				// Hanged man      "
     30 {SPR_STAT_6,bo_alpo},			// Bad food        "
     31 {SPR_STAT_7,block},				// Red pillar      "
     32 //
     33 // NEW PAGE
     34 //
     35 {SPR_STAT_8,block},				// Tree            spr2v
     36 {SPR_STAT_9},					// Skeleton flat   "
     37 {SPR_STAT_10,block},			// Sink            " (SOD:gibs)
     38 {SPR_STAT_11,block},			// Potted plant    "
     39 {SPR_STAT_12,block},			// Urn             "
     40 {SPR_STAT_13,block},			// Bare table      "
     41 {SPR_STAT_14},					// Ceiling light   "
     42 #ifndef SPEAR
     43 {SPR_STAT_15},					// Kitchen stuff   "
     44 #else
     45 {SPR_STAT_15,block},			// Gibs!
     46 #endif
     47 //
     48 // NEW PAGE
     49 //
     50 {SPR_STAT_16,block},			// suit of armor   spr3v
     51 {SPR_STAT_17,block},			// Hanging cage    "
     52 {SPR_STAT_18,block},			// SkeletoninCage  "
     53 {SPR_STAT_19},					// Skeleton relax  "
     54 {SPR_STAT_20,bo_key1},			// Key 1           "
     55 {SPR_STAT_21,bo_key2},			// Key 2           "
     56 {SPR_STAT_22,block},			// stuff				(SOD:gibs)
     57 {SPR_STAT_23},					// stuff
     58 //
     59 // NEW PAGE
     60 //
     61 {SPR_STAT_24,bo_food}, 			// Good food       spr4v
     62 {SPR_STAT_25,bo_firstaid},		// First aid       "
     63 {SPR_STAT_26,bo_clip},			// Clip            "
     64 {SPR_STAT_27,bo_machinegun},	// Machine gun     "
     65 {SPR_STAT_28,bo_chaingun},		// Gatling gun     "
     66 {SPR_STAT_29,bo_cross},			// Cross           "
     67 {SPR_STAT_30,bo_chalice},		// Chalice         "
     68 {SPR_STAT_31,bo_bible},			// Bible           "
     69 //
     70 // NEW PAGE
     71 //
     72 {SPR_STAT_32,bo_crown},			// crown           spr5v
     73 {SPR_STAT_33,bo_fullheal},		// one up          "
     74 {SPR_STAT_34,bo_gibs},			// gibs            "
     75 {SPR_STAT_35,block},			// barrel          "
     76 {SPR_STAT_36,block},			// well            "
     77 {SPR_STAT_37,block},			// Empty well      "
     78 {SPR_STAT_38,bo_gibs},			// Gibs 2          "
     79 {SPR_STAT_39,block},			// flag				"
     80 //
     81 // NEW PAGE
     82 //
     83 #ifndef SPEAR
     84 {SPR_STAT_40,block},			// Call Apogee		spr7v
     85 #else
     86 {SPR_STAT_40},					// Red light
     87 #endif
     88 //
     89 // NEW PAGE
     90 //
     91 {SPR_STAT_41},					// junk            "
     92 {SPR_STAT_42},					// junk 		   "
     93 {SPR_STAT_43},					// junk            "
     94 #ifndef SPEAR
     95 {SPR_STAT_44},					// pots            "
     96 #else
     97 {SPR_STAT_44,block},			// Gibs!
     98 #endif
     99 {SPR_STAT_45,block},			// stove           " (SOD:gibs)
    100 {SPR_STAT_46,block},			// spears          " (SOD:gibs)
    101 {SPR_STAT_47},					// vines			"
    102 //
    103 // NEW PAGE
    104 //
    105 #ifdef SPEAR
    106 {SPR_STAT_48,block},			// marble pillar
    107 {SPR_STAT_49,bo_25clip},		// bonus 25 clip
    108 {SPR_STAT_50,block},			// truck
    109 {SPR_STAT_51,bo_spear},			// SPEAR OF DESTINY!
    110 #endif
    111 
    112 {SPR_STAT_26,bo_clip2},			// Clip            "
    113 {-1}							// terminator
    114 };
    115 
    116 /*
    117 ===============
    118 =
    119 = InitStaticList
    120 =
    121 ===============
    122 */
    123 
    124 void InitStaticList (void)
    125 {
    126 	laststatobj = &statobjlist[0];
    127 }
    128 
    129 
    130 
    131 /*
    132 ===============
    133 =
    134 = SpawnStatic
    135 =
    136 ===============
    137 */
    138 
    139 void SpawnStatic (int tilex, int tiley, int type)
    140 {
    141 	laststatobj->shapenum = statinfo[type].picnum;
    142 	laststatobj->tilex = tilex;
    143 	laststatobj->tiley = tiley;
    144 	laststatobj->visspot = &spotvis[tilex][tiley];
    145 
    146 	switch (statinfo[type].type)
    147 	{
    148 	case block:
    149 		(unsigned)actorat[tilex][tiley] = 1;		// consider it a blocking tile
    150 	case dressing:
    151 		laststatobj->flags = 0;
    152 		break;
    153 
    154 	case	bo_cross:
    155 	case	bo_chalice:
    156 	case	bo_bible:
    157 	case	bo_crown:
    158 	case	bo_fullheal:
    159 		if (!loadedgame)
    160 		  gamestate.treasuretotal++;
    161 
    162 	case	bo_firstaid:
    163 	case	bo_key1:
    164 	case	bo_key2:
    165 	case	bo_key3:
    166 	case	bo_key4:
    167 	case	bo_clip:
    168 	case	bo_25clip:
    169 	case	bo_machinegun:
    170 	case	bo_chaingun:
    171 	case	bo_food:
    172 	case	bo_alpo:
    173 	case	bo_gibs:
    174 	case	bo_spear:
    175 		laststatobj->flags = FL_BONUS;
    176 		laststatobj->itemnumber = statinfo[type].type;
    177 		break;
    178 	}
    179 
    180 	laststatobj++;
    181 
    182 	if (laststatobj == &statobjlist[MAXSTATS])
    183 		Quit ("Too many static objects!\n");
    184 }
    185 
    186 
    187 /*
    188 ===============
    189 =
    190 = PlaceItemType
    191 =
    192 = Called during game play to drop actors' items.  It finds the proper
    193 = item number based on the item type (bo_???).  If there are no free item
    194 = spots, nothing is done.
    195 =
    196 ===============
    197 */
    198 
    199 void PlaceItemType (int itemtype, int tilex, int tiley)
    200 {
    201 	int			type;
    202 	statobj_t	*spot;
    203 
    204 //
    205 // find the item number
    206 //
    207 	for (type=0 ;  ; type++)
    208 	{
    209 		if (statinfo[type].picnum == -1)		// end of list
    210 			Quit ("PlaceItemType: couldn't find type!");
    211 		if (statinfo[type].type == itemtype)
    212 			break;
    213 	}
    214 
    215 //
    216 // find a spot in statobjlist to put it in
    217 //
    218 	for (spot=&statobjlist[0] ; ; spot++)
    219 	{
    220 		if (spot==laststatobj)
    221 		{
    222 			if (spot == &statobjlist[MAXSTATS])
    223 				return;							// no free spots
    224 			laststatobj++;						// space at end
    225 			break;
    226 		}
    227 
    228 		if (spot->shapenum == -1)				// -1 is a free spot
    229 			break;
    230 	}
    231 //
    232 // place it
    233 //
    234 	spot->shapenum = statinfo[type].picnum;
    235 	spot->tilex = tilex;
    236 	spot->tiley = tiley;
    237 	spot->visspot = &spotvis[tilex][tiley];
    238 	spot->flags = FL_BONUS;
    239 	spot->itemnumber = statinfo[type].type;
    240 }
    241 
    242 
    243 
    244 /*
    245 =============================================================================
    246 
    247 							DOORS
    248 
    249 doorobjlist[] holds most of the information for the doors
    250 
    251 doorposition[] holds the amount the door is open, ranging from 0 to 0xffff
    252 	this is directly accessed by AsmRefresh during rendering
    253 
    254 The number of doors is limited to 64 because a spot in tilemap holds the
    255 	door number in the low 6 bits, with the high bit meaning a door center
    256 	and bit 6 meaning a door side tile
    257 
    258 Open doors conect two areas, so sounds will travel between them and sight
    259 	will be checked when the player is in a connected area.
    260 
    261 Areaconnect is incremented/decremented by each door. If >0 they connect
    262 
    263 Every time a door opens or closes the areabyplayer matrix gets recalculated.
    264 	An area is true if it connects with the player's current spor.
    265 
    266 =============================================================================
    267 */
    268 
    269 #define DOORWIDTH	0x7800
    270 #define OPENTICS	300
    271 
    272 doorobj_t	doorobjlist[MAXDOORS],*lastdoorobj;
    273 int			doornum;
    274 
    275 unsigned	doorposition[MAXDOORS];		// leading edge of door 0=closed
    276 										// 0xffff = fully open
    277 
    278 byte		far areaconnect[NUMAREAS][NUMAREAS];
    279 
    280 boolean		areabyplayer[NUMAREAS];
    281 
    282 
    283 /*
    284 ==============
    285 =
    286 = ConnectAreas
    287 =
    288 = Scans outward from playerarea, marking all connected areas
    289 =
    290 ==============
    291 */
    292 
    293 void RecursiveConnect (int areanumber)
    294 {
    295 	int	i;
    296 
    297 	for (i=0;i<NUMAREAS;i++)
    298 	{
    299 		if (areaconnect[areanumber][i] && !areabyplayer[i])
    300 		{
    301 			areabyplayer[i] = true;
    302 			RecursiveConnect (i);
    303 		}
    304 	}
    305 }
    306 
    307 
    308 void ConnectAreas (void)
    309 {
    310 	memset (areabyplayer,0,sizeof(areabyplayer));
    311 	areabyplayer[player->areanumber] = true;
    312 	RecursiveConnect (player->areanumber);
    313 }
    314 
    315 
    316 void InitAreas (void)
    317 {
    318 	memset (areabyplayer,0,sizeof(areabyplayer));
    319 	areabyplayer[player->areanumber] = true;
    320 }
    321 
    322 
    323 
    324 /*
    325 ===============
    326 =
    327 = InitDoorList
    328 =
    329 ===============
    330 */
    331 
    332 void InitDoorList (void)
    333 {
    334 	memset (areabyplayer,0,sizeof(areabyplayer));
    335 	_fmemset (areaconnect,0,sizeof(areaconnect));
    336 
    337 	lastdoorobj = &doorobjlist[0];
    338 	doornum = 0;
    339 }
    340 
    341 
    342 /*
    343 ===============
    344 =
    345 = SpawnDoor
    346 =
    347 ===============
    348 */
    349 
    350 void SpawnDoor (int tilex, int tiley, boolean vertical, int lock)
    351 {
    352 	int	areanumber;
    353 	unsigned	far *map;
    354 
    355 	if (doornum==64)
    356 		Quit ("64+ doors on level!");
    357 
    358 	doorposition[doornum] = 0;		// doors start out fully closed
    359 	lastdoorobj->tilex = tilex;
    360 	lastdoorobj->tiley = tiley;
    361 	lastdoorobj->vertical = vertical;
    362 	lastdoorobj->lock = lock;
    363 	lastdoorobj->action = dr_closed;
    364 
    365 	(unsigned)actorat[tilex][tiley] = doornum | 0x80;	// consider it a solid wall
    366 
    367 //
    368 // make the door tile a special tile, and mark the adjacent tiles
    369 // for door sides
    370 //
    371 	tilemap[tilex][tiley] = doornum | 0x80;
    372 	map = mapsegs[0] + farmapylookup[tiley]+tilex;
    373 	if (vertical)
    374 	{
    375 		*map = *(map-1);                        // set area number
    376 		tilemap[tilex][tiley-1] |= 0x40;
    377 		tilemap[tilex][tiley+1] |= 0x40;
    378 	}
    379 	else
    380 	{
    381 		*map = *(map-mapwidth);					// set area number
    382 		tilemap[tilex-1][tiley] |= 0x40;
    383 		tilemap[tilex+1][tiley] |= 0x40;
    384 	}
    385 
    386 	doornum++;
    387 	lastdoorobj++;
    388 }
    389 
    390 //===========================================================================
    391 
    392 /*
    393 =====================
    394 =
    395 = OpenDoor
    396 =
    397 =====================
    398 */
    399 
    400 void OpenDoor (int door)
    401 {
    402 	if (doorobjlist[door].action == dr_open)
    403 		doorobjlist[door].ticcount = 0;			// reset open time
    404 	else
    405 		doorobjlist[door].action = dr_opening;	// start it opening
    406 }
    407 
    408 
    409 /*
    410 =====================
    411 =
    412 = CloseDoor
    413 =
    414 =====================
    415 */
    416 
    417 void CloseDoor (int door)
    418 {
    419 	int	tilex,tiley,area;
    420 	objtype *check;
    421 
    422 //
    423 // don't close on anything solid
    424 //
    425 	tilex = doorobjlist[door].tilex;
    426 	tiley = doorobjlist[door].tiley;
    427 
    428 	if (actorat[tilex][tiley])
    429 		return;
    430 
    431 	if (player->tilex == tilex && player->tiley == tiley)
    432 		return;
    433 
    434 	if (doorobjlist[door].vertical)
    435 	{
    436 		if ( player->tiley == tiley )
    437 		{
    438 			if ( ((player->x+MINDIST) >>TILESHIFT) == tilex )
    439 				return;
    440 			if ( ((player->x-MINDIST) >>TILESHIFT) == tilex )
    441 				return;
    442 		}
    443 		check = actorat[tilex-1][tiley];
    444 		if (check && ((check->x+MINDIST) >> TILESHIFT) == tilex )
    445 			return;
    446 		check = actorat[tilex+1][tiley];
    447 		if (check && ((check->x-MINDIST) >> TILESHIFT) == tilex )
    448 			return;
    449 	}
    450 	else if (!doorobjlist[door].vertical)
    451 	{
    452 		if (player->tilex == tilex)
    453 		{
    454 			if ( ((player->y+MINDIST) >>TILESHIFT) == tiley )
    455 				return;
    456 			if ( ((player->y-MINDIST) >>TILESHIFT) == tiley )
    457 				return;
    458 		}
    459 		check = actorat[tilex][tiley-1];
    460 		if (check && ((check->y+MINDIST) >> TILESHIFT) == tiley )
    461 			return;
    462 		check = actorat[tilex][tiley+1];
    463 		if (check && ((check->y-MINDIST) >> TILESHIFT) == tiley )
    464 			return;
    465 	}
    466 
    467 
    468 //
    469 // play door sound if in a connected area
    470 //
    471 	area = *(mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
    472 			+doorobjlist[door].tilex)-AREATILE;
    473 	if (areabyplayer[area])
    474 	{
    475 		PlaySoundLocTile(CLOSEDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley);	// JAB
    476 	}
    477 
    478 	doorobjlist[door].action = dr_closing;
    479 //
    480 // make the door space solid
    481 //
    482 	(unsigned)actorat[tilex][tiley]
    483 		= door | 0x80;
    484 }
    485 
    486 
    487 
    488 /*
    489 =====================
    490 =
    491 = OperateDoor
    492 =
    493 = The player wants to change the door's direction
    494 =
    495 =====================
    496 */
    497 
    498 void OperateDoor (int door)
    499 {
    500 	int	lock;
    501 
    502 	lock = doorobjlist[door].lock;
    503 	if (lock >= dr_lock1 && lock <= dr_lock4)
    504 	{
    505 		if ( ! (gamestate.keys & (1 << (lock-dr_lock1) ) ) )
    506 		{
    507 			SD_PlaySound (NOWAYSND);		// locked
    508 			return;
    509 		}
    510 	}
    511 
    512 	switch (doorobjlist[door].action)
    513 	{
    514 	case dr_closed:
    515 	case dr_closing:
    516 		OpenDoor (door);
    517 		break;
    518 	case dr_open:
    519 	case dr_opening:
    520 		CloseDoor (door);
    521 		break;
    522 	}
    523 }
    524 
    525 
    526 //===========================================================================
    527 
    528 /*
    529 ===============
    530 =
    531 = DoorOpen
    532 =
    533 = Close the door after three seconds
    534 =
    535 ===============
    536 */
    537 
    538 void DoorOpen (int door)
    539 {
    540 	if ( (doorobjlist[door].ticcount += tics) >= OPENTICS)
    541 		CloseDoor (door);
    542 }
    543 
    544 
    545 
    546 /*
    547 ===============
    548 =
    549 = DoorOpening
    550 =
    551 ===============
    552 */
    553 
    554 void DoorOpening (int door)
    555 {
    556 	int		area1,area2;
    557 	unsigned	far	*map;
    558 	long	position;
    559 
    560 	position = doorposition[door];
    561 	if (!position)
    562 	{
    563 	//
    564 	// door is just starting to open, so connect the areas
    565 	//
    566 		map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
    567 			+doorobjlist[door].tilex;
    568 
    569 		if (doorobjlist[door].vertical)
    570 		{
    571 			area1 =	*(map+1);
    572 			area2 =	*(map-1);
    573 		}
    574 		else
    575 		{
    576 			area1 =	*(map-mapwidth);
    577 			area2 =	*(map+mapwidth);
    578 		}
    579 		area1 -= AREATILE;
    580 		area2 -= AREATILE;
    581 		areaconnect[area1][area2]++;
    582 		areaconnect[area2][area1]++;
    583 		ConnectAreas ();
    584 		if (areabyplayer[area1])
    585 		{
    586 			PlaySoundLocTile(OPENDOORSND,doorobjlist[door].tilex,doorobjlist[door].tiley);	// JAB
    587 		}
    588 	}
    589 
    590 //
    591 // slide the door by an adaptive amount
    592 //
    593 	position += tics<<10;
    594 	if (position >= 0xffff)
    595 	{
    596 	//
    597 	// door is all the way open
    598 	//
    599 		position = 0xffff;
    600 		doorobjlist[door].ticcount = 0;
    601 		doorobjlist[door].action = dr_open;
    602 		actorat[doorobjlist[door].tilex][doorobjlist[door].tiley] = 0;
    603 	}
    604 
    605 	doorposition[door] = position;
    606 }
    607 
    608 
    609 /*
    610 ===============
    611 =
    612 = DoorClosing
    613 =
    614 ===============
    615 */
    616 
    617 void DoorClosing (int door)
    618 {
    619 	int		area1,area2,move;
    620 	unsigned	far	*map;
    621 	long	position;
    622 	int		tilex,tiley;
    623 
    624 	tilex = doorobjlist[door].tilex;
    625 	tiley = doorobjlist[door].tiley;
    626 
    627 	if ( ((unsigned)actorat[tilex][tiley] != (door | 0x80))
    628 	|| (player->tilex == tilex && player->tiley == tiley) )
    629 	{			// something got inside the door
    630 		OpenDoor (door);
    631 		return;
    632 	};
    633 
    634 	position = doorposition[door];
    635 
    636 //
    637 // slide the door by an adaptive amount
    638 //
    639 	position -= tics<<10;
    640 	if (position <= 0)
    641 	{
    642 	//
    643 	// door is closed all the way, so disconnect the areas
    644 	//
    645 		position = 0;
    646 
    647 		doorobjlist[door].action = dr_closed;
    648 
    649 		map = mapsegs[0] + farmapylookup[doorobjlist[door].tiley]
    650 			+doorobjlist[door].tilex;
    651 
    652 		if (doorobjlist[door].vertical)
    653 		{
    654 			area1 =	*(map+1);
    655 			area2 =	*(map-1);
    656 		}
    657 		else
    658 		{
    659 			area1 =	*(map-mapwidth);
    660 			area2 =	*(map+mapwidth);
    661 		}
    662 		area1 -= AREATILE;
    663 		area2 -= AREATILE;
    664 		areaconnect[area1][area2]--;
    665 		areaconnect[area2][area1]--;
    666 
    667 		ConnectAreas ();
    668 	}
    669 
    670 	doorposition[door] = position;
    671 }
    672 
    673 
    674 
    675 
    676 /*
    677 =====================
    678 =
    679 = MoveDoors
    680 =
    681 = Called from PlayLoop
    682 =
    683 =====================
    684 */
    685 
    686 void MoveDoors (void)
    687 {
    688 	int		door;
    689 
    690 	if (gamestate.victoryflag)		// don't move door during victory sequence
    691 		return;
    692 
    693 	for (door = 0 ; door < doornum ; door++)
    694 		switch (doorobjlist[door].action)
    695 		{
    696 		case dr_open:
    697 			DoorOpen (door);
    698 			break;
    699 
    700 		case dr_opening:
    701 			DoorOpening(door);
    702 			break;
    703 
    704 		case dr_closing:
    705 			DoorClosing(door);
    706 			break;
    707 		}
    708 }
    709 
    710 
    711 /*
    712 =============================================================================
    713 
    714 						PUSHABLE WALLS
    715 
    716 =============================================================================
    717 */
    718 
    719 unsigned	pwallstate;
    720 unsigned	pwallpos;			// amount a pushable wall has been moved (0-63)
    721 unsigned	pwallx,pwally;
    722 int			pwalldir;
    723 
    724 /*
    725 ===============
    726 =
    727 = PushWall
    728 =
    729 ===============
    730 */
    731 
    732 void PushWall (int checkx, int checky, int dir)
    733 {
    734 	int		oldtile;
    735 
    736 	if (pwallstate)
    737 	  return;
    738 
    739 
    740 	oldtile = tilemap[checkx][checky];
    741 	if (!oldtile)
    742 		return;
    743 
    744 	switch (dir)
    745 	{
    746 	case di_north:
    747 		if (actorat[checkx][checky-1])
    748 		{
    749 			SD_PlaySound (NOWAYSND);
    750 			return;
    751 		}
    752 		(unsigned)actorat[checkx][checky-1] =
    753 		tilemap[checkx][checky-1] = oldtile;
    754 		break;
    755 
    756 	case di_east:
    757 		if (actorat[checkx+1][checky])
    758 		{
    759 			SD_PlaySound (NOWAYSND);
    760 			return;
    761 		}
    762 		(unsigned)actorat[checkx+1][checky] =
    763 		tilemap[checkx+1][checky] = oldtile;
    764 		break;
    765 
    766 	case di_south:
    767 		if (actorat[checkx][checky+1])
    768 		{
    769 			SD_PlaySound (NOWAYSND);
    770 			return;
    771 		}
    772 		(unsigned)actorat[checkx][checky+1] =
    773 		tilemap[checkx][checky+1] = oldtile;
    774 		break;
    775 
    776 	case di_west:
    777 		if (actorat[checkx-1][checky])
    778 		{
    779 			SD_PlaySound (NOWAYSND);
    780 			return;
    781 		}
    782 		(unsigned)actorat[checkx-1][checky] =
    783 		tilemap[checkx-1][checky] = oldtile;
    784 		break;
    785 	}
    786 
    787 	gamestate.secretcount++;
    788 	pwallx = checkx;
    789 	pwally = checky;
    790 	pwalldir = dir;
    791 	pwallstate = 1;
    792 	pwallpos = 0;
    793 	tilemap[pwallx][pwally] |= 0xc0;
    794 	*(mapsegs[1]+farmapylookup[pwally]+pwallx) = 0;	// remove P tile info
    795 
    796 	SD_PlaySound (PUSHWALLSND);
    797 }
    798 
    799 
    800 
    801 /*
    802 =================
    803 =
    804 = MovePWalls
    805 =
    806 =================
    807 */
    808 
    809 void MovePWalls (void)
    810 {
    811 	int		oldblock,oldtile;
    812 
    813 	if (!pwallstate)
    814 		return;
    815 
    816 	oldblock = pwallstate/128;
    817 
    818 	pwallstate += tics;
    819 
    820 	if (pwallstate/128 != oldblock)
    821 	{
    822 	// block crossed into a new block
    823 		oldtile = tilemap[pwallx][pwally] & 63;
    824 
    825 		//
    826 		// the tile can now be walked into
    827 		//
    828 		tilemap[pwallx][pwally] = 0;
    829 		(unsigned)actorat[pwallx][pwally] = 0;
    830 		*(mapsegs[0]+farmapylookup[pwally]+pwallx) = player->areanumber+AREATILE;
    831 
    832 		//
    833 		// see if it should be pushed farther
    834 		//
    835 		if (pwallstate>256)
    836 		{
    837 		//
    838 		// the block has been pushed two tiles
    839 		//
    840 			pwallstate = 0;
    841 			return;
    842 		}
    843 		else
    844 		{
    845 			switch (pwalldir)
    846 			{
    847 			case di_north:
    848 				pwally--;
    849 				if (actorat[pwallx][pwally-1])
    850 				{
    851 					pwallstate = 0;
    852 					return;
    853 				}
    854 				(unsigned)actorat[pwallx][pwally-1] =
    855 				tilemap[pwallx][pwally-1] = oldtile;
    856 				break;
    857 
    858 			case di_east:
    859 				pwallx++;
    860 				if (actorat[pwallx+1][pwally])
    861 				{
    862 					pwallstate = 0;
    863 					return;
    864 				}
    865 				(unsigned)actorat[pwallx+1][pwally] =
    866 				tilemap[pwallx+1][pwally] = oldtile;
    867 				break;
    868 
    869 			case di_south:
    870 				pwally++;
    871 				if (actorat[pwallx][pwally+1])
    872 				{
    873 					pwallstate = 0;
    874 					return;
    875 				}
    876 				(unsigned)actorat[pwallx][pwally+1] =
    877 				tilemap[pwallx][pwally+1] = oldtile;
    878 				break;
    879 
    880 			case di_west:
    881 				pwallx--;
    882 				if (actorat[pwallx-1][pwally])
    883 				{
    884 					pwallstate = 0;
    885 					return;
    886 				}
    887 				(unsigned)actorat[pwallx-1][pwally] =
    888 				tilemap[pwallx-1][pwally] = oldtile;
    889 				break;
    890 			}
    891 
    892 			tilemap[pwallx][pwally] = oldtile | 0xc0;
    893 		}
    894 	}
    895 
    896 
    897 	pwallpos = (pwallstate/2)&63;
    898 
    899 }
    900