home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DP Tool Club 18
/
CD_ASCQ_18_111294_W.iso
/
dos
/
prg
/
c
/
ack3d
/
engsrc
/
ackdoor.c
< prev
next >
Wrap
Text File
|
1993-08-22
|
10KB
|
396 lines
/******************* ( Animation Construction Kit 3D ) ***********************/
/* Door Routines */
/* CopyRight (c) 1993 Author: Lary Myers */
/*****************************************************************************/
#include <stdlib.h>
#include <stdio.h>
#include <dos.h>
#include <mem.h>
#include <alloc.h>
#include <io.h>
#include <fcntl.h>
#include <time.h>
#include <string.h>
#include <sys\stat.h>
#include "ack3d.h"
#include "ackeng.h"
#include "ackext.h"
/****************************************************************************
** Check all the doors to see what state they are in. If a door's column **
** offset is non-zero then it is either opening or closing, so add in the **
** speed of the door and check for fully open and fully closed conditions. **
** **
** **
****************************************************************************/
void CheckDoors(ACKENG *ae)
{
int i,MapPosn,mPos,mPos1;
int column,mx,my,DeltaGrid;
int xPlayer,yPlayer;
unsigned char mCode,mCode1;
xPlayer = ae->xPlayer;
yPlayer = ae->yPlayer;
for (i = 0; i < MAX_DOORS; i++)
{
if (ae->Door[i].ColOffset)
{
ae->Door[i].ColOffset += ae->Door[i].Speed;
mPos = ae->Door[i].mPos;
mPos1 = ae->Door[i].mPos1;
/* Door is closing and is visible. Put old codes back to make non-passable */
if (ae->Door[i].Speed < 0 && ae->Door[i].ColOffset < 65)
{
MapPosn = (yPlayer & 0xFFC0) + (xPlayer >> 6);
if (MapPosn == mPos ||
MapPosn == mPos1)
{
ae->Door[i].ColOffset -= ae->Door[i].Speed;
continue;
}
if (ae->Door[i].Type == DOOR_XCODE)
{
ae->xGrid[mPos] = ae->Door[i].mCode;
ae->xGrid[mPos1] = ae->Door[i].mCode1;
}
else
{
ae->yGrid[mPos] = ae->Door[i].mCode;
ae->yGrid[mPos1] = ae->Door[i].mCode1;
}
/* Door is close enough to fully closed to get rid of the door from the array */
if (ae->Door[i].ColOffset < 3)
{
ae->Door[i].ColOffset = 0;
ae->Door[i].mPos = -1;
ae->Door[i].mPos1 = -1;
ae->Door[i].Flags = 0;
}
}
/* Door is fully open, reverse the speed to begin closing */
if (ae->Door[i].ColOffset > 0xA0)
{
ae->Door[i].Speed = -ae->Door[i].Speed;
ae->Door[i].Flags &= ~DOOR_OPENING;
ae->Door[i].Flags |= DOOR_CLOSING;
}
}
}
/* Now check for any action occuring in a secret door. This is currently */
/* setup to handle only one door at a time in the X and Y directions, but */
/* it should be fairly straightforward to use a list of doors, similiar */
/* to normal doors, to handle more than one. */
if (xSecretColumn)
{
if (xSecretColumn > 0) /* See if the door is to the right of us */
{
mPos = xSecretmPos1;
DeltaGrid = -1;
xSecretColumn += ae->DoorSpeed;
}
else
{
mPos = xSecretmPos;
DeltaGrid = 0;
xSecretColumn -= ae->DoorSpeed;
}
my = mPos & 0xFFC0;
mx = (mPos - my) << 6;
if (abs(xSecretColumn) > GRID_SIZE) /* Beyond one grid square */
{
mx += xSecretColumn;
my = my + (mx >> 6);
if (ae->xGrid[my]) /* No further, an obstruction */
{
ae->xGrid[xSecretmPos] = 0;
ae->xGrid[xSecretmPos1] = 0;
my += DeltaGrid;
ae->xGrid[my] = ae->NonSecretCode;
ae->xGrid[my+1] = ae->NonSecretCode;
ae->yGrid[my] = ae->NonSecretCode;
ae->yGrid[my + GRID_WIDTH] = ae->NonSecretCode;
xSecretColumn = 0;
}
else
{
if (my != mPos)
{
ae->xGrid[xSecretmPos] = 0;
ae->xGrid[xSecretmPos1] = 0;
if (xSecretColumn > 0)
{
xSecretColumn -= 63;
ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
xSecretmPos1 = my;
my--;
ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
xSecretmPos = my;
}
else
{
xSecretColumn += 63;
ae->xGrid[my] = DOOR_TYPE_SECRET + 1;
ae->xGrid[my+1] = DOOR_TYPE_SECRET + 1;
xSecretmPos = my;
xSecretmPos = my+1;
}
}
} /* End if (xGrid[my]) ... else ... */
} /* End if (abs(xSecretColumn) > GRID_SIZE) */
} /* End if (xSecretColumn) */
/* Perform same process on a secret door that may be moving in the Y */
/* direction. The same door can move either way, depending on which */
/* angle the player struck it at. */
if (ySecretColumn)
{
if (ySecretColumn > 0)
{
mPos = ySecretmPos1;
DeltaGrid = -GRID_WIDTH;
ySecretColumn += ae->DoorSpeed;
}
else
{
mPos = ySecretmPos;
DeltaGrid = 0;
ySecretColumn -= ae->DoorSpeed;
}
my = mPos & 0xFFC0;
mx = (mPos - my) << 6;
if (abs(ySecretColumn) > GRID_SIZE)
{
my += ySecretColumn;
my = (my & 0xFFC0) + (mx >> 6);
if (ae->yGrid[my])
{
ae->yGrid[ySecretmPos] = 0;
ae->yGrid[ySecretmPos1] = 0;
my += DeltaGrid;
ae->xGrid[my] = ae->NonSecretCode;
ae->xGrid[my+1] = ae->NonSecretCode;
ae->yGrid[my] = ae->NonSecretCode;
ae->yGrid[my + GRID_WIDTH] = ae->NonSecretCode;
ySecretColumn = 0;
}
else
{
if (my != mPos)
{
ae->yGrid[ySecretmPos] = 0;
ae->yGrid[ySecretmPos1] = 0;
if (ySecretColumn > 0)
{
ySecretColumn -= 63;
ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
ySecretmPos1 = my;
my -= GRID_WIDTH;
ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
ySecretmPos = my;
}
else
{
ySecretColumn += 63;
ae->yGrid[my] = DOOR_TYPE_SECRET + 1;
ae->yGrid[my+GRID_WIDTH] = DOOR_TYPE_SECRET + 1;
ySecretmPos = my;
ySecretmPos = my+GRID_WIDTH;
}
}
}
}
}
}
/****************************************************************************
** Locate a door from its Map coordinate and return the index to the **
** caller. **
** **
****************************************************************************/
int FindDoor(int MapPosn,ACKENG *ae)
{
int index;
for (index = 0; index < MAX_DOORS; index++)
{
if (MapPosn == ae->Door[index].mPos || MapPosn == ae->Door[index].mPos1)
return(index);
}
return(-1);
}
/****************************************************************************
** Find an empty slot for a door. If the door already occupies a slot and **
** it is in a non-closed state then return error. **
** **
****************************************************************************/
int FindDoorSlot(int MapPosn,ACKENG *ae)
{
int index;
index = FindDoor(MapPosn,ae);
if (index >= 0 && ae->Door[index].ColOffset)
return(-1);
for (index = 0; index < MAX_DOORS; index++)
{
if (ae->Door[index].mPos == -1)
return(index);
}
return(-1);
}
/****************************************************************************
** The application performs this call to see if the POV is close enough to **
** a door to begin opening it. (A good time to make this call would be **
** when the POV moves). If a door is activated a return code tells the **
** application what kind of door it was (for purposes of sound, etc.) **
** **
****************************************************************************/
int AckCheckDoorOpen(int xPlayer,int yPlayer,int PlayerAngle,ACKENG *ae)
{
int i,j,DoorCode;
DoorCode = POV_NODOOR; /* Default - assumes no doors found */
i = AckCheckHit(xPlayer,yPlayer,PlayerAngle,ae);
/* Check secret doors along the X walls */
if (i == 1 && ae->xGrid[xMapPosn] & DOOR_TYPE_SECRET)
{
if (xSecretColumn == 0)
{
DoorCode = POV_XSECRETDOOR;
if (ae->xGrid[xMapPosn] & DOOR_LOCKED)
return(DoorCode | POV_DOORLOCKED);
xSecretmPos = xMapPosn;
if (iLastX > xPlayer)
{
xSecretmPos1 = xMapPosn + 1;
LastMapPosn = xMapPosn;
xSecretColumn = 1;
ae->yGrid[xMapPosn] = ae->yGrid[xMapPosn - GRID_WIDTH];
}
else
{
LastMapPosn = xSecretmPos1 = xMapPosn - 1;
xSecretColumn = -1;
ae->yGrid[xSecretmPos1] = ae->yGrid[xSecretmPos1 - GRID_WIDTH];
}
}
}
/* Check secret doors along the Y walls */
if (i == 2 && ae->yGrid[yMapPosn] & DOOR_TYPE_SECRET)
{
if (ySecretColumn == 0)
{
DoorCode = POV_YSECRETDOOR;
if (ae->yGrid[yMapPosn] & DOOR_LOCKED)
return(DoorCode | POV_DOORLOCKED);
ySecretmPos = yMapPosn;
if (iLastY > yPlayer)
{
LastMapPosn = yMapPosn;
ySecretmPos1 = yMapPosn + GRID_WIDTH;
ae->xGrid[yMapPosn] = ae->xGrid[yMapPosn-1];
ySecretColumn = 1;
}
else
{
LastMapPosn = ySecretmPos1 = yMapPosn - GRID_WIDTH;
ae->xGrid[ySecretmPos1] = ae->xGrid[ySecretmPos1 - 1];
ySecretColumn = -1;
}
}
}
/* Check doors along the X walls */
if (i == 1 && (ae->xGrid[xMapPosn] & 0xFF) == DOOR_XCODE)
{
j = FindDoorSlot(xMapPosn,ae);
if (j >= 0)
{
DoorCode = POV_XDOOR;
LastMapPosn = ae->Door[j].mPos = xMapPosn;
if ((int)iLastX > xPlayer)
i = xMapPosn + 1;
else
LastMapPosn = i = xMapPosn - 1;
if (ae->xGrid[xMapPosn] & DOOR_LOCKED)
{
ae->Door[j].mPos = -1;
return(DoorCode | POV_DOORLOCKED);
}
ae->Door[j].mCode = ae->xGrid[xMapPosn];
ae->Door[j].mCode1 = ae->xGrid[i];
ae->Door[j].mPos1 = i;
ae->Door[j].ColOffset = 1;
ae->Door[j].Speed = ae->DoorSpeed;
ae->Door[j].Type = DOOR_XCODE;
ae->Door[j].Flags = DOOR_OPENING;
}
}
/* Check doors along the Y walls */
if (i == 2 && (ae->yGrid[yMapPosn] & 0xFF) == DOOR_YCODE)
{
j = FindDoorSlot(yMapPosn,ae);
if (j >= 0)
{
DoorCode = POV_YDOOR;
LastMapPosn = ae->Door[j].mPos = yMapPosn;
if ((int)iLastY > yPlayer)
i = yMapPosn + GRID_WIDTH;
else
LastMapPosn = i = yMapPosn - GRID_WIDTH;
if (ae->yGrid[yMapPosn] & DOOR_LOCKED)
{
ae->Door[j].mPos = -1;
return(DoorCode | POV_DOORLOCKED);
}
ae->Door[j].mCode = ae->yGrid[yMapPosn];
ae->Door[j].mCode1 = ae->yGrid[i];
ae->Door[j].mPos1 = i;
ae->Door[j].ColOffset = 1;
ae->Door[j].Speed = ae->DoorSpeed;
ae->Door[j].Type = DOOR_YCODE;
ae->Door[j].Flags = DOOR_OPENING;
}
}
return(DoorCode);
}