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

362 lines
4.8 KiB
C++

//
// Tripwires.
//
#include "game.h"
#include "trip.h"
#include "animate.h"
TRIP_Wire *TRIP_wire;//[TRIP_MAX_WIRES];
SLONG TRIP_wire_upto;
#ifndef PSX
void TRIP_init()
{
TRIP_wire_upto = 1;
}
#endif
UBYTE TRIP_create(
SLONG y,
SLONG x1,
SLONG z1,
SLONG x2,
SLONG z2)
{
SLONG i;
TRIP_Wire *tw;
//
// Look for a tripwire that already exists.
//
for (i = 1; i < TRIP_wire_upto; i++)
{
tw = &TRIP_wire[i];
if (tw->y == y &&
tw->x1 == x1 &&
tw->z1 == z1 &&
tw->x2 == x2 &&
tw->z2 == z2)
{
//
// Found a tripwire in this position already!
//
return i;
}
}
//
// We have to create a new tripwire.
//
if (TRIP_wire_upto >= TRIP_MAX_WIRES)
{
//
// No more trip-wires available.
//
return NULL;
}
tw = &TRIP_wire[TRIP_wire_upto++];
tw->counter = rand();
tw->y = y;
tw->x1 = x1;
tw->z1 = z1;
tw->x2 = x2;
tw->z2 = z2;
tw->along = 255;
tw->wait = 0;
return TRIP_wire_upto - 1;
}
//
// If (x,z) lies along the line this funciton returns the amount
// along the line that (x,z) is in 8-bit fixed point, otherwise
// it returns TRIP_NOT_COLLIDED.
//
#define TRIP_NOT_COLLIDED (-1)
SLONG TRIP_collide(
SLONG x1, SLONG z1,
SLONG x2, SLONG z2,
SLONG x,
SLONG z)
{
SLONG dx;
SLONG dz;
SLONG da;
SLONG db;
SLONG len;
SLONG dist;
SLONG along;
SLONG dprod;
SLONG cprod;
dx = x2 - x1;
dz = z2 - z1;
da = x - x1;
db = z - z1;
cprod = da*dz - db*dx;
len = QDIST2(abs(dx),abs(dz)) + 1;
dist = cprod / len;
if (abs(dist) < 0x20)
{
dprod = da*dx + db*dz;
along = dprod / len;
//
// 8-bit fixed point...
//
along = (along * 256) / len;
if (WITHIN(along, 0, 256))
{
return along;
}
}
return TRIP_NOT_COLLIDED;
}
void TRIP_process()
{
SLONG i;
SLONG dx;
SLONG dy;
SLONG dz;
SLONG lfx;
SLONG lfy;
SLONG lfz;
SLONG rfx;
SLONG rfy;
SLONG rfz;
SLONG hx;
SLONG hy;
SLONG hz;
SLONG tx;
SLONG tz;
SLONG dist;
SLONG along;
SLONG feet;
SLONG head;
TRIP_Wire *tw;
Thing *darci = NET_PERSON(0);
for (i = 1; i < TRIP_wire_upto; i++)
{
tw = &TRIP_wire[i];
if (tw->x1 == TRIP_X1_DEACTIVATED)
{
//
// This magic number means the trip wire is deactivated
//
continue;
}
tw->counter += 50;
if (tw->wait)
{
ASSERT(tw->along != 255);
//
// The tripwire is triggered- don't detrigger for a while!
//
tw->wait -= 1;
continue;
}
tw->along = 255;
dx = (darci->WorldPos.X >> 8) - tw->x1;
dz = (darci->WorldPos.Z >> 8) - tw->z1;
dist = abs(dx) + abs(dz);
if (dist > 0x500)
{
//
// Too far away to be worth even bothering about.
//
continue;
}
else
{
//
// Take Darci's height from her foot.
//
calc_sub_objects_position(
darci,
darci->Draw.Tweened->AnimTween,
SUB_OBJECT_LEFT_FOOT,
&lfx,
&lfy,
&lfz);
calc_sub_objects_position(
darci,
darci->Draw.Tweened->AnimTween,
SUB_OBJECT_RIGHT_FOOT,
&rfx,
&rfy,
&rfz);
feet = MIN(lfy,rfy);
feet += darci->WorldPos.Y >> 8;
calc_sub_objects_position(
darci,
darci->Draw.Tweened->AnimTween,
SUB_OBJECT_HEAD,
&hx,
&hy,
&hz);
head = hy;
head += darci->WorldPos.Y >> 8;
if (head < feet)
{
//
// Darci can do a summersault
//
SWAP(head,feet);
}
//
// Has darci set off the trip-wire?
//
if (!WITHIN(tw->y, feet - 0x10, head + 0x10))
{
//
// Out of y-range.
//
continue;
}
along = TRIP_collide(
tw->x1, tw->z1,
tw->x2, tw->z2,
darci->WorldPos.X >> 8,
darci->WorldPos.Z >> 8);
if (along != TRIP_NOT_COLLIDED)
{
if (along == 255)
{
along = 254;
}
tw->along = along;
tw->wait = 4;
}
}
}
}
SLONG TRIP_get_upto;
TRIP_Info TRIP_get_info;
void TRIP_get_start()
{
TRIP_get_upto = 1;
}
TRIP_Info *TRIP_get_next()
{
TRIP_Wire *tw;
tail_recurse:;
if (TRIP_get_upto >= TRIP_wire_upto)
{
return NULL;
}
ASSERT(WITHIN(TRIP_get_upto, 0, TRIP_wire_upto - 1));
tw = &TRIP_wire[TRIP_get_upto++];
if (tw->x1 == TRIP_X1_DEACTIVATED)
{
//
// This magic number means the trip wire is deactivated
//
goto tail_recurse;
}
TRIP_get_info.y = tw->y;
TRIP_get_info.x1 = tw->x1;
TRIP_get_info.z1 = tw->z1;
TRIP_get_info.x2 = tw->x2;
TRIP_get_info.z2 = tw->z2;
TRIP_get_info.counter = tw->counter;
TRIP_get_info.along = tw->along;
return &TRIP_get_info;
}
SLONG TRIP_activated(UBYTE tripwire)
{
TRIP_Wire *tw;
ASSERT(WITHIN(tripwire, 0, TRIP_wire_upto - 1));
tw = &TRIP_wire[tripwire];
return (tw->along != 255);
}
void TRIP_deactivate(UBYTE tripwire)
{
TRIP_Wire *tw;
ASSERT(WITHIN(tripwire, 0, TRIP_wire_upto - 1));
tw = &TRIP_wire[tripwire];
tw->x1 = TRIP_X1_DEACTIVATED;
}