mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-07 11:13:53 +03:00
773 lines
No EOL
16 KiB
C++
773 lines
No EOL
16 KiB
C++
#include "../oldobjects.h"
|
|
#include "../../Game/sphere.h"
|
|
#include "../../Game/items.h"
|
|
#include "../../Game/tomb4fx.h"
|
|
#include "../../Game/effect2.h"
|
|
#include "../../Game/Box.h"
|
|
#include "../../Game/people.h"
|
|
#include "../../Game/debris.h"
|
|
#include "../../Game/draw.h"
|
|
#include "../../Game/control.h"
|
|
#include "../../Game/effects.h"
|
|
#include "../../Specific/setup.h"
|
|
|
|
int NextBat;
|
|
BAT_STRUCT* Bats;
|
|
|
|
int NextSpider;
|
|
SPIDER_STRUCT* Spiders;
|
|
|
|
int NextRat;
|
|
RAT_STRUCT* Rats;
|
|
|
|
void InitialiseLittleBats(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->pos.yRot == 0)
|
|
{
|
|
item->pos.zPos += 512;
|
|
}
|
|
else if (item->pos.yRot == -ANGLE(180))
|
|
{
|
|
item->pos.zPos -= 512;
|
|
}
|
|
else if (item->pos.yRot == -ANGLE(90))
|
|
{
|
|
item->pos.xPos -= 512;
|
|
}
|
|
else if (item->pos.yRot == ANGLE(90))
|
|
{
|
|
item->pos.xPos += 512;
|
|
}
|
|
|
|
if (Objects[ID_BATS_EMITTER].loaded)
|
|
ZeroMemory(Bats, NUM_BATS * sizeof(BAT_STRUCT));
|
|
|
|
//LOWORD(item) = sub_402F27(ebx0, Bats, 0, 1920);
|
|
}
|
|
|
|
void ControlLittleBats(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (TriggerActive(item))
|
|
{
|
|
if (item->triggerFlags)
|
|
{
|
|
TriggerLittleBat(item);
|
|
item->triggerFlags--;
|
|
}
|
|
else
|
|
{
|
|
KillItem(itemNumber);
|
|
}
|
|
}
|
|
}
|
|
|
|
short GetNextBat()
|
|
{
|
|
short batNumber = NextBat;
|
|
int index = 0;
|
|
BAT_STRUCT* bat = &Bats[NextBat];
|
|
|
|
while (bat->on)
|
|
{
|
|
if (batNumber == NUM_BATS - 1)
|
|
{
|
|
bat = (BAT_STRUCT*)Bats;
|
|
batNumber = 0;
|
|
}
|
|
else
|
|
{
|
|
batNumber++;
|
|
bat++;
|
|
}
|
|
|
|
index++;
|
|
|
|
if (index >= NUM_BATS)
|
|
return NO_ITEM;
|
|
}
|
|
|
|
NextBat = (batNumber + 1) & (NUM_BATS - 1);
|
|
|
|
return batNumber;
|
|
}
|
|
|
|
void TriggerLittleBat(ITEM_INFO* item)
|
|
{
|
|
short batNumber = GetNextBat();
|
|
|
|
if (batNumber != NO_ITEM)
|
|
{
|
|
BAT_STRUCT* bat = &Bats[batNumber];
|
|
|
|
bat->roomNumber = item->roomNumber;
|
|
bat->pos.xPos = item->pos.xPos;
|
|
bat->pos.yPos = item->pos.yPos;
|
|
bat->pos.zPos = item->pos.zPos;
|
|
bat->pos.yRot = (GetRandomControl() & 0x7FF) + item->pos.yRot + -ANGLE(180) - 1024;
|
|
bat->on = 1;
|
|
bat->flags = 0;
|
|
bat->pos.xRot = (GetRandomControl() & 0x3FF) - 512;
|
|
bat->speed = (GetRandomControl() & 0x1F) + 16;
|
|
bat->laraTarget = GetRandomControl() & 0x1FF;
|
|
bat->counter = 20 * ((GetRandomControl() & 7) + 15);
|
|
}
|
|
}
|
|
|
|
short GetNextSpider()
|
|
{
|
|
short spiderNum = NextSpider;
|
|
int i = 0;
|
|
SPIDER_STRUCT* spider = &Spiders[NextSpider];
|
|
|
|
while (spider->on)
|
|
{
|
|
if (spiderNum == NUM_SPIDERS - 1)
|
|
{
|
|
spider = &Spiders[0];
|
|
spiderNum = 0;
|
|
}
|
|
else
|
|
{
|
|
++spiderNum;
|
|
++spider;
|
|
}
|
|
|
|
if (++i >= NUM_SPIDERS)
|
|
return -1;
|
|
}
|
|
|
|
NextSpider = (spiderNum + 1) & 0x3F;
|
|
|
|
return spiderNum;
|
|
}
|
|
|
|
void ClearSpiders()
|
|
{
|
|
if (Objects[ID_SPIDERS_EMITTER].loaded)
|
|
{
|
|
ZeroMemory(Spiders, NUM_SPIDERS * sizeof(SPIDER_STRUCT));
|
|
NextSpider = 0;
|
|
FlipEffect = -1;
|
|
}
|
|
}
|
|
|
|
void ClearSpidersPatch(ITEM_INFO* item)
|
|
{
|
|
ClearSpiders();
|
|
}
|
|
|
|
void InitialiseSpiders(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
short flags = item->triggerFlags / -24;
|
|
|
|
item->pos.xRot = ANGLE(45);
|
|
item->itemFlags[1] = flags & 2;
|
|
item->itemFlags[2] = flags & 4;
|
|
item->itemFlags[0] = flags & 1;
|
|
item->triggerFlags = flags % 1000;
|
|
|
|
if (flags & 1)
|
|
{
|
|
ClearSpiders();
|
|
return;
|
|
}
|
|
|
|
if (item->pos.yRot > -28672 && item->pos.yRot < -4096)
|
|
{
|
|
item->pos.xPos += 512;
|
|
}
|
|
else if(item->pos.yRot > 4096 && item->pos.yRot < 28672)
|
|
{
|
|
item->pos.xPos -= 512;
|
|
}
|
|
|
|
if (item->pos.yRot > -8192 && item->pos.yRot < 8192)
|
|
{
|
|
item->pos.zPos -= 512;
|
|
}
|
|
else if (item->pos.yRot < -20480 || item->pos.yRot > 20480)
|
|
{
|
|
item->pos.zPos += 512;
|
|
}
|
|
|
|
ClearSpiders();
|
|
}
|
|
|
|
void ControlSpiders(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->triggerFlags)
|
|
{
|
|
if (!item->itemFlags[2] || !(GetRandomControl() & 0xF))
|
|
{
|
|
item->triggerFlags--;
|
|
|
|
if (item->itemFlags[2] && GetRandomControl() & 1)
|
|
item->itemFlags[2]--;
|
|
|
|
short spiderNum = GetNextSpider();
|
|
if (spiderNum != -1)
|
|
{
|
|
SPIDER_STRUCT* spider = &Spiders[spiderNum];
|
|
|
|
spider->pos.xPos = item->pos.xPos;
|
|
spider->pos.yPos = item->pos.yPos;
|
|
spider->pos.zPos = item->pos.zPos;
|
|
spider->roomNumber = item->roomNumber;
|
|
|
|
if (item->itemFlags[0])
|
|
{
|
|
spider->pos.yRot = 2 * GetRandomControl();
|
|
spider->fallspeed = -16 - (GetRandomControl() & 0x1F);
|
|
}
|
|
else
|
|
{
|
|
spider->fallspeed = 0;
|
|
spider->pos.yRot = item->pos.yRot + (GetRandomControl() & 0x3FFF) - ANGLE(45);
|
|
}
|
|
|
|
spider->pos.xRot = 0;
|
|
spider->pos.zRot = 0;
|
|
spider->on = true;
|
|
spider->flags = 0;
|
|
spider->speed = (GetRandomControl() & 0x1F) + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
short GetNextRat()
|
|
{
|
|
short ratNum = NextRat;
|
|
int i = 0;
|
|
RAT_STRUCT* rat = &Rats[NextRat];
|
|
|
|
while (rat->on)
|
|
{
|
|
if (ratNum == NUM_RATS - 1)
|
|
{
|
|
rat = &Rats[0];
|
|
ratNum = 0;
|
|
}
|
|
else
|
|
{
|
|
ratNum++;
|
|
rat++;
|
|
}
|
|
|
|
i++;
|
|
|
|
if (i >= NUM_RATS)
|
|
return NO_ITEM;
|
|
}
|
|
|
|
NextRat = (ratNum + 1) & 0x1F;
|
|
return ratNum;
|
|
}
|
|
|
|
void ControlLittleRats(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
if (item->triggerFlags)
|
|
{
|
|
if (!item->itemFlags[2] || !(GetRandomControl() & 0xF))
|
|
{
|
|
item->triggerFlags--;
|
|
|
|
if (item->itemFlags[2] && GetRandomControl() & 1)
|
|
item->itemFlags[2]--;
|
|
|
|
short ratNum = GetNextRat();
|
|
if (ratNum != -1)
|
|
{
|
|
RAT_STRUCT* rat = &Rats[ratNum];
|
|
|
|
rat->pos.xPos = item->pos.xPos;
|
|
rat->pos.yPos = item->pos.yPos;
|
|
rat->pos.zPos = item->pos.zPos;
|
|
rat->roomNumber = item->roomNumber;
|
|
|
|
if (item->itemFlags[0])
|
|
{
|
|
rat->pos.yRot = 2 * GetRandomControl();
|
|
rat->fallspeed = -16 - (GetRandomControl() & 31);
|
|
}
|
|
else
|
|
{
|
|
rat->fallspeed = 0;
|
|
rat->pos.yRot = item->pos.yRot + (GetRandomControl() & 0x3FFF) - ANGLE(45);
|
|
}
|
|
|
|
rat->pos.xRot = 0;
|
|
rat->pos.zRot = 0;
|
|
rat->on = 1;
|
|
rat->flags = GetRandomControl() & 30;
|
|
rat->speed = (GetRandomControl() & 31) + 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void ClearRats()
|
|
{
|
|
if (Objects[ID_RATS_EMITTER].loaded)
|
|
{
|
|
ZeroMemory(Rats, NUM_RATS * sizeof(RAT_STRUCT));
|
|
NextRat = 0;
|
|
FlipEffect = -1;
|
|
}
|
|
}
|
|
|
|
void InitialiseLittleRats(short itemNumber)
|
|
{
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
|
|
char flags = item->triggerFlags / 1000;
|
|
|
|
item->pos.xRot = ANGLE(45);
|
|
item->itemFlags[1] = flags & 2;
|
|
item->itemFlags[2] = flags & 4;
|
|
item->itemFlags[0] = flags & 1;
|
|
item->triggerFlags = item->triggerFlags % 1000;
|
|
|
|
if (flags & 1)
|
|
{
|
|
ClearRats();
|
|
return;
|
|
}
|
|
|
|
if (item->pos.yRot > -28672 && item->pos.yRot < -4096)
|
|
{
|
|
item->pos.xPos += 512;
|
|
}
|
|
else if (item->pos.yRot > 4096 && item->pos.yRot < 28672)
|
|
{
|
|
item->pos.xPos -= 512;
|
|
}
|
|
|
|
if (item->pos.yRot > -8192 && item->pos.yRot < 8192)
|
|
{
|
|
item->pos.zPos -= 512;
|
|
}
|
|
else if (item->pos.yRot < -20480 || item->pos.yRot > 20480)
|
|
{
|
|
item->pos.zPos += 512;
|
|
}
|
|
|
|
ClearRats();
|
|
}
|
|
|
|
void UpdateBats()
|
|
{
|
|
if (!Objects[ID_BATS_EMITTER].loaded)
|
|
return;
|
|
|
|
short* bounds = GetBoundsAccurate(LaraItem);
|
|
|
|
int x1 = LaraItem->pos.xPos + bounds[0] - (bounds[0] >> 2);
|
|
int x2 = LaraItem->pos.xPos + bounds[1] - (bounds[1] >> 2);
|
|
|
|
int y1 = LaraItem->pos.yPos + bounds[2] - (bounds[2] >> 2);
|
|
int y2 = LaraItem->pos.yPos + bounds[3] - (bounds[3] >> 2);
|
|
|
|
int z1 = LaraItem->pos.zPos + bounds[4] - (bounds[4] >> 2);
|
|
int z2 = LaraItem->pos.zPos + bounds[5] - (bounds[5] >> 2);
|
|
|
|
int minDistance = 0xFFFFFFF;
|
|
int minIndex = -1;
|
|
|
|
for (int i = 0; i < NUM_BATS; i++)
|
|
{
|
|
BAT_STRUCT* bat = &Bats[i];
|
|
|
|
if (!bat->on)
|
|
continue;
|
|
|
|
if ((Lara.burn || LaraItem->hitPoints <= 0)
|
|
&& bat->counter > 90
|
|
&& !(GetRandomControl() & 7))
|
|
bat->counter = 90;
|
|
|
|
if (!(--bat->counter))
|
|
{
|
|
bat->on = 0;
|
|
continue;
|
|
}
|
|
|
|
if (!(GetRandomControl() & 7))
|
|
{
|
|
bat->laraTarget = GetRandomControl() % 640 + 128;
|
|
bat->xTarget = (GetRandomControl() & 0x7F) - 64;
|
|
bat->zTarget = (GetRandomControl() & 0x7F) - 64;
|
|
}
|
|
|
|
short angles[2];
|
|
phd_GetVectorAngles(
|
|
LaraItem->pos.xPos + 8 * bat->xTarget - bat->pos.xPos,
|
|
LaraItem->pos.yPos - bat->laraTarget - bat->pos.yPos,
|
|
LaraItem->pos.zPos + 8 * bat->zTarget - bat->pos.zPos,
|
|
angles);
|
|
|
|
int distance = SQUARE(LaraItem->pos.zPos - bat->pos.zPos) +
|
|
SQUARE(LaraItem->pos.xPos - bat->pos.xPos);
|
|
if (distance < minDistance)
|
|
{
|
|
minDistance = distance;
|
|
minIndex = i;
|
|
}
|
|
|
|
distance = SQRT_ASM(distance) >> 3;
|
|
if (distance < 48)
|
|
distance = 48;
|
|
else if (distance > 128)
|
|
distance = 128;
|
|
|
|
if (bat->speed < distance)
|
|
bat->speed++;
|
|
else if (bat->speed > distance)
|
|
bat->speed--;
|
|
|
|
if (bat->counter > 90)
|
|
{
|
|
short speed = bat->speed << 7;
|
|
|
|
short xAngle = abs(angles[1] - bat->pos.xRot) >> 3;
|
|
short yAngle = abs(angles[0] - bat->pos.yRot) >> 3;
|
|
|
|
if (xAngle < -speed)
|
|
xAngle = -speed;
|
|
else if (xAngle > speed)
|
|
xAngle = speed;
|
|
|
|
if (yAngle < -speed)
|
|
yAngle = -speed;
|
|
else if (yAngle > speed)
|
|
yAngle = speed;
|
|
|
|
bat->pos.yRot += yAngle;
|
|
bat->pos.xRot += xAngle;
|
|
}
|
|
|
|
int sp = bat->speed * COS(bat->pos.xRot) >> W2V_SHIFT;
|
|
|
|
bat->pos.xPos += sp * SIN(bat->pos.yRot) >> W2V_SHIFT;
|
|
bat->pos.yPos += bat->speed * SIN(-bat->pos.xRot) >> W2V_SHIFT;
|
|
bat->pos.zPos += sp * COS(bat->pos.yRot) >> W2V_SHIFT;
|
|
|
|
if ((i % 2 == 0)
|
|
&& bat->pos.xPos > x1
|
|
&& bat->pos.xPos < x2
|
|
&& bat->pos.yPos > y1
|
|
&& bat->pos.yPos < y2
|
|
&& bat->pos.zPos > z1
|
|
&& bat->pos.zPos < z2)
|
|
{
|
|
TriggerBlood(bat->pos.xPos, bat->pos.yPos, bat->pos.zPos, 2 * GetRandomControl(), 2);
|
|
if (LaraItem->hitPoints > 0)
|
|
LaraItem->hitPoints -= 2;
|
|
}
|
|
}
|
|
|
|
if (minIndex != -1)
|
|
{
|
|
BAT_STRUCT* bat = &Bats[minIndex];
|
|
if (!(GetRandomControl() & 4))
|
|
SoundEffect(SFX_BATS_1, &bat->pos, 0);
|
|
}
|
|
}
|
|
|
|
|
|
void UpdateRats()
|
|
{
|
|
if (Objects[ID_RATS_EMITTER].loaded)
|
|
{
|
|
for (int i = 0; i < NUM_RATS; i++)
|
|
{
|
|
RAT_STRUCT* rat = &Rats[i];
|
|
|
|
if (rat->on)
|
|
{
|
|
int oldX = rat->pos.xPos;
|
|
int oldY = rat->pos.yPos;
|
|
int oldZ = rat->pos.zPos;
|
|
|
|
rat->pos.xPos += rat->speed * SIN(rat->pos.yRot) >> W2V_SHIFT;
|
|
rat->pos.yPos += rat->fallspeed;
|
|
rat->pos.zPos += rat->speed * COS(rat->pos.yRot) >> W2V_SHIFT;
|
|
|
|
rat->fallspeed += GRAVITY;
|
|
|
|
int dx = LaraItem->pos.xPos - rat->pos.xPos;
|
|
int dy = LaraItem->pos.yPos - rat->pos.yPos;
|
|
int dz = LaraItem->pos.zPos - rat->pos.zPos;
|
|
|
|
short angle;
|
|
if (rat->flags >= 170)
|
|
angle = rat->pos.yRot - (short)ATAN(dz, dx);
|
|
else
|
|
angle = (short)ATAN(dz, dx) - rat->pos.yRot;
|
|
|
|
if (abs(dx) < 85 && abs(dy) < 85 && abs(dz) < 85)
|
|
{
|
|
LaraItem->hitPoints--;
|
|
LaraItem->hitStatus = true;
|
|
}
|
|
|
|
// if life is even
|
|
if (rat->flags & 1)
|
|
{
|
|
// if rat is very near
|
|
if (abs(dz) + abs(dx) <= 1024)
|
|
{
|
|
if (rat->speed & 1)
|
|
rat->pos.yRot += 512;
|
|
else
|
|
rat->pos.yRot -= 512;
|
|
rat->speed = 48 - (abs(angle) >> 10);
|
|
}
|
|
else
|
|
{
|
|
if (rat->speed < (i & 31) + 24)
|
|
rat->speed++;
|
|
|
|
if (abs(angle) >= 2048)
|
|
{
|
|
if (angle >= 0)
|
|
rat->pos.yRot += 1024;
|
|
else
|
|
rat->pos.yRot -= 1024;
|
|
}
|
|
else
|
|
{
|
|
rat->pos.yRot += 8 * (Wibble - i);
|
|
}
|
|
}
|
|
}
|
|
|
|
__int16 oldRoomNumber = rat->roomNumber;
|
|
|
|
FLOOR_INFO* floor = GetFloor(rat->pos.xPos, rat->pos.yPos, rat->pos.zPos, &rat->roomNumber);
|
|
int height = GetFloorHeight(floor, rat->pos.xPos, rat->pos.yPos, rat->pos.zPos);
|
|
|
|
// if height is higher than 5 clicks
|
|
if (height < rat->pos.yPos - 1280 ||
|
|
height == NO_HEIGHT)
|
|
{
|
|
// if timer is higher than 170 time to disappear
|
|
if (rat->flags > 170)
|
|
{
|
|
rat->on = 0;
|
|
NextRat = 0;
|
|
}
|
|
|
|
if (angle <= 0)
|
|
rat->pos.yRot -= ANGLE(90);
|
|
else
|
|
rat->pos.yRot += ANGLE(90);
|
|
|
|
// reset rat to old position and disable fall
|
|
rat->pos.xPos = oldX;
|
|
rat->pos.yPos = oldY;
|
|
rat->pos.zPos = oldZ;
|
|
rat->fallspeed = 0;
|
|
}
|
|
else
|
|
{
|
|
// if height is lower than Y + 64
|
|
if (height >= rat->pos.yPos - 64)
|
|
{
|
|
// if rat is higher than floor
|
|
if (height >= rat->pos.yPos)
|
|
{
|
|
// if fallspeed is too much or life is ended then kill rat
|
|
if (rat->fallspeed >= 500 ||
|
|
rat->flags >= 200)
|
|
{
|
|
rat->on = 0;
|
|
NextRat = 0;
|
|
}
|
|
else
|
|
{
|
|
rat->pos.xRot = -128 * rat->fallspeed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
rat->pos.yPos = height;
|
|
rat->fallspeed = 0;
|
|
rat->flags |= 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// if block is higher than rat position then run vertically
|
|
rat->pos.xRot = 14336;
|
|
rat->pos.xPos = oldX;
|
|
rat->pos.yPos = oldY - 24;
|
|
rat->pos.zPos = oldZ;
|
|
rat->fallspeed = 0;
|
|
}
|
|
}
|
|
|
|
if (!(Wibble & 60))
|
|
rat->flags += 2;
|
|
|
|
ROOM_INFO* r = &Rooms[rat->roomNumber];
|
|
if (r->flags & ENV_FLAG_WATER)
|
|
{
|
|
rat->fallspeed = 0;
|
|
rat->speed = 16;
|
|
rat->pos.yPos = r->maxceiling + 50;
|
|
|
|
if (Rooms[oldRoomNumber].flags & ENV_FLAG_WATER)
|
|
{
|
|
if (!(GetRandomControl() & 0xF))
|
|
{
|
|
SetupRipple(rat->pos.xPos, r->maxceiling, rat->pos.zPos, (GetRandomControl() & 3) + 48, 2);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
AddWaterSparks(rat->pos.xPos, r->maxceiling, rat->pos.zPos, 16);
|
|
SetupRipple(rat->pos.xPos, r->maxceiling, rat->pos.zPos, (GetRandomControl() & 3) + 48, 2);
|
|
SoundEffect(SFX_RATSPLASH, &rat->pos, 0);
|
|
}
|
|
}
|
|
|
|
if (!i && !(GetRandomControl() & 4))
|
|
SoundEffect(SFX_RATS_1, &rat->pos, 0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateSpiders()
|
|
{
|
|
if (Objects[ID_SPIDERS_EMITTER].loaded)
|
|
{
|
|
for (int i = 0; i < NUM_SPIDERS; i++)
|
|
{
|
|
SPIDER_STRUCT* spider = &Spiders[i];
|
|
if (spider->on)
|
|
{
|
|
int x = spider->pos.xPos;
|
|
int y = spider->pos.yPos;
|
|
int z = spider->pos.zPos;
|
|
|
|
spider->pos.xPos += spider->speed * SIN(spider->pos.yRot) >> W2V_SHIFT;
|
|
spider->pos.yPos += spider->fallspeed;
|
|
spider->pos.zPos += spider->speed * COS(spider->pos.yRot) >> W2V_SHIFT;
|
|
spider->fallspeed += GRAVITY;
|
|
|
|
int dx = LaraItem->pos.xPos - spider->pos.xPos;
|
|
int dy = LaraItem->pos.yPos - spider->pos.yPos;
|
|
int dz = LaraItem->pos.zPos - spider->pos.zPos;
|
|
|
|
short angle = ATAN(dz, dx) - spider->pos.yRot;
|
|
|
|
if (abs(dx) < 85 && abs(dy) < 85 && abs(dz) < 85)
|
|
{
|
|
LaraItem->hitPoints -= 3;
|
|
LaraItem->hitStatus = true;
|
|
TriggerBlood(spider->pos.xPos, spider->pos.yPos, spider->pos.zPos, spider->pos.yRot, 1);
|
|
}
|
|
|
|
if (spider->flags)
|
|
{
|
|
if (abs(dx) + abs(dz) <= 768)
|
|
{
|
|
if (spider->speed & 1)
|
|
spider->pos.yRot += 512;
|
|
else
|
|
spider->pos.yRot -= 512;
|
|
spider->speed = 48 - (abs(angle) >> 10);
|
|
}
|
|
else
|
|
{
|
|
if (spider->speed < (i & 0x1F) + 24)
|
|
spider->speed++;
|
|
|
|
if (abs(angle) >= 2048)
|
|
{
|
|
if (angle >= 0)
|
|
spider->pos.yRot += 1024;
|
|
else
|
|
spider->pos.yRot -= 1024;
|
|
}
|
|
else
|
|
{
|
|
spider->pos.yRot += 8 * (Wibble - i);
|
|
}
|
|
}
|
|
}
|
|
|
|
FLOOR_INFO* floor = GetFloor(spider->pos.xPos, spider->pos.yPos, spider->pos.zPos, &spider->roomNumber);
|
|
int height = GetFloorHeight(floor, spider->pos.xPos, spider->pos.yPos, spider->pos.zPos);
|
|
|
|
if (height >= spider->pos.yPos - 1280 || height == -32512)
|
|
{
|
|
if (height >= spider->pos.yPos - 64)
|
|
{
|
|
if (spider->pos.yPos <= height)
|
|
{
|
|
if (spider->fallspeed >= 500)
|
|
{
|
|
spider->on = false;
|
|
NextSpider = 0;
|
|
}
|
|
else
|
|
{
|
|
spider->pos.xRot = -128 * spider->fallspeed;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
spider->pos.yPos = height;
|
|
spider->fallspeed = 0;
|
|
spider->flags = 1;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
spider->pos.xRot = 14336;
|
|
spider->pos.xPos = x;
|
|
spider->pos.yPos = y - 8;
|
|
spider->pos.zPos = z;
|
|
spider->fallspeed = 0;
|
|
if (!(GetRandomControl() & 0x1F))
|
|
spider->pos.yRot += -ANGLE(180);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (angle <= 0)
|
|
spider->pos.yRot -= ANGLE(90);
|
|
else
|
|
spider->pos.yRot += ANGLE(90);
|
|
spider->pos.xPos = x;
|
|
spider->pos.yPos = y;
|
|
spider->pos.zPos = z;
|
|
spider->fallspeed = 0;
|
|
}
|
|
|
|
if (spider->pos.yPos < Rooms[spider->roomNumber].maxceiling + 50)
|
|
{
|
|
spider->fallspeed = 1;
|
|
spider->pos.yRot += -32768;
|
|
spider->pos.yPos = Rooms[spider->roomNumber].maxceiling + 50;
|
|
}
|
|
|
|
if (!i && !(GetRandomControl() & 4))
|
|
SoundEffect(SFX_BEETLES, &spider->pos, 0);
|
|
}
|
|
}
|
|
}
|
|
} |