mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-08 03:28:03 +03:00
1432 lines
No EOL
31 KiB
C++
1432 lines
No EOL
31 KiB
C++
#include "../newobjects.h"
|
|
#include "../oldobjects.h"
|
|
#include "../../Game/lara.h"
|
|
#include "../../Game/draw.h"
|
|
#include "../../Global/global.h"
|
|
#include "../../Game/items.h"
|
|
#include "../../Game/collide.h"
|
|
#include "../../Game/effects.h"
|
|
#include "../../Game/laramisc.h"
|
|
#include "../../Game/Box.h"
|
|
#include "../../Game/tomb4fx.h"
|
|
#include "../../Game/switch.h"
|
|
#include "../../Game/spotcam.h"
|
|
#include "../../Game/effect2.h"
|
|
#include "../../Game/sphere.h"
|
|
#include "../../Game/traps.h"
|
|
|
|
short SPyoffs[8] =
|
|
{
|
|
0xFC00, 0x0000, 0xFE00, 0x0000, 0x0000, 0x0000, 0xFE00, 0x0000
|
|
};
|
|
|
|
short SPxzoffs[8] =
|
|
{
|
|
0x0000, 0x0000, 0x0200, 0x0000, 0x0000, 0x0000, 0xFE00, 0x0000
|
|
};
|
|
|
|
short SPDETyoffs[8] =
|
|
{
|
|
0x0400, 0x0200, 0x0200, 0x0200, 0x0000, 0x0200, 0x0200, 0x0200
|
|
};
|
|
|
|
void InitialiseTeethSpikes(short itemNumber)
|
|
{
|
|
short rotations[] = { -ANGLE(180), -ANGLE(135), -ANGLE(90), -ANGLE(45), ANGLE(0), ANGLE(45), ANGLE(90), ANGLE(135) };
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
item->status = ITEM_INVISIBLE;
|
|
|
|
int angle;
|
|
if (item->triggerFlags & 8)
|
|
{
|
|
angle = item->triggerFlags & 7;
|
|
item->pos.xRot = rotations[angle];
|
|
item->pos.yRot = ANGLE(90);
|
|
item->pos.zPos -= SPxzoffs[angle];
|
|
}
|
|
else
|
|
{
|
|
angle = item->triggerFlags & 7;
|
|
item->pos.zRot = rotations[angle];
|
|
item->pos.xPos += SPxzoffs[angle];
|
|
}
|
|
|
|
item->itemFlags[0] = 1024;
|
|
item->itemFlags[2] = 0;
|
|
item->pos.yPos += SPyoffs[angle];
|
|
}
|
|
|
|
int CollidedWithTeethSpikes(ITEM_INFO* item)
|
|
{
|
|
short angle;
|
|
int x;
|
|
int z;
|
|
|
|
if (item->triggerFlags & 8)
|
|
{
|
|
angle = item->triggerFlags & 7;
|
|
x = item->pos.xPos & 0xFFFFFE00 | 0x200;
|
|
z = (item->pos.zPos + SPxzoffs[angle]) & 0xFFFFFE00 | 0x200;
|
|
}
|
|
else
|
|
{
|
|
angle = item->triggerFlags & 7;
|
|
x = (item->pos.xPos - SPxzoffs[angle]) & 0xFFFFFE00 | 0x200;
|
|
z = item->pos.zPos & 0xFFFFFE00 | 0x200;
|
|
}
|
|
|
|
int delta = -((angle & 1) != 0);
|
|
delta = delta & 0xFF4C;
|
|
delta += 480;
|
|
int y = item->pos.yPos + SPDETyoffs[angle];
|
|
short* frames = GetBestFrame(LaraItem);
|
|
|
|
if (LaraItem->pos.yPos + frames[2] <= y && LaraItem->pos.yPos + frames[3] >= y - 900)
|
|
{
|
|
if (LaraItem->pos.xPos + frames[0] <= (x + delta) && LaraItem->pos.xPos + frames[1] >= (x - delta))
|
|
{
|
|
if (LaraItem->pos.zPos + frames[4] <= (z + delta) && LaraItem->pos.zPos + frames[5] >= (z - delta))
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ControlTeethSpikes(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (!TriggerActive(item) || item->itemFlags[2])
|
|
{
|
|
if (TriggerActive(item))
|
|
{
|
|
item->itemFlags[1] -= item->itemFlags[0];
|
|
item->itemFlags[0] += (item->itemFlags[0] >> 3) + 32;
|
|
|
|
if (item->itemFlags[1] < 0)
|
|
{
|
|
item->itemFlags[0] = 1024;
|
|
item->itemFlags[1] = 0;
|
|
item->status = ITEM_INVISIBLE;
|
|
}
|
|
|
|
if (item->triggerFlags & 0x20)
|
|
{
|
|
item->itemFlags[2] = 1;
|
|
}
|
|
else
|
|
{
|
|
if (item->itemFlags[2])
|
|
{
|
|
item->itemFlags[2]--;
|
|
}
|
|
}
|
|
}
|
|
else if (!item->timer)
|
|
{
|
|
item->itemFlags[0] += (item->itemFlags[0] >> 3) + 32;
|
|
|
|
if (item->itemFlags[1] > 0)
|
|
{
|
|
item->itemFlags[1] -= item->itemFlags[0];
|
|
if (item->itemFlags[1] < 0)
|
|
item->itemFlags[1] = 0;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (item->itemFlags[0] == 1024)
|
|
SoundEffect(SFX_TEETH_SPIKES, &item->pos, 0);
|
|
|
|
item->status = ITEM_ACTIVE;
|
|
|
|
if (LaraItem->hitPoints > 0 && CollidedWithTeethSpikes(item))
|
|
{
|
|
short* itemFrames = GetBestFrame(item);
|
|
short* laraFrames = GetBestFrame(LaraItem);
|
|
|
|
short angle = item->triggerFlags & 7;
|
|
int numBloods = 0;
|
|
|
|
if ((item->itemFlags[0] > 1024 || LaraItem->gravityStatus) && angle > 2 && angle < 6)
|
|
{
|
|
if (LaraItem->fallspeed > 6 || item->itemFlags[0] > 1024)
|
|
{
|
|
LaraItem->hitPoints = -1;
|
|
numBloods = 20;
|
|
}
|
|
}
|
|
else if (LaraItem->speed < 30)
|
|
{
|
|
numBloods = 0;
|
|
}
|
|
else
|
|
{
|
|
LaraItem->hitPoints -= 8;
|
|
numBloods = (GetRandomControl() & 3) + 2;
|
|
}
|
|
|
|
int laraY1 = LaraItem->pos.yPos + laraFrames[2];
|
|
int laraY2 = LaraItem->pos.yPos + laraFrames[3];
|
|
|
|
short triggerFlags = item->triggerFlags & 0xF;
|
|
int itemY1;
|
|
int itemY2;
|
|
|
|
if (triggerFlags != 8 && triggerFlags)
|
|
{
|
|
itemY1 = itemFrames[2];
|
|
itemY2 = itemFrames[3];
|
|
}
|
|
else
|
|
{
|
|
itemY1 = -itemFrames[3];
|
|
itemY2 = -itemFrames[2];
|
|
}
|
|
if (laraY1 < item->pos.yPos + itemY1)
|
|
laraY1 = itemY1 + item->pos.yPos;
|
|
if (laraY2 > item->pos.yPos + itemY2)
|
|
laraY2 = itemY2 + item->pos.yPos;
|
|
|
|
long dy = laraY1 - laraY2;
|
|
int modulus = (HIDWORD(dy) ^ dy) - HIDWORD(dy) + 1;
|
|
|
|
angle = item->triggerFlags & 7;
|
|
if (angle == 2 || angle == 6)
|
|
numBloods /= 2;
|
|
|
|
for (int i = 0; i < numBloods; i++)
|
|
{
|
|
TriggerBlood(
|
|
(GetRandomControl() & 0x7F) + LaraItem->pos.xPos - 64,
|
|
laraY2 - GetRandomControl() % modulus,
|
|
(GetRandomControl() & 0x7F) + LaraItem->pos.zPos - 64,
|
|
2 * GetRandomControl(),
|
|
1);
|
|
}
|
|
|
|
if (LaraItem->hitPoints <= 0)
|
|
{
|
|
short roomNumber = LaraItem->roomNumber;
|
|
FLOOR_INFO* floor = GetFloor(LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos, &roomNumber);
|
|
int height = GetFloorHeight(floor, LaraItem->pos.xPos, LaraItem->pos.yPos, LaraItem->pos.zPos);
|
|
|
|
if (item->pos.yPos >= LaraItem->pos.yPos && height - LaraItem->pos.yPos < 50)
|
|
{
|
|
LaraItem->animNumber = ANIMATION_LARA_SPIKED;
|
|
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
|
|
LaraItem->currentAnimState = STATE_LARA_DEATH;
|
|
LaraItem->goalAnimState = STATE_LARA_DEATH;
|
|
LaraItem->gravityStatus = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
item->itemFlags[0] += 128;
|
|
item->itemFlags[1] += item->itemFlags[0];
|
|
|
|
if (item->itemFlags[1] >= 5120)
|
|
{
|
|
item->itemFlags[1] = 5120;
|
|
if (item->itemFlags[0] <= 1024)
|
|
{
|
|
item->itemFlags[0] = 0;
|
|
if (!(item->triggerFlags & 0x10))
|
|
{
|
|
if (LaraItem->hitPoints > 0)
|
|
item->itemFlags[2] = 64;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] = -item->itemFlags[0] >> 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void InitialiseRaisingCog(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
short itemNos[32];
|
|
int numSwitchItems = GetSwitchTrigger(item, itemNos, 1);
|
|
|
|
if (numSwitchItems > 0)
|
|
{
|
|
for (int i = 0; i < numSwitchItems; i++)
|
|
{
|
|
ITEM_INFO* currentItem = &Items[itemNos[i]];
|
|
|
|
if (currentItem->objectNumber == ID_TRIGGER_TRIGGERER)
|
|
{
|
|
item->itemFlags[1] = currentItem->roomNumber;
|
|
}
|
|
|
|
if (currentItem->objectNumber == ID_PULLEY || currentItem->objectNumber == ID_TRIGGER_TRIGGERER)
|
|
{
|
|
currentItem->itemFlags[1] = 1;
|
|
PulleyItemNumber = itemNos[i];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void RaisingCogControl(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (TriggerActive(item))
|
|
{
|
|
if (item->itemFlags[0] >= 3)
|
|
{
|
|
AnimateItem(item);
|
|
}
|
|
else
|
|
{
|
|
if (item->itemFlags[2] >= 256)
|
|
{
|
|
item->itemFlags[2] = 0;
|
|
item->itemFlags[0]++;
|
|
|
|
if (item->itemFlags[0] == 3)
|
|
{
|
|
short itemNos[32];
|
|
short numItems = GetSwitchTrigger(item, itemNos, 1);
|
|
|
|
if (numItems > 0)
|
|
{
|
|
for (int i = 0; i < numItems; i++)
|
|
{
|
|
ITEM_INFO* currentItem = &Items[itemNos[i]];
|
|
|
|
if (item->objectNumber == ID_PULLEY)
|
|
{
|
|
if (currentItem->roomNumber == item->itemFlags[1])
|
|
{
|
|
currentItem->itemFlags[1] = 0;
|
|
currentItem->collidable = true;
|
|
}
|
|
else
|
|
{
|
|
currentItem->itemFlags[1] = 1;
|
|
}
|
|
}
|
|
else if (item->objectNumber == ID_TRIGGER_TRIGGERER)
|
|
{
|
|
AddActiveItem(itemNos[i]);
|
|
currentItem->status = ITEM_ACTIVE;
|
|
currentItem->aiBits = (GUARD | MODIFY | AMBUSH | PATROL1 | FOLLOW);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
RemoveActiveItem(itemNumber);
|
|
item->status = ITEM_INACTIVE;
|
|
item->aiBits = 0;
|
|
}
|
|
else
|
|
{
|
|
if (!item->itemFlags[2])
|
|
{
|
|
InitialiseSpotCam(item->itemFlags[2]);
|
|
UseSpotCam = 1;
|
|
}
|
|
|
|
int flags = 0;
|
|
|
|
if (item->itemFlags[2] >= 31)
|
|
{
|
|
if (item->itemFlags[2] <= 224)
|
|
flags = 31;
|
|
else
|
|
flags = 255 - item->itemFlags[2];
|
|
}
|
|
else
|
|
{
|
|
flags = item->itemFlags[2];
|
|
}
|
|
|
|
SoundEffect(SFX_BLK_PLAT_RAISE_LOW, &item->pos, (flags << 8) | 8);
|
|
|
|
item->itemFlags[2] += 2;
|
|
item->pos.yPos -= 2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void TriggerElectricityWiresSparks(int x, int z, char objNum, char node, int flags)
|
|
{
|
|
SPARKS* spark = &Sparks[GetFreeSpark()];
|
|
|
|
spark->on = 1;
|
|
spark->sR = -1;
|
|
spark->sG = -1;
|
|
spark->sB = -1;
|
|
spark->dB = -1;
|
|
spark->dG = (GetRandomControl() & 0x7F) + 64;
|
|
spark->dR = 0;
|
|
|
|
if (flags)
|
|
{
|
|
spark->colFadeSpeed = 1;
|
|
spark->fadeToBlack = 0;
|
|
spark->life = spark->sLife = 4;
|
|
}
|
|
else
|
|
{
|
|
spark->colFadeSpeed = 3;
|
|
spark->fadeToBlack = 4;
|
|
spark->life = spark->sLife = 16;
|
|
}
|
|
|
|
spark->fxObj = objNum;
|
|
spark->transType = 2;
|
|
spark->flags = SP_ITEM | SP_NODEATTATCH | SP_SCALE | SP_DEF;
|
|
spark->nodeNumber = node;
|
|
spark->x = x;
|
|
spark->z = z;
|
|
spark->y = 0;
|
|
|
|
if (flags)
|
|
{
|
|
spark->xVel = 0;
|
|
spark->yVel = 0;
|
|
spark->zVel = 0;
|
|
}
|
|
else
|
|
{
|
|
spark->xVel = (GetRandomControl() & 0x1FF) - 256;
|
|
spark->yVel = GetRandomControl() - 64;
|
|
spark->zVel = (GetRandomControl() & 0x1FF) - 256;
|
|
}
|
|
spark->friction = 51;
|
|
spark->maxYvel = 0;
|
|
spark->gravity = 0;
|
|
|
|
if (flags)
|
|
{
|
|
spark->scalar = 1;
|
|
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 11;
|
|
spark->size = spark->sSize = (GetRandomControl() & 0x1F) + 160;
|
|
}
|
|
else
|
|
{
|
|
spark->scalar = 0;
|
|
spark->def = Objects[ID_DEFAULT_SPRITES].meshIndex + 14;
|
|
spark->size = spark->sSize = (GetRandomControl() & 7) + 8;
|
|
}
|
|
|
|
spark->dSize = spark->size >> 1;
|
|
}
|
|
|
|
void TriggerLaraElectricitySparks(int flame)
|
|
{
|
|
PHD_VECTOR pos;
|
|
pos.x = 0;
|
|
pos.y = 0;
|
|
pos.z = 0;
|
|
|
|
GetLaraJointPosition(&pos, GetRandomControl() % 15);
|
|
|
|
SPARKS* spark = &Sparks[GetFreeSpark()];
|
|
|
|
spark->on = 1;
|
|
spark->dR = 0;
|
|
spark->colFadeSpeed = 8;
|
|
byte color = (GetRandomControl() & 0x3F) - 64;
|
|
spark->sR = color;
|
|
spark->sB = color;
|
|
spark->sG = color;
|
|
spark->dB = color;
|
|
spark->dG = color >> 1;
|
|
spark->transType = 2;
|
|
spark->fadeToBlack = 4;
|
|
spark->life = 12;
|
|
spark->sLife = 12;
|
|
spark->x = pos.x;
|
|
spark->y = pos.y;
|
|
spark->z = pos.z;
|
|
spark->xVel = 2 * (GetRandomControl() & 0x1FF) - 512;
|
|
spark->yVel = 2 * (GetRandomControl() & 0x1FF) - 512;
|
|
spark->zVel = 2 * (GetRandomControl() & 0x1FF) - 512;
|
|
spark->friction = 51;
|
|
spark->maxYvel = 0;
|
|
spark->gravity = 0;
|
|
spark->flags = 0;
|
|
|
|
if (flame)
|
|
TriggerFireFlame(pos.x, pos.y, pos.z, -1, 254);
|
|
}
|
|
|
|
int ElectricityWireCheckDeadlyBounds(PHD_VECTOR* pos, short delta)
|
|
{
|
|
if (pos->x + delta >= DeadlyBounds[0] && pos->x - delta <= DeadlyBounds[1]
|
|
&& pos->y + delta >= DeadlyBounds[2] && pos->y - delta <= DeadlyBounds[3]
|
|
&& pos->z + delta >= DeadlyBounds[4] && pos->z - delta <= DeadlyBounds[5])
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void ElectricityWiresControl(short itemNumber)
|
|
{
|
|
bool flag = false;
|
|
int counter = 3;
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->itemFlags[0] > 2)
|
|
{
|
|
TriggerDynamicLight(
|
|
LaraItem->pos.xPos,
|
|
LaraItem->pos.yPos,
|
|
LaraItem->pos.zPos,
|
|
item->itemFlags[0],
|
|
0,
|
|
(GetRandomControl() & 0x1F) + 8 * item->itemFlags[0],
|
|
(GetRandomControl() & 0x1F) + 8 * item->itemFlags[0]);
|
|
|
|
item->itemFlags[0] -= 2;
|
|
}
|
|
|
|
if (TriggerActive(item))
|
|
{
|
|
SoundEffect(SFX_ELECTRIC_WIRES, &item->pos, 0);
|
|
|
|
counter = (abs(LaraItem->pos.xPos - item->pos.xPos) > 2048)
|
|
+ (abs(LaraItem->pos.zPos - item->pos.zPos) > 2048)
|
|
+ (abs(LaraItem->pos.yPos - item->pos.yPos) > 4096);
|
|
|
|
int x = (GetRandomControl() & 0x1F) - 16;
|
|
int z = (GetRandomControl() & 0x1F) - 16;
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
{
|
|
if (GetRandomControl() & 1)
|
|
TriggerElectricityWiresSparks(x, z, itemNumber, i + 2, 0);
|
|
}
|
|
|
|
if (!(GlobalCounter & 3))
|
|
{
|
|
TriggerElectricityWiresSparks(0, 0, itemNumber, 2, 1);
|
|
TriggerElectricityWiresSparks(0, 0, itemNumber, 3, 1);
|
|
TriggerElectricityWiresSparks(0, 0, itemNumber, 4, 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
flag = true;
|
|
}
|
|
|
|
AnimateItem(item);
|
|
|
|
if (!Lara.burn && !flag && !counter)
|
|
{
|
|
GetLaraDeadlyBounds();
|
|
|
|
int i = 2;
|
|
while (true)
|
|
{
|
|
PHD_VECTOR pos;
|
|
pos.x = 0;
|
|
pos.y = 0;
|
|
pos.z = 0;
|
|
|
|
GetJointAbsPosition(item, &pos, i);
|
|
|
|
if (ElectricityWireCheckDeadlyBounds(&pos, item->triggerFlags))
|
|
{
|
|
for (int i = 0; i < 48; i++)
|
|
{
|
|
TriggerLaraElectricitySparks(0);
|
|
}
|
|
|
|
item->itemFlags[0] = 28;
|
|
LaraBurn();
|
|
Lara.burnBlue = 1;
|
|
Lara.BurnCount = 48;
|
|
LaraItem->hitPoints = 0;
|
|
return;
|
|
}
|
|
|
|
i += 3;
|
|
if (i >= 27)
|
|
break;
|
|
}
|
|
}
|
|
|
|
int i = 8;
|
|
int j = 0;
|
|
counter = GlobalCounter % 3;
|
|
short roomNumber = item->roomNumber;
|
|
bool water = false;
|
|
|
|
do
|
|
{
|
|
PHD_VECTOR pos;
|
|
pos.x = 0;
|
|
pos.y = 0;
|
|
pos.z = 256;
|
|
GetJointAbsPosition(item, &pos, i);
|
|
|
|
if (GetRandomControl() & 1 && !flag)
|
|
{
|
|
TriggerDynamicLight(pos.x, pos.y, pos.z, 12, 0, ((GetRandomControl() & 0x3F) + 128) >> 1, (GetRandomControl() & 0x3F) + 128);
|
|
}
|
|
|
|
roomNumber = item->roomNumber;
|
|
GetFloor(pos.x, pos.y, pos.z, &roomNumber);
|
|
ROOM_INFO* r = &Rooms[roomNumber];
|
|
|
|
if (r->flags & ENV_FLAG_WATER)
|
|
{
|
|
if (counter == j)
|
|
{
|
|
SetupRipple(pos.x, r->maxceiling, pos.z, (GetRandomControl() & 7) + 32, 16);
|
|
}
|
|
|
|
water = true;
|
|
}
|
|
|
|
i += 9;
|
|
j++;
|
|
} while (i < 27);
|
|
|
|
if (!flag && !Lara.burn)
|
|
{
|
|
if (water)
|
|
{
|
|
int flipNumber = Rooms[roomNumber].flipNumber;
|
|
|
|
PHD_VECTOR pos1;
|
|
pos1.x = 0;
|
|
pos1.y = 0;
|
|
pos1.z = 0;
|
|
GetLaraJointPosition(&pos1, LJ_LFOOT);
|
|
|
|
short roomNumber1 = LaraItem->roomNumber;
|
|
GetFloor(pos1.x, pos1.y, pos1.z, &roomNumber1);
|
|
|
|
PHD_VECTOR pos2;
|
|
pos2.x = 0;
|
|
pos2.y = 0;
|
|
pos2.z = 0;
|
|
GetLaraJointPosition(&pos2, LJ_RFOOT);
|
|
|
|
short roomNumber2 = LaraItem->roomNumber;
|
|
GetFloor(pos2.x, pos2.y, pos2.z, &roomNumber2);
|
|
|
|
if (Rooms[roomNumber1].flipNumber == flipNumber
|
|
|| Rooms[roomNumber2].flipNumber == flipNumber)
|
|
{
|
|
if (LaraItem->hitPoints > 32)
|
|
{
|
|
SoundEffect(SFX_LARA_ELECTRIC_CRACKLES, &LaraItem->pos, 0);
|
|
TriggerLaraElectricitySparks(0);
|
|
TriggerLaraElectricitySparks(1);
|
|
TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 8, 0, GetRandomControl() & 0x7F, (GetRandomControl() & 0x3F) + 128);
|
|
LaraItem->hitPoints -= 10;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] = 28;
|
|
LaraBurn();
|
|
Lara.burnBlue = 1;
|
|
Lara.BurnCount = 48;
|
|
LaraItem->hitPoints = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void InitialiseRomeHammer(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
item->itemFlags[0] = 2;
|
|
item->itemFlags[3] = 250;
|
|
}
|
|
|
|
void VentilatorEffect(short* bounds, int intensity, short rot, int speed)
|
|
{
|
|
int x, y, z;
|
|
|
|
if (abs(intensity) == 1)
|
|
{
|
|
x = (bounds[0]+bounds[1]) >> 1;
|
|
if (intensity >= 0)
|
|
y = bounds[3];
|
|
else
|
|
y = bounds[2];
|
|
z = (bounds[4] + bounds[5]) >> 1;
|
|
}
|
|
else
|
|
{
|
|
y = (bounds[2]+bounds[3]) >> 1;
|
|
if (rot & 0x7FFF)
|
|
{
|
|
if (intensity >= 0)
|
|
z = bounds[5];
|
|
else
|
|
z = bounds[4];
|
|
x = (bounds[0]+bounds[1]) >> 1;
|
|
}
|
|
else
|
|
{
|
|
if (intensity >= 0)
|
|
x = bounds[1];
|
|
else
|
|
x = bounds[0];
|
|
z = (bounds[4] + bounds[5]) >> 1;
|
|
}
|
|
}
|
|
|
|
if (abs(Camera.pos.x-x) <= 7168)
|
|
{
|
|
if (abs(Camera.pos.y-y) <= 7168)
|
|
{
|
|
if (abs(Camera.pos.z-z) <= 7168)
|
|
{
|
|
SPARKS* spark = &Sparks[GetFreeSpark()];
|
|
|
|
spark->on = 1;
|
|
spark->sR = 0;
|
|
spark->sG = 0;
|
|
spark->sB = 0;
|
|
spark->dR = spark->dG = 48 * speed >> 7;
|
|
spark->colFadeSpeed = 4;
|
|
spark->fadeToBlack = 8;
|
|
spark->dB = speed * ((GetRandomControl() & 8) + 48) >> 7;
|
|
spark->transType = COLADD;
|
|
spark->life = spark->sLife = (GetRandomControl() & 3) + 20;
|
|
|
|
if (abs(intensity) == 1)
|
|
{
|
|
int factor = 3 * (bounds[1]-bounds[0]) >> 3;
|
|
short angle = 2 * GetRandomControl();
|
|
|
|
spark->x = ((bounds[0] + bounds[1]) >> 1) + ((GetRandomControl() % factor) * SIN(angle) >> W2V_SHIFT);
|
|
spark->z = ((bounds[4] + bounds[5]) >> 1) + ((GetRandomControl() % factor) * COS(angle) >> W2V_SHIFT);
|
|
|
|
if (intensity >= 0)
|
|
spark->y = bounds[3];
|
|
else
|
|
spark->y = bounds[2];
|
|
|
|
spark->zVel = 0;
|
|
spark->xVel = 0;
|
|
spark->yVel = 32 * intensity * ((GetRandomControl() & 0x1F) + 224);
|
|
}
|
|
else
|
|
{
|
|
int factor = 3 * (bounds[3] - bounds[2]) >> 3;
|
|
short angle = 2 * GetRandomControl();
|
|
|
|
spark->y = (bounds[2] + bounds[3]) >> 1;
|
|
|
|
if (rot & 0x7FFF)
|
|
{
|
|
if (intensity >= 0)
|
|
spark->z = bounds[5];
|
|
else
|
|
spark->z = bounds[4];
|
|
|
|
spark->x = ((bounds[0] + bounds[1]) >> 1) + ((GetRandomControl() % factor) * COS(angle) >> W2V_SHIFT);
|
|
spark->y += (GetRandomControl() % factor) * SIN(angle) >> W2V_SHIFT;
|
|
spark->xVel = 0;
|
|
spark->zVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
|
|
}
|
|
else
|
|
{
|
|
if (intensity >= 0)
|
|
spark->x = bounds[1];
|
|
else
|
|
spark->x = bounds[0];
|
|
|
|
spark->y += (GetRandomControl() % factor) * SIN(angle) >> W2V_SHIFT;
|
|
spark->z = ((bounds[4] + bounds[5]) >> 1) + ((GetRandomControl() % factor) * COS(angle) >> W2V_SHIFT);
|
|
spark->zVel = 0;
|
|
spark->xVel = 16 * intensity * ((GetRandomControl() & 0x1F) + 224);
|
|
}
|
|
|
|
spark->yVel = 0;
|
|
}
|
|
|
|
spark->friction = 85;
|
|
spark->xVel = speed * spark->xVel >> 7;
|
|
spark->yVel = speed * spark->yVel >> 7;
|
|
spark->zVel = speed * spark->zVel >> 7;
|
|
spark->maxYvel = 0;
|
|
spark->gravity = 0;
|
|
spark->flags = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void InitialiseVentilator(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
item->itemFlags[0] = item->triggerFlags << WALL_SHIFT;
|
|
if (item->itemFlags[0] < 2048)
|
|
item->itemFlags[0] = 3072;
|
|
}
|
|
|
|
void VentilatorControl(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
AnimateItem(item);
|
|
|
|
int xChange = 0;
|
|
int zChange = 0;
|
|
|
|
if (TriggerActive(item))
|
|
{
|
|
xChange = 1;
|
|
}
|
|
else
|
|
{
|
|
xChange = 1;
|
|
TestTriggersAtXYZ(item->pos.xPos, item->pos.yPos, item->pos.zPos, item->roomNumber, 1, 0);
|
|
if (item->currentAnimState == 1)
|
|
{
|
|
//result = 5 * item->animNumber;
|
|
if (item->frameNumber == Anims[item->animNumber].frameEnd)
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = 1;
|
|
}
|
|
}
|
|
|
|
int speed = 0;
|
|
if (item->currentAnimState == 1)
|
|
{
|
|
speed = Anims[item->animNumber].frameEnd - item->frameNumber;
|
|
}
|
|
else
|
|
{
|
|
speed = 128;
|
|
}
|
|
|
|
short* bounds = GetBoundsAccurate(item);
|
|
short effectBounds[6];
|
|
|
|
effectBounds[2] = item->pos.yPos + bounds[2];
|
|
effectBounds[3] = item->pos.yPos + bounds[3];
|
|
|
|
if (item->objectNumber != ID_PROPELLER_V) // TODO: check this ID
|
|
{
|
|
if (item->pos.yRot != -ANGLE(180))
|
|
{
|
|
if (item->pos.yRot == -ANGLE(90))
|
|
{
|
|
effectBounds[0] = item->pos.xPos - bounds[5];
|
|
effectBounds[1] = item->pos.xPos - bounds[4];
|
|
effectBounds[4] = item->pos.zPos + bounds[0];
|
|
effectBounds[5] = item->pos.zPos + bounds[1];
|
|
xChange = 0;
|
|
zChange = 1;
|
|
}
|
|
else
|
|
{
|
|
if (item->pos.yRot != ANGLE(90))
|
|
{
|
|
effectBounds[0] = item->pos.xPos + bounds[0];
|
|
effectBounds[1] = item->pos.xPos + bounds[1];
|
|
effectBounds[4] = item->pos.zPos + bounds[4];
|
|
effectBounds[5] = item->pos.zPos + bounds[5];
|
|
zChange = 0;
|
|
}
|
|
else
|
|
{
|
|
effectBounds[0] = item->pos.xPos + bounds[4];
|
|
effectBounds[1] = item->pos.xPos + bounds[5];
|
|
effectBounds[4] = item->pos.zPos - bounds[1];
|
|
effectBounds[5] = item->pos.zPos - bounds[0];
|
|
xChange = 0;
|
|
zChange = 1;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
effectBounds[0] = item->pos.xPos - bounds[1];
|
|
effectBounds[1] = item->pos.xPos - bounds[0];
|
|
effectBounds[4] = item->pos.zPos - bounds[5];
|
|
effectBounds[5] = item->pos.zPos - bounds[4];
|
|
zChange = 0;
|
|
}
|
|
|
|
VentilatorEffect(effectBounds, 2, item->pos.yRot, speed);
|
|
VentilatorEffect(effectBounds, -2, item->pos.yRot, speed);
|
|
|
|
if (LaraItem->pos.yPos >= effectBounds[2] && LaraItem->pos.yPos <= effectBounds[3])
|
|
{
|
|
if (zChange)
|
|
{
|
|
if (LaraItem->pos.xPos >= effectBounds[0] && LaraItem->pos.xPos <= effectBounds[1])
|
|
{
|
|
int z1 = abs(LaraItem->pos.zPos - effectBounds[4]);
|
|
int z2 = abs(LaraItem->pos.zPos - effectBounds[5]);
|
|
|
|
if (z2 >= z1)
|
|
zChange = -zChange;
|
|
else
|
|
z1 = z2;
|
|
|
|
if (z1 < item->itemFlags[0])
|
|
{
|
|
int dz = 96 * zChange * (item->itemFlags[0] - z1) / item->itemFlags[0];
|
|
if (item->currentAnimState == 1)
|
|
dz = speed * dz / 120;
|
|
LaraItem->pos.zPos += dz;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (LaraItem->pos.zPos >= effectBounds[4] && LaraItem->pos.zPos <= effectBounds[5])
|
|
{
|
|
int x1 = abs(LaraItem->pos.xPos - effectBounds[0]);
|
|
int x2 = abs(LaraItem->pos.xPos - effectBounds[0]);
|
|
|
|
if (x2 >= x1)
|
|
xChange = -xChange;
|
|
else
|
|
x1 = x2;
|
|
|
|
if (x1 < item->itemFlags[0])
|
|
{
|
|
int dx = 96 * xChange * (item->itemFlags[0] - x1) / item->itemFlags[0];
|
|
if (item->currentAnimState == 1)
|
|
dx = speed * dx / 120;
|
|
LaraItem->pos.xPos += dx;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
phd_PushUnitMatrix();
|
|
phd_RotYXZ(item->pos.yRot, item->pos.xRot, item->pos.zRot);
|
|
phd_SetTrans(0, 0, 0);
|
|
short tbounds[6];
|
|
phd_RotBoundingBoxNoPersp(bounds, tbounds);
|
|
phd_PopMatrix();
|
|
|
|
effectBounds[0] = item->pos.xPos + tbounds[0];
|
|
effectBounds[1] = item->pos.xPos + tbounds[1];
|
|
effectBounds[4] = item->pos.zPos + tbounds[4];
|
|
effectBounds[5] = item->pos.zPos + tbounds[5];
|
|
|
|
VentilatorEffect(effectBounds, 1, 0, speed);
|
|
VentilatorEffect(effectBounds, -1, 0, speed);
|
|
|
|
if (LaraItem->pos.xPos >= effectBounds[0] && LaraItem->pos.xPos <= effectBounds[1])
|
|
{
|
|
if (LaraItem->pos.zPos >= effectBounds[4] && LaraItem->pos.zPos <= effectBounds[5])
|
|
{
|
|
int y = effectBounds[3];
|
|
|
|
if (LaraItem->pos.yPos <= effectBounds[3])
|
|
{
|
|
if (effectBounds[2] - LaraItem->pos.yPos >= item->itemFlags[0])
|
|
return;
|
|
y = 96 * (effectBounds[3] - item->itemFlags[0]) / item->itemFlags[0];
|
|
}
|
|
else
|
|
{
|
|
if (LaraItem->pos.yPos - effectBounds[3] >= item->itemFlags[0])
|
|
return;
|
|
y = 96 * (item->itemFlags[0] - (LaraItem->pos.yPos - effectBounds[3])) / item->itemFlags[0];
|
|
}
|
|
if (item->currentAnimState == 1)
|
|
y = speed * y / 120;
|
|
LaraItem->pos.yPos += y;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DartControl(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->touchBits)
|
|
{
|
|
LaraItem->hitPoints -= 25;
|
|
LaraItem->hitStatus = true;
|
|
Lara.poisoned += 160;
|
|
DoBloodSplat(item->pos.xPos, item->pos.yPos, item->pos.zPos, (GetRandomControl() & 3) + 4, LaraItem->pos.yRot, LaraItem->roomNumber);
|
|
KillItem(itemNumber);
|
|
}
|
|
else
|
|
{
|
|
item->pos.xPos += item->speed * SIN(item->pos.yRot) >> W2V_SHIFT;
|
|
item->pos.yPos -= item->speed * SIN(item->pos.xRot) >> W2V_SHIFT;
|
|
item->pos.xPos += item->speed * COS(item->pos.yRot) >> W2V_SHIFT;
|
|
|
|
short roomNumber = item->roomNumber;
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
|
|
if (item->roomNumber != roomNumber)
|
|
ItemNewRoom(itemNumber, roomNumber);
|
|
|
|
int height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
item->floor = height;
|
|
|
|
if (item->pos.yPos >= height)
|
|
{
|
|
for (int i = 0; i < 4; i++)
|
|
{
|
|
TriggerDartSmoke(item->pos.xPos, item->pos.yPos, item->pos.zPos, 0, 0, 1);
|
|
}
|
|
|
|
KillItem(itemNumber);
|
|
}
|
|
}
|
|
}
|
|
|
|
void DartEmitterControl(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->active)
|
|
{
|
|
if (item->timer > 0)
|
|
{
|
|
item->timer--;
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
item->timer = 24;
|
|
}
|
|
}
|
|
|
|
short dartItemNumber = CreateItem();
|
|
|
|
if (dartItemNumber != NO_ITEM)
|
|
{
|
|
ITEM_INFO* dartItem = &Items[dartItemNumber];
|
|
|
|
dartItem->objectNumber = ID_DARTS;
|
|
dartItem->roomNumber = item->roomNumber;
|
|
|
|
int x = 0;
|
|
int z = 0;
|
|
|
|
if (item->pos.yRot > 0)
|
|
{
|
|
if (item->pos.yRot == ANGLE(90))
|
|
x = 512;
|
|
}
|
|
else if (item->pos.yRot < 0)
|
|
{
|
|
if (item->pos.yRot == -ANGLE(180))
|
|
{
|
|
z = -512;
|
|
}
|
|
else if (item->pos.yRot == -ANGLE(90))
|
|
{
|
|
x = -512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
z = 512;
|
|
}
|
|
|
|
dartItem->pos.xPos = x + item->pos.xPos;
|
|
dartItem->pos.yPos = item->pos.yPos - 512;
|
|
dartItem->pos.zPos = z + item->pos.zPos;
|
|
|
|
InitialiseItem(dartItemNumber);
|
|
|
|
dartItem->pos.xRot = 0;
|
|
dartItem->pos.yRot = item->pos.yRot + -ANGLE(180);
|
|
dartItem->speed = 256;
|
|
|
|
int xf = 0;
|
|
int zf = 0;
|
|
|
|
if (x)
|
|
xf = abs(2 * x) - 1;
|
|
else
|
|
zf = abs(2 * z) - 1;
|
|
|
|
for (int i = 0; i < 5; i++)
|
|
{
|
|
int random = -GetRandomControl();
|
|
|
|
int xv = 0;
|
|
int zv = 0;
|
|
|
|
if (z >= 0)
|
|
zv = zf & random;
|
|
else
|
|
zv = -(zf & random);
|
|
|
|
if (x >= 0)
|
|
xv = xf & random;
|
|
else
|
|
xv = -(xf & random);
|
|
|
|
TriggerDartSmoke(dartItem->pos.xPos, dartItem->pos.yPos, dartItem->pos.zPos, xv, zv, 0);
|
|
}
|
|
|
|
AddActiveItem(dartItemNumber);
|
|
dartItem->status = ITEM_ACTIVE;
|
|
SoundEffect(SFX_LIFT_DOORS, &dartItem->pos, 0);
|
|
}
|
|
}
|
|
|
|
void FallingCeilingControl(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->currentAnimState)
|
|
{
|
|
if (item->currentAnimState == 1 && item->touchBits)
|
|
{
|
|
LaraItem->hitPoints -= 300;
|
|
LaraItem->hitStatus = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->goalAnimState = 1;
|
|
item->gravityStatus = true;;
|
|
}
|
|
|
|
AnimateItem(item);
|
|
|
|
if (item->status == ITEM_DEACTIVATED)
|
|
{
|
|
RemoveActiveItem(itemNumber);
|
|
}
|
|
else
|
|
{
|
|
short roomNumber = item->roomNumber;
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
item->floor = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
|
|
if (roomNumber != item->roomNumber)
|
|
ItemNewRoom(itemNumber, roomNumber);
|
|
|
|
if (item->currentAnimState == 1)
|
|
{
|
|
if (item->pos.yPos >= item->floor)
|
|
{
|
|
item->pos.yPos = item->floor;
|
|
item->gravityStatus = false;
|
|
item->goalAnimState = 2;
|
|
item->fallspeed = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void RollingBallCollision(short itemNumber, ITEM_INFO* l, COLL_INFO* coll)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (TestBoundsCollide(item, l, coll->radius))
|
|
{
|
|
if (TestCollision(item, l))
|
|
{
|
|
if (TriggerActive(item) && (item->itemFlags[0] || item->fallspeed))
|
|
{
|
|
LaraItem->animNumber = ANIMATION_LARA_SQUASH_BOULDER;
|
|
LaraItem->frameNumber = Anims[LaraItem->animNumber].frameBase;
|
|
LaraItem->goalAnimState = STATE_LARA_DEATH;
|
|
LaraItem->currentAnimState = STATE_LARA_DEATH;
|
|
LaraItem->gravityStatus = false;
|
|
}
|
|
else
|
|
{
|
|
ObjectCollision(itemNumber, l, coll);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void RollingBallControl(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (!TriggerActive(item))
|
|
return;
|
|
|
|
item->fallspeed += GRAVITY;
|
|
|
|
item->pos.xPos += item->itemFlags[0] >> 5;
|
|
item->pos.yPos += item->fallspeed;
|
|
item->pos.zPos += item->itemFlags[1] >> 5;
|
|
|
|
short roomNumber = item->roomNumber;
|
|
FLOOR_INFO* floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
int height = GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
int dh = height - 512;
|
|
|
|
if (item->pos.yPos > height - 512)
|
|
{
|
|
if (abs(item->fallspeed) > 16)
|
|
{
|
|
int distance = SQRT_ASM(
|
|
SQUARE(Camera.pos.x - item->pos.xPos) +
|
|
SQUARE(Camera.pos.y - item->pos.yPos) +
|
|
SQUARE(Camera.pos.z - item->pos.zPos));
|
|
|
|
if (distance < 16384)
|
|
Camera.bounce = -((16384 - distance) * abs(item->fallspeed) >> 14);
|
|
}
|
|
|
|
if (item->pos.yPos - dh < 512)
|
|
item->pos.yPos = dh;
|
|
|
|
if (item->fallspeed <= 64)
|
|
{
|
|
if (abs(item->speed) <= 512 || GetRandomControl() & 0x1F)
|
|
item->fallspeed = 0;
|
|
else
|
|
item->fallspeed = -(short)(GetRandomControl() % (item->speed >> 3));
|
|
}
|
|
else
|
|
{
|
|
item->fallspeed = -(short)(item->fallspeed >> 2);
|
|
}
|
|
}
|
|
|
|
int x = item->pos.xPos;
|
|
int y = item->pos.yPos;
|
|
int z = item->pos.zPos;
|
|
|
|
floor = GetFloor(x, y, z + 128, &roomNumber);
|
|
int y1a = GetFloorHeight(floor, x, y, z + 128) - 512;
|
|
|
|
floor = GetFloor(x, y, z - 128, &roomNumber);
|
|
int y2a = GetFloorHeight(floor, x, y, z - 128) - 512;
|
|
|
|
floor = GetFloor(x + 128, y, z, &roomNumber);
|
|
int y3a = GetFloorHeight(floor, x + 128, y, z) - 512;
|
|
|
|
floor = GetFloor(x - 128, y, z, &roomNumber);
|
|
int y4a = GetFloorHeight(floor, x - 128, y, z) - 512;
|
|
|
|
floor = GetFloor(x, y, z + 512, &roomNumber);
|
|
int y1b = GetFloorHeight(floor, x, y, z + 512) - 512;
|
|
|
|
floor = GetFloor(x, y, z - 512, &roomNumber);
|
|
int y2b = GetFloorHeight(floor, x, y, z - 512) - 512;
|
|
|
|
floor = GetFloor(x + 512, y, z, &roomNumber);
|
|
int y3b = GetFloorHeight(floor, x + 512, y, z) - 512;
|
|
|
|
floor = GetFloor(x - 512, y, z, &roomNumber);
|
|
int y4b = GetFloorHeight(floor, x - 512, y, z) - 512;
|
|
|
|
if (item->pos.yPos - dh > -256
|
|
|| item->pos.yPos - y1b >= 512
|
|
|| item->pos.yPos - y3b >= 512
|
|
|| item->pos.yPos - y2b >= 512
|
|
|| item->pos.yPos - y4b >= 512)
|
|
{
|
|
int counterZ = 0;
|
|
|
|
if (y1a - dh <= 256)
|
|
{
|
|
if (y1b - dh < -1024 || y1a - dh < -256)
|
|
{
|
|
if (item->itemFlags[1] <= 0)
|
|
{
|
|
if (!item->itemFlags[1] && item->itemFlags[0])
|
|
{
|
|
item->pos.zPos = (item->pos.zPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[1] = -item->itemFlags[1] >> 1;
|
|
item->pos.zPos = (item->pos.zPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else if (y1a == dh)
|
|
{
|
|
counterZ = 1;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[1] += (y1a - dh) >> 1;
|
|
}
|
|
}
|
|
|
|
if (y2a - dh <= 256)
|
|
{
|
|
if (y2b - dh < -1024 || y2a - dh < -256)
|
|
{
|
|
if (item->itemFlags[1] >= 0)
|
|
{
|
|
if (!item->itemFlags[1] && item->itemFlags[0])
|
|
{
|
|
item->pos.zPos = (item->pos.zPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[1] = -item->itemFlags[1] >> 1;
|
|
item->pos.zPos = (item->pos.zPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else if (y2a == dh)
|
|
{
|
|
counterZ++;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[1] -= (y2a - dh) >> 1;
|
|
}
|
|
}
|
|
|
|
if (counterZ == 2)
|
|
{
|
|
if (abs(item->itemFlags[1]) <= 64)
|
|
item->itemFlags[1] = 0;
|
|
else
|
|
item->itemFlags[1] = item->itemFlags[1] - (item->itemFlags[1] >> 6);
|
|
}
|
|
|
|
int counterX = 0;
|
|
|
|
if (y4a - dh <= 256)
|
|
{
|
|
if (y4b - dh < -1024 || y4a - dh < -256)
|
|
{
|
|
if (item->itemFlags[0] >= 0)
|
|
{
|
|
if (!item->itemFlags[0] && item->itemFlags[1])
|
|
{
|
|
item->pos.xPos = (item->pos.xPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] = -item->itemFlags[0] >> 1;
|
|
item->pos.xPos = (item->pos.xPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else if (y4a == dh)
|
|
{
|
|
counterX = 1;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] -= (y4a - dh) >> 1;
|
|
}
|
|
}
|
|
|
|
if (y3a - dh <= 256)
|
|
{
|
|
if (y3b - dh < -1024 || y3a - dh < -256)
|
|
{
|
|
if (item->itemFlags[0] <= 0)
|
|
{
|
|
if (!item->itemFlags[0] && item->itemFlags[1])
|
|
{
|
|
item->pos.xPos = (item->pos.xPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] = -item->itemFlags[0] >> 1;
|
|
item->pos.xPos = (item->pos.xPos & 0xFFFFFE00) + 512;
|
|
}
|
|
}
|
|
else if (y3a == dh)
|
|
{
|
|
counterX++;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] += (y3a - dh) >> 1;
|
|
}
|
|
}
|
|
|
|
if (counterX == 2)
|
|
{
|
|
if (abs(item->itemFlags[0]) <= 64)
|
|
item->itemFlags[0] = 0;
|
|
else
|
|
item->itemFlags[0] = item->itemFlags[0] - (item->itemFlags[0] >> 6);
|
|
}
|
|
}
|
|
|
|
GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
|
|
if (item->roomNumber != roomNumber)
|
|
ItemNewRoom(itemNumber, roomNumber);
|
|
|
|
if (item->itemFlags[0] <= 3072)
|
|
{
|
|
if (item->itemFlags[0] < -3072)
|
|
item->itemFlags[0] = -3072;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[0] = 3072;
|
|
}
|
|
|
|
if (item->itemFlags[1] <= 3072)
|
|
{
|
|
if (item->itemFlags[1] < -3072)
|
|
item->itemFlags[1] = -3072;
|
|
}
|
|
else
|
|
{
|
|
item->itemFlags[1] = 3072;
|
|
}
|
|
|
|
short angle = 0;
|
|
|
|
if (item->itemFlags[1] || item->itemFlags[0])
|
|
angle = ATAN(item->itemFlags[1], item->itemFlags[0]);
|
|
else
|
|
angle = item->pos.yRot;
|
|
|
|
if (item->pos.yRot != angle)
|
|
{
|
|
if (((angle - item->pos.yRot) & 0x7FFFu) >= 0x200)
|
|
{
|
|
if (angle <= item->pos.yRot || angle - item->pos.yRot >= 0x8000)
|
|
item->pos.yRot -= 512;
|
|
else
|
|
item->pos.yRot += 512;
|
|
}
|
|
else
|
|
{
|
|
item->pos.yRot = angle;
|
|
}
|
|
}
|
|
|
|
item->pos.xRot -= (abs(item->itemFlags[0]) + abs(item->itemFlags[1])) >> 1;
|
|
|
|
roomNumber = item->roomNumber;
|
|
floor = GetFloor(item->pos.xPos, item->pos.yPos, item->pos.zPos, &roomNumber);
|
|
GetFloorHeight(floor, item->pos.xPos, item->pos.yPos, item->pos.zPos);
|
|
TestTriggers(TriggerIndex, 1, 0);
|
|
} |