mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-03 18:27:59 +03:00
295 lines
6.4 KiB
C++
295 lines
6.4 KiB
C++
![]() |
#include "framework.h"
|
||
|
#include "tr5_rollingball.h"
|
||
|
#include "sphere.h"
|
||
|
#include "camera.h"
|
||
|
#include "control.h"
|
||
|
#include "lara.h"
|
||
|
#include "setup.h"
|
||
|
|
||
|
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(
|
||
|
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 & -512) + 512;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
item->itemFlags[1] = -item->itemFlags[1] >> 1;
|
||
|
item->pos.zPos = (item->pos.zPos & -512) + 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 & -512) + 512;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
item->itemFlags[1] = -item->itemFlags[1] >> 1;
|
||
|
item->pos.zPos = (item->pos.zPos & -512) + 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 & -512) + 512;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
item->itemFlags[0] = -item->itemFlags[0] >> 1;
|
||
|
item->pos.xPos = (item->pos.xPos & -512) + 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 & -512) + 512;
|
||
|
}
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
item->itemFlags[0] = -item->itemFlags[0] >> 1;
|
||
|
item->pos.xPos = (item->pos.xPos & -512) + 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 = phd_atan(item->itemFlags[1], item->itemFlags[0]);
|
||
|
else
|
||
|
angle = item->pos.yRot;
|
||
|
|
||
|
if (item->pos.yRot != angle)
|
||
|
{
|
||
|
if (((angle - item->pos.yRot) & 32767) >= 512)
|
||
|
{
|
||
|
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, TRUE, NULL);
|
||
|
}
|