mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-30 08:47:58 +03:00

- deleted all the __cdecl except for the #define function. because /Gd enable the __cdecl for function by default. - added the commented code in FireWeapon for TR3 entity (some function is missing)
489 lines
13 KiB
C++
489 lines
13 KiB
C++
#include "newobjects.h"
|
|
#include "..\Global\global.h"
|
|
#include "..\Game\Box.h"
|
|
#include "..\Game\items.h"
|
|
#include "..\Game\lot.h"
|
|
#include "..\Game\control.h"
|
|
#include "..\Game\effects.h"
|
|
#include "..\Game\draw.h"
|
|
#include "..\Game\sphere.h"
|
|
#include "..\Game\effect2.h"
|
|
#include "..\Game\people.h"
|
|
#include "..\Game\Lara.h"
|
|
|
|
#define PIRAHNA_DAMAGE 4
|
|
#define X 0
|
|
#define Y 1
|
|
#define Z 2
|
|
#define XYZ 3
|
|
#define MAX_FISH 8
|
|
#define OCB_FISH_LETAL 0x1000
|
|
#define OCB_FISH_EAT_CARCASS 0x2000
|
|
|
|
FISH_LEADER_INFO LeaderInfo[MAX_FISH];
|
|
FISH_INFO Fishes[MAX_FISH + (MAX_FISH * 24)];
|
|
|
|
byte FishRanges[1][3] = {
|
|
{ 2 << 2, 5 << 2, 3 }
|
|
};
|
|
|
|
int PirahnaHitWait = false;
|
|
int CarcassItem = NO_ITEM;
|
|
|
|
/*uchar temple_fish_ranges[3][3] = {
|
|
{ 1 << 2,1 << 2,2 },
|
|
{ 1 << 2,4 << 2,2 },
|
|
{ 1 << 2,7 << 2,4 },
|
|
};
|
|
|
|
uchar quadchase_fish_ranges[8][3] = {
|
|
{ 1 << 2,3 << 2,1 },
|
|
{ 0 << 2,3 << 2,2 },
|
|
{ 2 << 2,1 << 2,2 },
|
|
{ 1 << 2,2 << 2,1 },
|
|
{ 1 << 2,4 << 2,2 },
|
|
{ 1 << 2,6 << 2,1 },
|
|
{ 3 << 2,1 << 2,1 },
|
|
{ 4 << 2,1 << 2,1 },
|
|
};
|
|
|
|
uchar house_fish_ranges[7][3] = {
|
|
{ 1 << 2,1 << 2,1 }, // Unused.
|
|
{ 4 << 2,2 << 2,2 },
|
|
{ 6 << 2,2 << 2,2 },
|
|
{ 2 << 2,4 << 2,2 },
|
|
{ 2 << 2,3 << 2,1 },
|
|
{ 5 << 2,2 << 2,2 },
|
|
{ 4 << 2,2 << 2,1 },
|
|
};
|
|
|
|
uchar shore_fish_ranges[3][3] = {
|
|
{ 3 << 2,3 << 2,6 },
|
|
{ 3 << 2,5 << 2,6 },
|
|
{ 5 << 2,1 << 2,8 },
|
|
};
|
|
|
|
uchar crash_fish_ranges[1][3] = {
|
|
{ 5 << 2,1 << 2,6 },
|
|
};
|
|
|
|
uchar rapids_fish_ranges[2][3] = {
|
|
{ 4 << 2,4 << 2,8 },
|
|
{ 1 << 2,2 << 2,5 },
|
|
};*/
|
|
|
|
void SetupShoal(int shoalNumber)
|
|
{
|
|
//if (CurrentLevel == LV_JUNGLE)
|
|
//{
|
|
LeaderInfo[shoalNumber].xRange = (FishRanges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (FishRanges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (FishRanges[shoalNumber][2]) << 8;
|
|
//}
|
|
/*else if (CurrentLevel == LV_TEMPLE)
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = (temple_fish_ranges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (temple_fish_ranges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (temple_fish_ranges[shoalNumber][2]) << 8;
|
|
}
|
|
else if (CurrentLevel == LV_QUADBIKE)
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = (quadchase_fish_ranges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (quadchase_fish_ranges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (quadchase_fish_ranges[shoalNumber][2]) << 8;
|
|
}
|
|
else if (CurrentLevel == LV_GYM)
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = (house_fish_ranges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (house_fish_ranges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (house_fish_ranges[shoalNumber][2]) << 8;
|
|
}
|
|
else if (CurrentLevel == LV_SHORE)
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = (shore_fish_ranges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (shore_fish_ranges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (shore_fish_ranges[shoalNumber][2]) << 8;
|
|
}
|
|
else if (CurrentLevel == LV_CRASH)
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = (crash_fish_ranges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (crash_fish_ranges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (crash_fish_ranges[shoalNumber][2]) << 8;
|
|
}
|
|
else if (CurrentLevel == LV_RAPIDS)
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = (rapids_fish_ranges[shoalNumber][0] + 2) << 8;
|
|
LeaderInfo[shoalNumber].zRange = (rapids_fish_ranges[shoalNumber][1] + 2) << 8;
|
|
LeaderInfo[shoalNumber].yRange = (rapids_fish_ranges[shoalNumber][2]) << 8;
|
|
}
|
|
else
|
|
{
|
|
LeaderInfo[shoalNumber].xRange = 1 << 8;
|
|
LeaderInfo[shoalNumber].zRange = 1 << 8;
|
|
LeaderInfo[shoalNumber].yRange = 1 << 8;
|
|
}*/
|
|
}
|
|
|
|
|
|
void SetupFish(int leader, ITEM_INFO* item)
|
|
{
|
|
int fishXRange = LeaderInfo[leader].xRange;
|
|
int fishYRange = LeaderInfo[leader].yRange;
|
|
int fishZRange = LeaderInfo[leader].zRange;
|
|
|
|
Fishes[leader].x = 0;
|
|
Fishes[leader].y = 0;
|
|
Fishes[leader].z = 0;
|
|
Fishes[leader].angle = 0;
|
|
Fishes[leader].speed = (GetRandomControl() & 63) + 8;
|
|
Fishes[leader].swim = GetRandomControl() & 63;
|
|
|
|
for (int i = 0; i < 24; i++)
|
|
{
|
|
Fishes[MAX_FISH + (leader * 24) + i].x = (GetRandomControl() % (fishXRange << 1)) - fishXRange;
|
|
Fishes[MAX_FISH + (leader * 24) + i].y = (GetRandomControl() % fishYRange);
|
|
Fishes[MAX_FISH + (leader * 24) + i].destY = (GetRandomControl() % fishYRange);
|
|
Fishes[MAX_FISH + (leader * 24) + i].z = (GetRandomControl() % (fishZRange << 1)) - fishZRange;
|
|
|
|
Fishes[MAX_FISH + (leader * 24) + i].angle = GetRandomControl() & 4095;
|
|
Fishes[MAX_FISH + (leader * 24) + i].speed = (GetRandomControl() & 31) + 32;
|
|
Fishes[MAX_FISH + (leader * 24) + i].swim = GetRandomControl() & 63;
|
|
}
|
|
|
|
LeaderInfo[leader].on = 1;
|
|
LeaderInfo[leader].angle = 0;
|
|
LeaderInfo[leader].speed = (GetRandomControl() & 127) + 32;
|
|
LeaderInfo[leader].angleTime = 0;
|
|
LeaderInfo[leader].speedTime = 0;
|
|
}
|
|
|
|
void ControlFish(short itemNumber)
|
|
{
|
|
int pirahnaAttack = 0;
|
|
int angle = 0;
|
|
|
|
ITEM_INFO* item = &Items[itemNumber];
|
|
ITEM_INFO* enemy = item;
|
|
|
|
if (!TriggerActive(item))
|
|
return;
|
|
|
|
int leader = item->hitPoints;
|
|
if (!LeaderInfo[leader].on)
|
|
SetupFish(leader, item);
|
|
|
|
if (item->triggerFlags & OCB_FISH_LETAL)
|
|
{
|
|
if ((item->triggerFlags == OCB_FISH_EAT_CARCASS) == 0)
|
|
pirahnaAttack = (LaraItem->roomNumber == item->roomNumber);
|
|
else
|
|
{
|
|
if (CarcassItem != -1)
|
|
pirahnaAttack = 2;
|
|
else
|
|
pirahnaAttack = (LaraItem->roomNumber == item->roomNumber);
|
|
}
|
|
}
|
|
else
|
|
pirahnaAttack = 0;
|
|
|
|
if (PirahnaHitWait)
|
|
PirahnaHitWait--;
|
|
|
|
FISH_INFO* fish = (FISH_INFO*)&Fishes[leader];
|
|
|
|
if (pirahnaAttack)
|
|
{
|
|
if (pirahnaAttack == 1)
|
|
enemy = LaraItem;
|
|
else
|
|
enemy = &Items[CarcassItem];
|
|
|
|
LeaderInfo[leader].angle = fish->angle = (-(mGetAngle(fish->x + item->pos.xPos, fish->z + item->pos.zPos, enemy->pos.xPos, enemy->pos.zPos) + 0x4000) >> 4) & 4095;
|
|
LeaderInfo[leader].speed = (GetRandomControl() & 63) + 192;
|
|
}
|
|
|
|
int diff = fish->angle - LeaderInfo[leader].angle;
|
|
|
|
if (diff > 2048)
|
|
diff -= 4096;
|
|
else if (diff < -2048)
|
|
diff += 4096;
|
|
|
|
if (diff > 128)
|
|
{
|
|
fish->angAdd -= 4;
|
|
if (fish->angAdd < -120)
|
|
fish->angAdd = -120;
|
|
}
|
|
else if (diff < -128)
|
|
{
|
|
fish->angAdd += 4;
|
|
if (fish->angAdd > 120)
|
|
fish->angAdd = 120;
|
|
}
|
|
else
|
|
{
|
|
fish->angAdd -= fish->angAdd >> 2;
|
|
if (abs(fish->angAdd) < 4)
|
|
fish->angAdd = 0;
|
|
}
|
|
|
|
fish->angle += fish->angAdd;
|
|
|
|
if (diff > 1024)
|
|
fish->angle += fish->angAdd >> 2;
|
|
fish->angle &= 4095;
|
|
|
|
diff = fish->speed - LeaderInfo[leader].speed;
|
|
|
|
if (diff < -4)
|
|
{
|
|
diff = fish->speed + (GetRandomControl() & 3) + 1;
|
|
if (diff < 0)
|
|
diff = 0;
|
|
fish->speed = diff;
|
|
|
|
}
|
|
else if (diff > 4)
|
|
{
|
|
diff = fish->speed - (GetRandomControl() & 3) - 1;
|
|
if (diff > 255)
|
|
diff = 255;
|
|
fish->speed = diff;
|
|
}
|
|
|
|
fish->swim += fish->speed >> 4;
|
|
fish->swim &= 63;
|
|
|
|
int x = fish->x;
|
|
int z = fish->z;
|
|
|
|
x += -fish->speed * SIN(fish->angle << 4) >> W2V_SHIFT; // -(((rcossin_tbl[(fish->angle << 1)]) * (fish->speed)) >> 13);
|
|
z += fish->speed * COS(fish->angle << 4) >> W2V_SHIFT; // (((rcossin_tbl[(fish->angle << 1) + 1]) * (fish->speed)) >> 13);
|
|
|
|
if (pirahnaAttack == 0)
|
|
{
|
|
int fishXRange = LeaderInfo[leader].xRange;
|
|
int fishZRange = LeaderInfo[leader].zRange;
|
|
if (z < -fishZRange)
|
|
{
|
|
z = -fishZRange;
|
|
if (fish->angle < 2048)
|
|
LeaderInfo[leader].angle = fish->angle - ((GetRandomControl() & 127) + 128);
|
|
else
|
|
LeaderInfo[leader].angle = fish->angle + ((GetRandomControl() & 127) + 128);
|
|
LeaderInfo[leader].angleTime = (GetRandomControl() & 15) + 8;
|
|
LeaderInfo[leader].speedTime = 0;
|
|
}
|
|
else if (z > fishZRange)
|
|
{
|
|
z = fishZRange;
|
|
if (fish->angle > 3072)
|
|
LeaderInfo[leader].angle = fish->angle - ((GetRandomControl() & 127) + 128);
|
|
else
|
|
LeaderInfo[leader].angle = fish->angle + ((GetRandomControl() & 127) + 128);
|
|
LeaderInfo[leader].angleTime = (GetRandomControl() & 15) + 8;
|
|
LeaderInfo[leader].speedTime = 0;
|
|
}
|
|
|
|
if (x < -fishXRange)
|
|
{
|
|
x = -fishXRange;
|
|
if (fish->angle < 1024)
|
|
LeaderInfo[leader].angle = fish->angle - ((GetRandomControl() & 127) + 128);
|
|
else
|
|
LeaderInfo[leader].angle = fish->angle + ((GetRandomControl() & 127) + 128);
|
|
LeaderInfo[leader].angleTime = (GetRandomControl() & 15) + 8;
|
|
LeaderInfo[leader].speedTime = 0;
|
|
}
|
|
else if (x > fishXRange)
|
|
{
|
|
x = fishXRange;
|
|
if (fish->angle < 3072)
|
|
LeaderInfo[leader].angle = fish->angle - ((GetRandomControl() & 127) + 128);
|
|
else
|
|
LeaderInfo[leader].angle = fish->angle + ((GetRandomControl() & 127) + 128);
|
|
LeaderInfo[leader].angleTime = (GetRandomControl() & 15) + 8;
|
|
LeaderInfo[leader].speedTime = 0;
|
|
}
|
|
|
|
if ((GetRandomControl() & 15) == 0)
|
|
LeaderInfo[leader].angleTime = 0;
|
|
|
|
if (LeaderInfo[leader].angleTime)
|
|
LeaderInfo[leader].angleTime--;
|
|
else
|
|
{
|
|
LeaderInfo[leader].angleTime = (GetRandomControl() & 15) + 8;
|
|
int angAdd = ((GetRandomControl() & 63) + 16) - 8 - 32;
|
|
if ((GetRandomControl() & 3) == 0)
|
|
LeaderInfo[leader].angle += angAdd << 5;
|
|
else
|
|
LeaderInfo[leader].angle += angAdd;
|
|
LeaderInfo[leader].angle &= 4095;
|
|
}
|
|
|
|
if (LeaderInfo[leader].speedTime)
|
|
LeaderInfo[leader].speedTime--;
|
|
else
|
|
{
|
|
LeaderInfo[leader].speedTime = (GetRandomControl() & 31) + 32;
|
|
if ((GetRandomControl() & 7) == 0)
|
|
LeaderInfo[leader].speed = (GetRandomControl() & 127) + 128;
|
|
else if ((GetRandomControl() & 3) == 0)
|
|
LeaderInfo[leader].speed += (GetRandomControl() & 127) + 32;
|
|
else if (LeaderInfo[leader].speed > 140)
|
|
LeaderInfo[leader].speed -= (GetRandomControl() & 31) + 48;
|
|
else
|
|
{
|
|
LeaderInfo[leader].speedTime = (GetRandomControl() & 3) + 4;
|
|
LeaderInfo[leader].speed += (GetRandomControl() & 31) - 15;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
int ftx = x;
|
|
int ftz = z;
|
|
|
|
fish->x = x;
|
|
fish->z = z;
|
|
|
|
fish = (FISH_INFO*)&Fishes[MAX_FISH + (leader * 24)];
|
|
|
|
for (int i = 0; i < 24; i++)
|
|
{
|
|
if (item->flags & OCB_FISH_LETAL)
|
|
{
|
|
PHD_3DPOS pos;
|
|
pos.xPos = item->pos.xPos + fish->x;
|
|
pos.yPos = item->pos.yPos + fish->y;
|
|
pos.zPos = item->pos.zPos + fish->z;
|
|
if (FishNearLara(&pos, 256, (pirahnaAttack < 2) ? LaraItem : enemy))
|
|
{
|
|
if (PirahnaHitWait == 0)
|
|
{
|
|
DoBloodSplat(item->pos.xPos + fish->x, item->pos.yPos + fish->y, item->pos.zPos + fish->z, 0, 0, (pirahnaAttack < 2) ? LaraItem->roomNumber : enemy->roomNumber);
|
|
PirahnaHitWait = 8;
|
|
}
|
|
if (pirahnaAttack != 2)
|
|
LaraItem->hitPoints -= PIRAHNA_DAMAGE;
|
|
}
|
|
}
|
|
|
|
angle = (-(mGetAngle(fish->x, fish->z, ftx, ftz) + 0x4000) >> 4) & 4095;
|
|
int dx = fish->x - ftx + ((24 - i) << 7);
|
|
int dz = fish->z - ftz - ((24 - i) << 7);
|
|
|
|
dx *= dx;
|
|
dz *= dz;
|
|
|
|
diff = fish->angle - angle;
|
|
|
|
if (diff > 2048)
|
|
diff -= 4096;
|
|
else if (diff < -2048)
|
|
diff += 4096;
|
|
|
|
if (diff > 128)
|
|
{
|
|
fish->angAdd -= 4;
|
|
if (fish->angAdd < -92 - (i >> 1))
|
|
fish->angAdd = -92 - (i >> 1);
|
|
}
|
|
else if (diff < -128)
|
|
{
|
|
fish->angAdd += 4;
|
|
if (fish->angAdd > 92 + (i >> 1))
|
|
fish->angAdd = 92 + (i >> 1);
|
|
}
|
|
else
|
|
{
|
|
fish->angAdd -= fish->angAdd >> 2;
|
|
if (abs(fish->angAdd) < 4)
|
|
fish->angAdd = 0;
|
|
}
|
|
|
|
fish->angle += fish->angAdd;
|
|
|
|
if (diff > 1024)
|
|
fish->angle += fish->angAdd >> 2;
|
|
fish->angle &= 4095;
|
|
|
|
if ((dx + dz) < (0x100000 + ((i << 7) * (i << 7))))
|
|
{
|
|
if (fish->speed > 32 + (i << 1))
|
|
fish->speed -= fish->speed >> 5;
|
|
}
|
|
else
|
|
{
|
|
if (fish->speed < 160 + (i >> 1))
|
|
fish->speed += (GetRandomControl() & 3) + 1 + (i >> 1);
|
|
if (fish->speed > 160 + (i >> 1) - (i << 2))
|
|
fish->speed = 160 + (i >> 1) - (i << 2);
|
|
}
|
|
|
|
if (GetRandomControl() & 1)
|
|
fish->speed -= GetRandomControl() & 1;
|
|
else
|
|
fish->speed += GetRandomControl() & 1;
|
|
|
|
if (fish->speed < 32)
|
|
fish->speed = 32;
|
|
else if (fish->speed > 200)
|
|
fish->speed = 200;
|
|
|
|
fish->swim += (fish->speed >> 4) + (fish->speed >> 5);
|
|
fish->swim &= 63;
|
|
|
|
x = fish->x - fish->speed * SIN(fish->angle << 4) >> W2V_SHIFT; // (((rcossin_tbl[(fish->angle << 1)])* (fish->speed)) >> 13);
|
|
z = fish->z + fish->speed * COS(fish->angle << 4) >> W2V_SHIFT; //
|
|
|
|
if (z < -32000)
|
|
z = -32000;
|
|
else if (z > 32000)
|
|
z = 32000;
|
|
if (x < -32000)
|
|
x = -32000;
|
|
else if (x > 32000)
|
|
x = 32000;
|
|
|
|
fish->x = x;
|
|
fish->z = z;
|
|
|
|
if (pirahnaAttack == 0)
|
|
{
|
|
if (abs(fish->y - fish->destY) < 16)
|
|
fish->destY = GetRandomControl() % LeaderInfo[leader].yRange;
|
|
}
|
|
else
|
|
{
|
|
int y = enemy->pos.yPos - item->pos.yPos;
|
|
if (abs(fish->y - fish->destY) < 16)
|
|
fish->destY = y + (GetRandomControl() & 255);
|
|
}
|
|
|
|
fish->y += (fish->destY - fish->y) >> 4;
|
|
fish++;
|
|
}
|
|
}
|
|
|
|
bool FishNearLara(PHD_3DPOS* pos, int distance, ITEM_INFO* item)
|
|
{
|
|
int x = pos->xPos - item->pos.xPos;
|
|
int y = abs(pos->yPos - item->pos.yPos);
|
|
int z = pos->zPos - item->pos.zPos;
|
|
|
|
if (x < -distance || x > distance || z < -distance || z > distance || y < -WALL_SIZE * 3 || y > WALL_SIZE * 3)
|
|
return false;
|
|
|
|
if (x * x + z * z > SQUARE(distance))
|
|
return false;
|
|
|
|
if (y > distance)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|