mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-12 21:47:03 +03:00
359 lines
No EOL
7.9 KiB
C++
359 lines
No EOL
7.9 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"
|
|
|
|
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;
|
|
}
|
|
}
|
|
}
|
|
} |