MuckyFoot-UrbanChaos/fallen/Source/door.cpp
2017-05-20 11:14:17 +10:00

443 lines
5.7 KiB
C++

//
// Doors
//
#include "game.h"
#include "door.h"
#include "mav.h"
#include "supermap.h"
#include "memory.h"
//
// Doors in the process of opening or closing.
//
DOOR_Door *DOOR_door;
//
// Finds a door facet.
//
UWORD DOOR_find(
SLONG world_x,
SLONG world_z)
{
SLONG fx;
SLONG fz;
SLONG dx;
SLONG dz;
SLONG score;
SLONG mx1 = world_x - 0x200 >> PAP_SHIFT_LO;
SLONG mz1 = world_z - 0x200 >> PAP_SHIFT_LO;
SLONG mx2 = world_x + 0x200 >> PAP_SHIFT_LO;
SLONG mz2 = world_z + 0x200 >> PAP_SHIFT_LO;
SLONG mx;
SLONG mz;
SLONG f_list;
SLONG exit;
SLONG i_facet;
DFacet *df;
SATURATE(mx1, 0, PAP_SIZE_LO - 1);
SATURATE(mz1, 0, PAP_SIZE_LO - 1);
SATURATE(mx2, 0, PAP_SIZE_LO - 1);
SATURATE(mz2, 0, PAP_SIZE_LO - 1);
SLONG best_score = INFINITY;
SLONG best_facet = NULL;
for (mx = mx1; mx <= mx2; mx++)
for (mz = mz1; mz <= mz2; mz++)
{
f_list = PAP_2LO(mx,mz).ColVectHead;
if (f_list)
{
exit = FALSE;
while(1)
{
i_facet = facet_links[f_list];
if (i_facet < 0)
{
i_facet = -i_facet;
exit = TRUE;
}
df = &dfacets[i_facet];
if (df->FacetType == STOREY_TYPE_OUTSIDE_DOOR)
{
fx = df->x[0] + df->x[1] << 7;
fz = df->z[0] + df->z[1] << 7;
dx = abs(fx - world_x);
dz = abs(fz - world_z);
score = QDIST2(dx,dz);
if (best_score > score)
{
best_score = score;
best_facet = i_facet;
}
}
if (exit)
{
break;
}
f_list += 1;
}
}
}
return best_facet;
}
void DOOR_open(SLONG world_x, SLONG world_z)
{
UWORD facet;
facet = DOOR_find(world_x, world_z);
if (facet)
{
SLONG i;
SLONG x;
SLONG z;
SLONG dx;
SLONG dz;
SLONG mx;
SLONG mz;
SLONG left;
SLONG right;
DFacet *df = &dfacets[facet];
//
// Start it opening.
//
df->FacetFlags |= FACET_FLAG_OPEN;
for (i = 0; i < DOOR_MAX_DOORS; i++)
{
if (DOOR_door[i].facet == facet)
{
goto already_being_processed;
}
}
for (i = 0; i < DOOR_MAX_DOORS; i++)
{
if (DOOR_door[i].facet == NULL)
{
DOOR_door[i].facet = facet;
}
}
already_being_processed:;
//
// Make sure nobody can navigate through this facet.
//
dx = SIGN(df->x[1] - df->x[0]);
dz = SIGN(df->z[1] - df->z[0]);
x = df->x[0];
z = df->z[0];
if (dx)
{
if (dx == 1)
{
left = MAV_DIR_ZS;
right = MAV_DIR_ZL;
}
else
{
left = MAV_DIR_ZL;
right = MAV_DIR_ZS;
}
}
else
{
if (dz == 1)
{
left = MAV_DIR_XL;
right = MAV_DIR_XS;
}
else
{
left = MAV_DIR_XS;
right = MAV_DIR_XL;
}
}
while(1)
{
mx = (x << 8) + (dx << 7);
mz = (z << 8) + (dz << 7);
mx += -dz << 7;
mz += +dx << 7;
mx >>= 8;
mz >>= 8;
MAV_turn_movement_on (mx,mz,left);
MAV_turn_car_movement_on(mx,mz,left);
mx = (x << 8) + (dx << 7);
mz = (z << 8) + (dz << 7);
mx -= -dz << 7;
mz -= +dx << 7;
mx >>= 8;
mz >>= 8;
MAV_turn_movement_on (mx,mz,right);
MAV_turn_car_movement_on(mx,mz,right);
x += dx;
z += dz;
if (x == df->x[1] &&
z == df->z[1])
{
break;
}
}
}
}
void DOOR_shut(SLONG world_x, SLONG world_z)
{
UWORD facet;
facet = DOOR_find(world_x, world_z);
if (facet)
{
SLONG i;
SLONG x;
SLONG z;
SLONG dx;
SLONG dz;
SLONG mx;
SLONG mz;
SLONG left;
SLONG right;
DFacet *df = &dfacets[facet];
//
// Start it shutting.
//
df->FacetFlags &= ~FACET_FLAG_OPEN;
for (i = 0; i < DOOR_MAX_DOORS; i++)
{
if (DOOR_door[i].facet == facet)
{
goto already_being_processed;
}
}
for (i = 0; i < DOOR_MAX_DOORS; i++)
{
if (DOOR_door[i].facet == NULL)
{
DOOR_door[i].facet = facet;
}
}
already_being_processed:;
//
// Make sure nobody can navigate through this facet.
//
dx = SIGN(df->x[1] - df->x[0]);
dz = SIGN(df->z[1] - df->z[0]);
x = df->x[0];
z = df->z[0];
if (dx)
{
//
// This is right...
//
if (dx == 1)
{
left = MAV_DIR_ZS;
right = MAV_DIR_ZL;
}
else
{
left = MAV_DIR_ZL;
right = MAV_DIR_ZS;
}
}
else
{
if (dz == 1)
{
left = MAV_DIR_XL;
right = MAV_DIR_XS;
}
else
{
left = MAV_DIR_XS;
right = MAV_DIR_XL;
}
}
while(1)
{
mx = (x << 8) + (dx << 7);
mz = (z << 8) + (dz << 7);
mx += -dz << 7;
mz += +dx << 7;
mx >>= 8;
mz >>= 8;
MAV_turn_movement_off (mx,mz,left);
MAV_turn_car_movement_off(mx,mz,left);
mx = (x << 8) + (dx << 7);
mz = (z << 8) + (dz << 7);
mx -= -dz << 7;
mz -= +dx << 7;
mx >>= 8;
mz >>= 8;
MAV_turn_movement_off (mx,mz,right);
MAV_turn_car_movement_off(mx,mz,right);
x += dx;
z += dz;
if (x == df->x[1] &&
z == df->z[1])
{
break;
}
}
}
}
//
// Make the door knock people over as it opens...
//
void DOOR_knock_over_people(DFacet *df, SLONG side)
{
SLONG dx;
SLONG dz;
SLONG x1;
SLONG z1;
SLONG x2;
SLONG z2;
dx = df->x[1] - df->x[0];
dz = df->z[1] - df->z[0];
//
// Well.. there are more important things to do!
//
}
void DOOR_process()
{
SLONG i;
SLONG open;
SLONG max;
DFacet *df;
for (i = 0; i < DOOR_MAX_DOORS; i++)
{
if (DOOR_door[i].facet)
{
df = &dfacets[DOOR_door[i].facet];
open = df->Open;
if (df->FacetFlags & FACET_FLAG_OPEN)
{
open += 4;
#define DOOR_AJAR 15
if (df->FacetFlags & FACET_FLAG_90DEGREE)
{
max = 128 - DOOR_AJAR;
}
else
{
max = 255 - DOOR_AJAR;
}
if (open > max)
{
open = max;
DOOR_door[i].facet = NULL;
}
}
else
{
open -= 4;
if (open < 0)
{
open = 0;
DOOR_door[i].facet = NULL;
}
}
df->Open = open;
}
}
}