mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-05-02 17:57:59 +03:00
Move globals into KayakInfo; cleanup
This commit is contained in:
parent
d494a115b0
commit
6603670a93
11 changed files with 404 additions and 406 deletions
|
@ -585,7 +585,7 @@ bool HandleLaraVehicle(ITEM_INFO* item, COLL_INFO* coll)
|
|||
break;
|
||||
|
||||
case ID_UPV:
|
||||
SubControl(item, coll);
|
||||
UPVControl(item, coll);
|
||||
break;
|
||||
|
||||
case ID_MINECART:
|
||||
|
|
|
@ -474,8 +474,8 @@ void FireHarpoon(ITEM_INFO* laraItem)
|
|||
}
|
||||
|
||||
item->Position.zRot = 0;
|
||||
item->Velocity = HARPOON_SPEED * phd_cos(item->Position.xRot);
|
||||
item->VerticalVelocity = -HARPOON_SPEED * phd_sin(item->Position.xRot);
|
||||
item->Velocity = HARPOON_VELOCITY * phd_cos(item->Position.xRot);
|
||||
item->VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Position.xRot);
|
||||
item->HitPoints = HARPOON_TIME;
|
||||
|
||||
AddActiveItem(itemNumber);
|
||||
|
@ -507,8 +507,8 @@ void HarpoonBoltControl(short itemNumber)
|
|||
if (item->Position.xRot < -ANGLE(90.0f))
|
||||
item->Position.xRot = -ANGLE(90.0f);
|
||||
|
||||
item->VerticalVelocity = -HARPOON_SPEED * phd_sin(item->Position.xRot);
|
||||
item->Velocity = HARPOON_SPEED * phd_cos(item->Position.xRot);
|
||||
item->VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Position.xRot);
|
||||
item->Velocity = HARPOON_VELOCITY * phd_cos(item->Position.xRot);
|
||||
aboveWater = true;
|
||||
}
|
||||
else
|
||||
|
@ -518,8 +518,8 @@ void HarpoonBoltControl(short itemNumber)
|
|||
CreateBubble((PHD_VECTOR*)&item->Position, item->RoomNumber, 0, 0, BUBBLE_FLAG_CLUMP | BUBBLE_FLAG_HIGH_AMPLITUDE, 0, 0, 0); // CHECK
|
||||
|
||||
TriggerRocketSmoke(item->Position.xPos, item->Position.yPos, item->Position.zPos, 64);
|
||||
item->VerticalVelocity = -HARPOON_SPEED * phd_sin(item->Position.xRot) / 2;
|
||||
item->Velocity = HARPOON_SPEED * phd_cos(item->Position.xRot) / 2;
|
||||
item->VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Position.xRot) / 2;
|
||||
item->Velocity = HARPOON_VELOCITY * phd_cos(item->Position.xRot) / 2;
|
||||
aboveWater = false;
|
||||
}
|
||||
|
||||
|
@ -697,7 +697,7 @@ void FireGrenade(ITEM_INFO* laraItem)
|
|||
item->Position.yRot += lara->ExtraTorsoRot.yRot;
|
||||
}
|
||||
|
||||
item->Velocity = GRENADE_SPEED;
|
||||
item->Velocity = GRENADE_VELOCITY;
|
||||
item->VerticalVelocity = -512 * phd_sin(item->Position.xRot);
|
||||
item->ActiveState = item->Position.xRot;
|
||||
item->TargetState = item->Position.yRot;
|
||||
|
@ -1180,14 +1180,14 @@ void RocketControl(short itemNumber)
|
|||
bool abovewater = false;
|
||||
if (TestEnvironment(ENV_FLAG_WATER, item->RoomNumber))
|
||||
{
|
||||
if (item->Velocity > (ROCKET_SPEED / 4))
|
||||
if (item->Velocity > (ROCKET_VELOCITY / 4))
|
||||
item->Velocity -= item->Velocity / 4;
|
||||
else
|
||||
{
|
||||
item->Velocity += (item->Velocity / 4) + 4;
|
||||
|
||||
if (item->Velocity > (ROCKET_SPEED / 4))
|
||||
item->Velocity = ROCKET_SPEED / 4;
|
||||
if (item->Velocity > (ROCKET_VELOCITY / 4))
|
||||
item->Velocity = ROCKET_VELOCITY / 4;
|
||||
}
|
||||
|
||||
item->Position.zRot += (((item->Velocity / 8) + 3) * ANGLE(1.0f));
|
||||
|
@ -1195,7 +1195,7 @@ void RocketControl(short itemNumber)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (item->Velocity < ROCKET_SPEED)
|
||||
if (item->Velocity < ROCKET_VELOCITY)
|
||||
item->Velocity += (item->Velocity / 4) + 4;
|
||||
|
||||
item->Position.zRot += (((item->Velocity / 4) + 7) * ANGLE(1.0f));
|
||||
|
|
|
@ -4,6 +4,29 @@
|
|||
struct ITEM_INFO;
|
||||
enum LaraWeaponType;
|
||||
|
||||
#define PELLET_SCATTER ANGLE(20.0f)
|
||||
|
||||
constexpr auto HARPOON_DRAW_ANIM = 1;
|
||||
constexpr auto ROCKET_DRAW_ANIM = 0;
|
||||
constexpr auto HARPOON_VELOCITY = CLICK(1);
|
||||
constexpr auto HARPOON_TIME = 300;
|
||||
constexpr auto ROCKET_VELOCITY = CLICK(2);
|
||||
constexpr auto GRENADE_VELOCITY = CLICK(0.5f);
|
||||
constexpr auto MAX_GRENADE_VERTICAL_VELOCITY = CLICK(0.5f);
|
||||
constexpr auto GRENADE_Y_OFFSET = 180;
|
||||
constexpr auto GRENADE_Z_OFFSET = 80;
|
||||
constexpr auto CROSSBOW_DAMAGE = 5;
|
||||
constexpr auto CROSSBOW_AMMO1 = 1;
|
||||
constexpr auto CROSSBOW_AMMO2 = 2;
|
||||
constexpr auto CROSSBOW_AMMO3 = 2;
|
||||
constexpr auto CROSSBOW_HIT_RADIUS = CLICK(0.5f);
|
||||
constexpr auto CROSSBOW_EXPLODE_RADIUS = SECTOR(2);
|
||||
constexpr auto GRENADE_HIT_RADIUS = CLICK(0.5f);
|
||||
constexpr auto GRENADE_EXPLODE_RADIUS = SECTOR(2);
|
||||
constexpr auto ROCKET_HIT_RADIUS = CLICK(0.5f);
|
||||
constexpr auto ROCKET_EXPLODE_RADIUS = SECTOR(2);
|
||||
constexpr auto HARPOON_HIT_RADIUS = CLICK(0.5f);
|
||||
|
||||
enum class GrenadeType
|
||||
{
|
||||
Normal,
|
||||
|
@ -13,29 +36,6 @@ enum class GrenadeType
|
|||
Flags
|
||||
};
|
||||
|
||||
#define PELLET_SCATTER ANGLE(20.0f)
|
||||
|
||||
constexpr auto HARPOON_DRAW_ANIM = 1;
|
||||
constexpr auto ROCKET_DRAW_ANIM = 0;
|
||||
constexpr auto HARPOON_SPEED = 256;
|
||||
constexpr auto HARPOON_TIME = 300;
|
||||
constexpr auto ROCKET_SPEED = 512;
|
||||
constexpr auto GRENADE_SPEED = 128;
|
||||
constexpr auto MAX_GRENADE_FALLSPEED = 128;
|
||||
constexpr auto GRENADE_YOFF = 180;
|
||||
constexpr auto GRENADE_ZOFF = 80;
|
||||
constexpr auto CROSSBOW_DAMAGE = 5;
|
||||
constexpr auto CROSSBOW_AMMO1 = 1;
|
||||
constexpr auto CROSSBOW_AMMO2 = 2;
|
||||
constexpr auto CROSSBOW_AMMO3 = 2;
|
||||
constexpr auto CROSSBOW_HIT_RADIUS = 128;
|
||||
constexpr auto CROSSBOW_EXPLODE_RADIUS = SECTOR(2);
|
||||
constexpr auto GRENADE_HIT_RADIUS = 128;
|
||||
constexpr auto GRENADE_EXPLODE_RADIUS = SECTOR(2);
|
||||
constexpr auto ROCKET_HIT_RADIUS = 128;
|
||||
constexpr auto ROCKET_EXPLODE_RADIUS = SECTOR(2);
|
||||
constexpr auto HARPOON_HIT_RADIUS = 128;
|
||||
|
||||
void AnimateShotgun(ITEM_INFO* laraItem, LaraWeaponType weaponType);
|
||||
void ReadyShotgun(ITEM_INFO* laraItem, LaraWeaponType weaponType);
|
||||
void FireShotgun(ITEM_INFO* laraItem);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
#include "Game/animation.h"
|
||||
#include "Game/collision/collide_item.h"
|
||||
#include "Game/collision/collide_room.h"
|
||||
#include "Game/effects/effects.h"
|
||||
#include "Game/Lara/lara.h"
|
||||
#include "Game/items.h"
|
||||
|
@ -14,58 +15,50 @@
|
|||
#define ROCKET_DAMAGE 100
|
||||
#define DIVER_HARPOON_DAMAGE 50
|
||||
|
||||
#define SHARD_SPEED 250
|
||||
#define ROCKET_SPEED 220
|
||||
#define NATLAGUN_SPEED 400
|
||||
#define SHARD_VELOCITY 250
|
||||
#define ROCKET_VELOCITY 220
|
||||
#define NATLAGUN_VELOCITY 400
|
||||
|
||||
void ShootAtLara(FX_INFO *fx)
|
||||
{
|
||||
int x, y, z, distance;
|
||||
BOUNDING_BOX* bounds;
|
||||
int x = LaraItem->Position.xPos - fx->pos.xPos;
|
||||
int y = LaraItem->Position.yPos - fx->pos.yPos;
|
||||
int z = LaraItem->Position.zPos - fx->pos.zPos;
|
||||
|
||||
x = LaraItem->Position.xPos - fx->pos.xPos;
|
||||
y = LaraItem->Position.yPos - fx->pos.yPos;
|
||||
z = LaraItem->Position.zPos - fx->pos.zPos;
|
||||
|
||||
bounds = GetBoundsAccurate(LaraItem);
|
||||
auto* bounds = GetBoundsAccurate(LaraItem);
|
||||
y += bounds->Y2 + (bounds->Y1 - bounds->Y2) * 3 / 4;
|
||||
|
||||
distance = sqrt(SQUARE(x) + SQUARE(z));
|
||||
int distance = sqrt(pow(x, 2) + pow(z, 2));
|
||||
fx->pos.xRot = -phd_atan(distance, y);
|
||||
fx->pos.yRot = phd_atan(z, x);
|
||||
|
||||
/* Random scatter (only a little bit else it's too hard to avoid) */
|
||||
// Random scatter (only a little bit else it's too hard to avoid).
|
||||
fx->pos.xRot += (GetRandomControl() - 0x4000) / 0x40;
|
||||
fx->pos.yRot += (GetRandomControl() - 0x4000) / 0x40;
|
||||
}
|
||||
|
||||
void ControlMissile(short fxNumber)
|
||||
{
|
||||
FX_INFO *fx;
|
||||
FLOOR_INFO *floor;
|
||||
short roomNumber;
|
||||
int speed;
|
||||
|
||||
fx = &EffectList[fxNumber];
|
||||
auto* fx = &EffectList[fxNumber];
|
||||
printf("ControlMissile\n");
|
||||
|
||||
if (fx->objectNumber == ID_SCUBA_HARPOON && !(g_Level.Rooms[fx->roomNumber].flags & 1) && fx->pos.xRot > -0x3000)
|
||||
fx->pos.xRot -= ONE_DEGREE;
|
||||
fx->pos.xRot -= ANGLE(1.0f);
|
||||
|
||||
fx->pos.yPos += fx->speed * phd_sin(-fx->pos.xRot);
|
||||
speed = fx->speed * phd_cos(fx->pos.xRot);
|
||||
int speed = fx->speed * phd_cos(fx->pos.xRot);
|
||||
fx->pos.zPos += speed * phd_cos(fx->pos.yRot);
|
||||
fx->pos.xPos += speed * phd_sin(fx->pos.yRot);
|
||||
roomNumber = fx->roomNumber;
|
||||
floor = GetFloor(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, &roomNumber);
|
||||
|
||||
/* Check for hitting something */
|
||||
if (fx->pos.yPos >= GetFloorHeight(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos) ||
|
||||
fx->pos.yPos <= GetCeiling(floor, fx->pos.xPos, fx->pos.yPos, fx->pos.zPos))
|
||||
auto probe = GetCollisionResult(fx->pos.xPos, fx->pos.yPos, fx->pos.zPos, fx->roomNumber);
|
||||
|
||||
// Check for hitting something.
|
||||
if (fx->pos.yPos >= probe.Position.Floor ||
|
||||
fx->pos.yPos <= probe.Position.Ceiling)
|
||||
{
|
||||
if (/*fx->objectNumber == KNIFE ||*/ fx->objectNumber == ID_SCUBA_HARPOON)
|
||||
{
|
||||
/* Change shard into ricochet */
|
||||
// Change shard into ricochet.
|
||||
// fx->speed = 0;
|
||||
// fx->frameNumber = -GetRandomControl()/11000;
|
||||
// fx->counter = 6;
|
||||
|
@ -80,10 +73,10 @@ void ControlMissile(short fxNumber)
|
|||
return;
|
||||
}
|
||||
|
||||
if (roomNumber != fx->roomNumber)
|
||||
EffectNewRoom(fxNumber, roomNumber);
|
||||
if (probe.RoomNumber != fx->roomNumber)
|
||||
EffectNewRoom(fxNumber, probe.RoomNumber);
|
||||
|
||||
/* Check for hitting Lara */
|
||||
// Check for hitting Lara.
|
||||
/*if (fx->objectNumber == DRAGON_FIRE)
|
||||
{
|
||||
if (ItemNearLara(&fx->pos, 350))
|
||||
|
@ -108,14 +101,15 @@ void ControlMissile(short fxNumber)
|
|||
SoundEffect(317, &fx->pos, 0);
|
||||
KillEffect(fxNumber);
|
||||
}
|
||||
LaraItem->HitStatus = 1;
|
||||
|
||||
LaraItem->HitStatus = 1;
|
||||
|
||||
fx->pos.yRot = LaraItem->Position.yRot;
|
||||
fx->speed = LaraItem->Velocity;
|
||||
fx->frameNumber = fx->counter = 0;
|
||||
}
|
||||
|
||||
/* Create bubbles in wake of harpoon bolt */
|
||||
// Create bubbles in wake of harpoon bolt.
|
||||
//if (fx->objectNumber == ID_SCUBA_HARPOON && g_Level.Rooms[fx->roomNumber].flags & 1)
|
||||
// CreateBubble(&fx->pos, fx->roomNumber, 1, 0);
|
||||
/*else if (fx->objectNumber == DRAGON_FIRE && !fx->counter--)
|
||||
|
@ -128,42 +122,41 @@ void ControlMissile(short fxNumber)
|
|||
fx->pos.zRot += 30 * ONE_DEGREE;*/
|
||||
}
|
||||
|
||||
void ControlNatlaGun(short fx_number)
|
||||
void ControlNatlaGun(short fxNumber)
|
||||
{
|
||||
FX_INFO* fx, *newfx;
|
||||
OBJECT_INFO* object;
|
||||
FLOOR_INFO* floor;
|
||||
short roomNumber;
|
||||
int x, y, z;
|
||||
auto* fx = &EffectList[fxNumber];
|
||||
auto* object = &Objects[fx->objectNumber];
|
||||
|
||||
fx = &EffectList[fx_number];
|
||||
object = &Objects[fx->objectNumber];
|
||||
fx->frameNumber--;
|
||||
if (fx->frameNumber <= Objects[fx->objectNumber].nmeshes)
|
||||
KillEffect(fx_number);
|
||||
KillEffect(fxNumber);
|
||||
|
||||
/* If first frame, then start another explosion at next position */
|
||||
if (fx->frameNumber == -1)
|
||||
{
|
||||
z = fx->pos.zPos + fx->speed * phd_cos(fx->pos.yRot);
|
||||
x = fx->pos.xPos + fx->speed * phd_sin(fx->pos.yRot);
|
||||
y = fx->pos.yPos;
|
||||
roomNumber = fx->roomNumber;
|
||||
floor = GetFloor(x, y, z, &roomNumber);
|
||||
int z = fx->pos.zPos + fx->speed * phd_cos(fx->pos.yRot);
|
||||
int x = fx->pos.xPos + fx->speed * phd_sin(fx->pos.yRot);
|
||||
int y = fx->pos.yPos;
|
||||
|
||||
/* Don't create one if hit a wall */
|
||||
if (y >= GetFloorHeight(floor, x, y, z) || y <= GetCeiling(floor, x, y, z))
|
||||
return;
|
||||
auto probe = GetCollisionResult(x, y, z, fx->roomNumber);
|
||||
|
||||
fx_number = CreateNewEffect(roomNumber);
|
||||
if (fx_number != NO_ITEM)
|
||||
// Don't create one if hit a wall.
|
||||
if (y >= probe.Position.Floor ||
|
||||
y <= probe.Position.Ceiling)
|
||||
{
|
||||
newfx = &EffectList[fx_number];
|
||||
return;
|
||||
}
|
||||
|
||||
fxNumber = CreateNewEffect(probe.RoomNumber);
|
||||
if (fxNumber != NO_ITEM)
|
||||
{
|
||||
auto* newfx = &EffectList[fxNumber];
|
||||
|
||||
newfx->pos.xPos = x;
|
||||
newfx->pos.yPos = y;
|
||||
newfx->pos.zPos = z;
|
||||
newfx->pos.yRot = fx->pos.yRot;
|
||||
newfx->roomNumber = roomNumber;
|
||||
newfx->roomNumber = probe.RoomNumber;
|
||||
newfx->speed = fx->speed;
|
||||
newfx->frameNumber = 0;
|
||||
newfx->objectNumber = ID_PROJ_NATLA;
|
||||
|
@ -171,77 +164,71 @@ void ControlNatlaGun(short fx_number)
|
|||
}
|
||||
}
|
||||
|
||||
short ShardGun(int x, int y, int z, short speed, short yrot, short roomNumber)
|
||||
short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
|
||||
{
|
||||
short fx_number;
|
||||
FX_INFO* fx;
|
||||
|
||||
fx_number = CreateNewEffect(roomNumber);
|
||||
if (fx_number != NO_ITEM)
|
||||
short fxNumber = CreateNewEffect(roomNumber);
|
||||
if (fxNumber != NO_ITEM)
|
||||
{
|
||||
fx = &EffectList[fx_number];
|
||||
auto* fx = &EffectList[fxNumber];
|
||||
|
||||
fx->pos.xPos = x;
|
||||
fx->pos.yPos = y;
|
||||
fx->pos.zPos = z;
|
||||
fx->roomNumber = roomNumber;
|
||||
fx->pos.xRot = fx->pos.zRot = 0;
|
||||
fx->pos.yRot = yrot;
|
||||
fx->speed = SHARD_SPEED;
|
||||
fx->pos.yRot = yRot;
|
||||
fx->speed = SHARD_VELOCITY;
|
||||
fx->frameNumber = 0;
|
||||
fx->objectNumber = ID_PROJ_SHARD;
|
||||
fx->shade = 14 * 256;
|
||||
ShootAtLara(fx);
|
||||
}
|
||||
|
||||
return (fx_number);
|
||||
return fxNumber;
|
||||
}
|
||||
|
||||
short BombGun(int x, int y, int z, short speed, short yrot, short roomNumber)
|
||||
short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
|
||||
{
|
||||
short fx_number;
|
||||
FX_INFO* fx;
|
||||
|
||||
fx_number = CreateNewEffect(roomNumber);
|
||||
if (fx_number != NO_ITEM)
|
||||
short fxNumber = CreateNewEffect(roomNumber);
|
||||
if (fxNumber != NO_ITEM)
|
||||
{
|
||||
fx = &EffectList[fx_number];
|
||||
auto* fx = &EffectList[fxNumber];
|
||||
|
||||
fx->pos.xPos = x;
|
||||
fx->pos.yPos = y;
|
||||
fx->pos.zPos = z;
|
||||
fx->roomNumber = roomNumber;
|
||||
fx->pos.xRot = fx->pos.zRot = 0;
|
||||
fx->pos.yRot = yrot;
|
||||
fx->speed = ROCKET_SPEED;
|
||||
fx->pos.yRot = yRot;
|
||||
fx->speed = ROCKET_VELOCITY;
|
||||
fx->frameNumber = 0;
|
||||
fx->objectNumber = ID_PROJ_BOMB;
|
||||
fx->shade = 16 * 256;
|
||||
ShootAtLara(fx);
|
||||
}
|
||||
|
||||
return (fx_number);
|
||||
return fxNumber;
|
||||
}
|
||||
|
||||
short NatlaGun(int x, int y, int z, short speed, short yrot, short roomNumber)
|
||||
short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber)
|
||||
{
|
||||
short fx_number;
|
||||
FX_INFO* fx;
|
||||
|
||||
fx_number = CreateNewEffect(roomNumber);
|
||||
if (fx_number != NO_ITEM)
|
||||
short fxNumber = CreateNewEffect(roomNumber);
|
||||
if (fxNumber != NO_ITEM)
|
||||
{
|
||||
fx = &EffectList[fx_number];
|
||||
auto* fx = &EffectList[fxNumber];
|
||||
|
||||
fx->pos.xPos = x;
|
||||
fx->pos.yPos = y;
|
||||
fx->pos.zPos = z;
|
||||
fx->roomNumber = roomNumber;
|
||||
fx->pos.xRot = fx->pos.zRot = 0;
|
||||
fx->pos.yRot = yrot;
|
||||
fx->speed = NATLAGUN_SPEED;
|
||||
fx->pos.yRot = yRot;
|
||||
fx->speed = NATLAGUN_VELOCITY;
|
||||
fx->frameNumber = 0;
|
||||
fx->objectNumber = ID_PROJ_NATLA;
|
||||
fx->shade = 16 * 256;
|
||||
ShootAtLara(fx);
|
||||
}
|
||||
|
||||
return (fx_number);
|
||||
}
|
||||
return fxNumber;
|
||||
}
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
|
||||
void ShootAtLara(FX_INFO* fx);
|
||||
void ControlMissile(short fxNumber);
|
||||
void ControlNatlaGun(short fx_number);
|
||||
void ControlNatlaGun(short fxNumber);
|
||||
|
||||
short ShardGun(int x, int y, int z, short speed, short yrot, short roomNumber);
|
||||
short BombGun(int x, int y, int z, short speed, short yrot, short roomNumber); // RocketGun = BombGun
|
||||
short NatlaGun(int x, int y, int z, short speed, short yrot, short roomNumber);
|
||||
short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber);
|
||||
short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber); // RocketGun = BombGun
|
||||
short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber);
|
||||
|
|
|
@ -139,8 +139,6 @@ struct WAKE_PTS
|
|||
};
|
||||
|
||||
WAKE_PTS WakePts[NUM_WAKE_SPRITES][2];
|
||||
byte CurrentStartWake = 0;
|
||||
byte WakeShade = 0;
|
||||
|
||||
void InitialiseKayak(short itemNumber)
|
||||
{
|
||||
|
@ -155,9 +153,10 @@ void InitialiseKayak(short itemNumber)
|
|||
kayak->RightVerticalVelocity = 0;
|
||||
kayak->LeftRightCount = 0;
|
||||
kayak->OldPos = kayakItem->Position;
|
||||
kayak->CurrentStartWake = 0;
|
||||
kayak->WakeShade = 0;
|
||||
kayak->Flags = 0;
|
||||
|
||||
|
||||
for (int i = 0; i < NUM_WAKE_SPRITES; i++)
|
||||
{
|
||||
WakePts[i][0].life = 0;
|
||||
|
@ -172,7 +171,9 @@ void KayakDraw(ITEM_INFO* kayakItem)
|
|||
|
||||
void KayakDoWake(ITEM_INFO* kayakItem, int xOffset, int zOffset, short rotate)
|
||||
{
|
||||
if (WakePts[CurrentStartWake][rotate].life)
|
||||
auto* kayak = (KayakInfo*)kayakItem->Data;
|
||||
|
||||
if (WakePts[kayak->CurrentStartWake][rotate].life)
|
||||
return;
|
||||
|
||||
float s = phd_sin(kayakItem->Position.yRot);
|
||||
|
@ -220,21 +221,21 @@ void KayakDoWake(ITEM_INFO* kayakItem, int xOffset, int zOffset, short rotate)
|
|||
xv[1] = (WAKE_VELOCITY + 2) * phd_sin(angle2);
|
||||
zv[1] = (WAKE_VELOCITY + 2) * phd_cos(angle2);
|
||||
|
||||
WakePts[CurrentStartWake][rotate].y = kayakItem->Position.yPos + KAYAK_DRAW_SHIFT;
|
||||
WakePts[CurrentStartWake][rotate].life = 0x40;
|
||||
WakePts[kayak->CurrentStartWake][rotate].y = kayakItem->Position.yPos + KAYAK_DRAW_SHIFT;
|
||||
WakePts[kayak->CurrentStartWake][rotate].life = 0x40;
|
||||
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
WakePts[CurrentStartWake][rotate].x[i] = x;
|
||||
WakePts[CurrentStartWake][rotate].z[i] = z;
|
||||
WakePts[CurrentStartWake][rotate].xvel[i] = xv[i];
|
||||
WakePts[CurrentStartWake][rotate].zvel[i] = zv[i];
|
||||
WakePts[kayak->CurrentStartWake][rotate].x[i] = x;
|
||||
WakePts[kayak->CurrentStartWake][rotate].z[i] = z;
|
||||
WakePts[kayak->CurrentStartWake][rotate].xvel[i] = xv[i];
|
||||
WakePts[kayak->CurrentStartWake][rotate].zvel[i] = zv[i];
|
||||
}
|
||||
|
||||
if (rotate == 1)
|
||||
{
|
||||
CurrentStartWake++;
|
||||
CurrentStartWake &= (NUM_WAKE_SPRITES - 1);
|
||||
kayak->CurrentStartWake++;
|
||||
kayak->CurrentStartWake &= (NUM_WAKE_SPRITES - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -425,9 +426,9 @@ void KayakDoCurrent(ITEM_INFO* laraItem, ITEM_INFO* kayakItem)
|
|||
int dx = target.x - laraItem->Position.xPos;
|
||||
int dz = target.z - laraItem->Position.zPos;
|
||||
|
||||
int speed = g_Level.Sinks[sinkval].strength;
|
||||
dx = phd_sin(angle * 16) * speed * 1024;
|
||||
dz = phd_cos(angle * 16) * speed * 1024;
|
||||
int velocity = g_Level.Sinks[sinkval].strength;
|
||||
dx = phd_sin(angle * 16) * velocity * 1024;
|
||||
dz = phd_cos(angle * 16) * velocity * 1024;
|
||||
|
||||
lara->ExtraVelocity.x += (dx - lara->ExtraVelocity.x) / 16;
|
||||
lara->ExtraVelocity.z += (dz - lara->ExtraVelocity.z) / 16;
|
||||
|
@ -813,6 +814,7 @@ void KayakUserInput(ITEM_INFO* laraItem, ITEM_INFO* kayakItem)
|
|||
if (!frame)
|
||||
kayak->LeftRightCount = 0;
|
||||
|
||||
// TODO: Sort out the bitwise operations.
|
||||
if (frame == 2 && !(kayak->LeftRightCount & 0x80))
|
||||
kayak->LeftRightCount++;
|
||||
|
||||
|
@ -1354,13 +1356,13 @@ bool KayakControl(ITEM_INFO* laraItem)
|
|||
!lara->ExtraVelocity.x &&
|
||||
!lara->ExtraVelocity.z)
|
||||
{
|
||||
if (WakeShade)
|
||||
WakeShade--;
|
||||
if (kayak->WakeShade)
|
||||
kayak->WakeShade--;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (WakeShade < 16)
|
||||
WakeShade++;
|
||||
if (kayak->WakeShade < 16)
|
||||
kayak->WakeShade++;
|
||||
}
|
||||
|
||||
KayakUpdateWakeFX();
|
||||
|
|
|
@ -17,5 +17,8 @@ struct KayakInfo
|
|||
bool Forward;
|
||||
bool TrueWater;
|
||||
|
||||
int CurrentStartWake;
|
||||
int WakeShade;
|
||||
|
||||
char Flags;
|
||||
};
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "Game/camera.h"
|
||||
#include "Game/collision/sphere.h"
|
||||
#include "Game/collision/collide_item.h"
|
||||
#include "Game/collision/collide_room.h"
|
||||
#include "Game/control/box.h"
|
||||
#include "Game/control/los.h"
|
||||
#include "Game/effects/bubble.h"
|
||||
|
@ -43,24 +44,24 @@ BITE_INFO UPVBites[6] =
|
|||
#define ROT_SLOWACCEL 0x200000
|
||||
#define ROT_FRICTION 0x100000
|
||||
#define MAX_ROTATION 0x1c00000
|
||||
#define UPDOWN_ACCEL (ANGLE(2.0f) * 65536)
|
||||
#define UPDOWN_SLOWACCEL (ANGLE(1.0f) * 65536)
|
||||
#define UPDOWN_FRICTION (ANGLE(1.0f) * 65536)
|
||||
#define MAX_UPDOWN (ANGLE(2.0f) * 65536)
|
||||
#define UPDOWN_ACCEL (ANGLE(2.0f) * (USHRT_MAX + 1))
|
||||
#define UPDOWN_SLOWACCEL (ANGLE(1.0f) * (USHRT_MAX + 1))
|
||||
#define UPDOWN_FRICTION (ANGLE(1.0f) * (USHRT_MAX + 1))
|
||||
#define MAX_UPDOWN (ANGLE(2.0f) * (USHRT_MAX + 1))
|
||||
#define UPDOWN_LIMIT ANGLE(80.0f)
|
||||
#define UPDOWN_SPEED 10
|
||||
#define SURFACE_DIST 210
|
||||
#define SURFACE_ANGLE ANGLE(30.0f)
|
||||
#define DIVE_ANGLE ANGLE(15.0f)
|
||||
#define DIVE_SPEED ANGLE(5.0f)
|
||||
#define SUB_DRAW_SHIFT 128
|
||||
#define SUB_RADIUS 300
|
||||
#define SUB_HEIGHT 400
|
||||
#define SUB_LENGTH SECTOR(1)
|
||||
#define FRONT_TOLERANCE (ANGLE(45.0f) * 65536)
|
||||
#define TOP_TOLERANCE (ANGLE(45.0f) * 65536)
|
||||
#define WALLDEFLECT (ANGLE(2.0f) * 65536)
|
||||
#define GETOFF_DIST SECTOR(1)
|
||||
#define UPV_DRAW_SHIFT 128
|
||||
#define UPV_RADIUS 300
|
||||
#define UPV_HEIGHT 400
|
||||
#define UPV_LENGTH SECTOR(1)
|
||||
#define FRONT_TOLERANCE (ANGLE(45.0f) * (USHRT_MAX + 1))
|
||||
#define TOP_TOLERANCE (ANGLE(45.0f) * (USHRT_MAX + 1))
|
||||
#define WALL_DEFLECT (ANGLE(2.0f) * (USHRT_MAX + 1))
|
||||
#define DISMOUNT_DISTANCE SECTOR(1)
|
||||
#define HARPOON_VELOCITY CLICK(1)
|
||||
#define HARPOON_RELOAD 15
|
||||
|
||||
|
@ -75,26 +76,26 @@ BITE_INFO UPVBites[6] =
|
|||
#define MOUNT_UNDERWATER_SOUND_FRAME 30
|
||||
#define MOUNT_UNDERWATER_CONTROL_FRAME 42
|
||||
|
||||
#define UPV_IN_PROPEL IN_JUMP
|
||||
#define UPV_IN_UP IN_FORWARD
|
||||
#define UPV_IN_DOWN IN_BACK
|
||||
#define UPV_IN_LEFT IN_LEFT
|
||||
#define UPV_IN_RIGHT IN_RIGHT
|
||||
#define UPV_IN_FIRE IN_ACTION
|
||||
#define UPV_IN_DISMOUNT IN_ROLL
|
||||
#define UPV_IN_PROPEL IN_JUMP
|
||||
#define UPV_IN_UP IN_FORWARD
|
||||
#define UPV_IN_DOWN IN_BACK
|
||||
#define UPV_IN_LEFT IN_LEFT
|
||||
#define UPV_IN_RIGHT IN_RIGHT
|
||||
#define UPV_IN_FIRE IN_ACTION
|
||||
#define UPV_IN_DISMOUNT IN_ROLL
|
||||
|
||||
enum UPVState
|
||||
{
|
||||
UPV_STATE_DEATH,
|
||||
UPV_STATE_HIT,
|
||||
UPV_STATE_DISMOUNT_SURFACE,
|
||||
UPV_STATE_UNK1,
|
||||
UPV_STATE_MOVE,
|
||||
UPV_STATE_IDLE,
|
||||
UPV_STATE_UNK2,
|
||||
UPV_STATE_UNK3,
|
||||
UPV_STATE_MOUNT,
|
||||
UPV_STATE_DISMOUNT_UNDERWATER
|
||||
UPV_STATE_DEATH = 0,
|
||||
UPV_STATE_HIT = 1,
|
||||
UPV_STATE_DISMOUNT_WATER_SURFACE = 2,
|
||||
UPV_STATE_UNK1 = 3,
|
||||
UPV_STATE_MOVE = 4,
|
||||
UPV_STATE_IDLE = 5,
|
||||
UPV_STATE_UNK2 = 6, // TODO
|
||||
UPV_STATE_UNK3 = 7, // TODO
|
||||
UPV_STATE_MOUNT = 8,
|
||||
UPV_STATE_DISMOUNT_UNDERWATER = 9
|
||||
};
|
||||
|
||||
// TODO
|
||||
|
@ -111,75 +112,76 @@ enum UPVAnim
|
|||
UPV_ANIM_MOUNT_UNDERWATER = 13,
|
||||
};
|
||||
|
||||
enum SUB_BITE_FLAG
|
||||
enum UPVBiteFlags
|
||||
{
|
||||
SUB_FAN = 0,
|
||||
SUB_FRONT_LIGHT,
|
||||
SUB_LEFT_FIN_LEFT,
|
||||
SUB_LEFT_FIN_RIGHT,
|
||||
SUB_RIGHT_FIN_RIGHT,
|
||||
SUB_RIGHT_FIN_LEFT
|
||||
UPV_FAN = 0,
|
||||
UPV_FRONT_LIGHT = 1,
|
||||
UPV_LEFT_FIN_LEFT = 2,
|
||||
UPV_LEFT_FIN_RIGHT = 3,
|
||||
UPV_RIGHT_FIN_RIGHT = 4,
|
||||
UPV_RIGHT_FIN_LEFT = 5
|
||||
};
|
||||
|
||||
void UPVInitialise(short itemNumber)
|
||||
{
|
||||
ITEM_INFO* UPVItem = &g_Level.Items[itemNumber];
|
||||
auto* UPVItem = &g_Level.Items[itemNumber];
|
||||
UPVItem->Data = UPVInfo();
|
||||
UPVInfo* UPV = UPVItem->Data;
|
||||
auto* UPV = (UPVInfo*)UPVItem->Data;
|
||||
|
||||
UPV->Vel = UPV->Rot = 0;
|
||||
UPV->Velocity = 0;
|
||||
UPV->Rot = 0;
|
||||
UPV->Flags = UPV_SURFACE;
|
||||
UPV->WeaponTimer = 0;
|
||||
UPV->HarpoonTimer = 0;
|
||||
UPV->HarpoonLeft = false;
|
||||
}
|
||||
|
||||
static void FireSubHarpoon(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
static void FireUPVHarpoon(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
{
|
||||
short itemNum = CreateItem();
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
auto UPV = (UPVInfo*)UPVItem->Data;
|
||||
|
||||
if (itemNum != NO_ITEM)
|
||||
short itemNumber = CreateItem();
|
||||
|
||||
if (itemNumber != NO_ITEM)
|
||||
{
|
||||
static char lr = 0;
|
||||
PHD_VECTOR pos { (lr ? 22 : -22), 24, 230 };
|
||||
ITEM_INFO* harpoonItem = &g_Level.Items[itemNum];
|
||||
|
||||
auto* harpoonItem = &g_Level.Items[itemNumber];
|
||||
harpoonItem->ObjectNumber = ID_HARPOON;
|
||||
harpoonItem->Shade = 0xC210;
|
||||
harpoonItem->RoomNumber = UPVItem->RoomNumber;
|
||||
|
||||
PHD_VECTOR pos{ (UPV->HarpoonLeft ? 22 : -22), 24, 230 };
|
||||
GetJointAbsPosition(UPVItem, &pos, UPV_TURBINE_BONE);
|
||||
|
||||
harpoonItem->Position.xPos = pos.x;
|
||||
harpoonItem->Position.yPos = pos.y;
|
||||
harpoonItem->Position.zPos = pos.z;
|
||||
InitialiseItem(itemNum);
|
||||
InitialiseItem(itemNumber);
|
||||
|
||||
harpoonItem->Position.xRot = UPVItem->Position.xRot;
|
||||
harpoonItem->Position.yRot = UPVItem->Position.yRot;
|
||||
harpoonItem->Position.zRot = 0;
|
||||
|
||||
// TODO: Huh?
|
||||
harpoonItem->VerticalVelocity = -HARPOON_VELOCITY * phd_sin(harpoonItem->Position.xRot);
|
||||
harpoonItem->VerticalVelocity = HARPOON_VELOCITY * phd_cos(harpoonItem->Position.xRot);
|
||||
harpoonItem->HitPoints = HARPOON_TIME;
|
||||
harpoonItem->ItemFlags[0] = 1;
|
||||
|
||||
AddActiveItem(itemNum);
|
||||
AddActiveItem(itemNumber);
|
||||
|
||||
SoundEffect(SFX_TR3_LARA_HARPOON_FIRE_WATER, &LaraItem->Position, 2);
|
||||
SoundEffect(SFX_TR3_LARA_HARPOON_FIRE_WATER, &laraItem->Position, 2);
|
||||
|
||||
if (Lara.Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1])
|
||||
Lara.Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1]--;
|
||||
if (lara->Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1])
|
||||
lara->Weapons[WEAPON_HARPOON_GUN].Ammo[WEAPON_AMMO1]--;
|
||||
Statistics.Game.AmmoUsed++;
|
||||
|
||||
lr ^= 1;
|
||||
UPV->HarpoonLeft = !UPV->HarpoonLeft;
|
||||
}
|
||||
}
|
||||
|
||||
static void TriggerSubMist(long x, long y, long z, long speed, short angle)
|
||||
static void TriggerUPVMist(long x, long y, long z, long velocity, short angle)
|
||||
{
|
||||
long size, xv, zv;
|
||||
SPARKS* sptr;
|
||||
|
||||
sptr = &Sparks[GetFreeSpark()];
|
||||
auto* sptr = &Sparks[GetFreeSpark()];
|
||||
|
||||
sptr->on = 1;
|
||||
sptr->sR = 0;
|
||||
|
@ -200,8 +202,8 @@ static void TriggerSubMist(long x, long y, long z, long speed, short angle)
|
|||
sptr->x = x + ((GetRandomControl() & 15) - 8);
|
||||
sptr->y = y + ((GetRandomControl() & 15) - 8);
|
||||
sptr->z = z + ((GetRandomControl() & 15) - 8);
|
||||
zv = speed * phd_cos(angle) / 4;
|
||||
xv = speed * phd_sin(angle) / 4;
|
||||
long zv = velocity * phd_cos(angle) / 4;
|
||||
long xv = velocity * phd_sin(angle) / 4;
|
||||
sptr->xVel = xv + ((GetRandomControl() & 127) - 64);
|
||||
sptr->yVel = 0;
|
||||
sptr->zVel = zv + ((GetRandomControl() & 127) - 64);
|
||||
|
@ -222,61 +224,57 @@ static void TriggerSubMist(long x, long y, long z, long speed, short angle)
|
|||
|
||||
sptr->scalar = 3;
|
||||
sptr->gravity = sptr->maxYvel = 0;
|
||||
size = (GetRandomControl() & 7) + (speed / 2) + 16;
|
||||
long size = (GetRandomControl() & 7) + (velocity / 2) + 16;
|
||||
sptr->size = sptr->sSize = size / 4;
|
||||
sptr->dSize = size;
|
||||
}
|
||||
|
||||
void SubEffects(short itemNum)
|
||||
void UPVEffects(short itemNumber)
|
||||
{
|
||||
if (itemNum == NO_ITEM)
|
||||
if (itemNumber == NO_ITEM)
|
||||
return;
|
||||
|
||||
ITEM_INFO* laraItem = LaraItem;
|
||||
auto* laraItem = LaraItem;
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
ITEM_INFO* UPVItem = &g_Level.Items[itemNum];
|
||||
UPVInfo* UPV = UPVItem->Data;
|
||||
auto* UPVItem = &g_Level.Items[itemNumber];
|
||||
auto* UPV = (UPVInfo*)UPVItem->Data;
|
||||
|
||||
PHD_VECTOR pos;
|
||||
long lp;
|
||||
|
||||
if (lara->Vehicle == itemNum)
|
||||
if (lara->Vehicle == itemNumber)
|
||||
{
|
||||
if (!UPV->Vel)
|
||||
if (!UPV->Velocity)
|
||||
UPV->FanRot += ANGLE(2.0f);
|
||||
else
|
||||
UPV->FanRot += (UPV->Vel / 4069);
|
||||
UPV->FanRot += UPV->Velocity / 4069;
|
||||
|
||||
if (UPV->Vel)
|
||||
if (UPV->Velocity)
|
||||
{
|
||||
pos = { UPVBites[SUB_FAN].x, UPVBites[SUB_FAN].y, UPVBites[SUB_FAN].z };
|
||||
GetJointAbsPosition(UPVItem, &pos, UPVBites[SUB_FAN].meshNum);
|
||||
TriggerSubMist(pos.x, pos.y + SUB_DRAW_SHIFT, pos.z, abs(UPV->Vel) / 65536, UPVItem->Position.yRot + ANGLE(180.0f));
|
||||
pos = { UPVBites[UPV_FAN].x, UPVBites[UPV_FAN].y, UPVBites[UPV_FAN].z };
|
||||
GetJointAbsPosition(UPVItem, &pos, UPVBites[UPV_FAN].meshNum);
|
||||
|
||||
TriggerUPVMist(pos.x, pos.y + UPV_DRAW_SHIFT, pos.z, abs(UPV->Velocity) / (USHRT_MAX + 1), UPVItem->Position.yRot + ANGLE(180.0f));
|
||||
|
||||
if ((GetRandomControl() & 1) == 0)
|
||||
{
|
||||
PHD_3DPOS pos3d;
|
||||
short roomNum;
|
||||
|
||||
pos3d.xPos = pos.x + (GetRandomControl() & 63) - 32;
|
||||
pos3d.yPos = pos.y + SUB_DRAW_SHIFT;
|
||||
pos3d.zPos = pos.z + (GetRandomControl() & 63) - 32;
|
||||
roomNum = UPVItem->RoomNumber;
|
||||
GetFloor(pos3d.xPos, pos3d.yPos, pos3d.zPos, &roomNum);
|
||||
CreateBubble((PHD_VECTOR*)&pos3d, roomNum, 4, 8, BUBBLE_FLAG_CLUMP, 0, 0, 0);
|
||||
PHD_3DPOS pos2;
|
||||
pos2.xPos = pos.x + (GetRandomControl() & 63) - 32;
|
||||
pos2.yPos = pos.y + UPV_DRAW_SHIFT;
|
||||
pos2.zPos = pos.z + (GetRandomControl() & 63) - 32;
|
||||
short probedRoomNumber = GetCollisionResult(pos2.xPos, pos2.yPos, pos2.zPos, UPVItem->RoomNumber).RoomNumber;
|
||||
|
||||
CreateBubble((PHD_VECTOR*)&pos2, probedRoomNumber, 4, 8, BUBBLE_FLAG_CLUMP, 0, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (lp = 0; lp < 2; lp++)
|
||||
for (int lp = 0; lp < 2; lp++)
|
||||
{
|
||||
int random = 31 - (GetRandomControl() & 3);
|
||||
pos = { UPVBites[UPV_FRONT_LIGHT].x, UPVBites[UPV_FRONT_LIGHT].y, UPVBites[UPV_FRONT_LIGHT].z << (lp * 6) };
|
||||
GetJointAbsPosition(UPVItem, &pos, UPVBites[UPV_FRONT_LIGHT].meshNum);
|
||||
|
||||
GAME_VECTOR source, target;
|
||||
long r;
|
||||
|
||||
r = 31 - (GetRandomControl() & 3);
|
||||
pos = { UPVBites[SUB_FRONT_LIGHT].x, UPVBites[SUB_FRONT_LIGHT].y, UPVBites[SUB_FRONT_LIGHT].z << (lp * 6) };
|
||||
GetJointAbsPosition(UPVItem, &pos, UPVBites[SUB_FRONT_LIGHT].meshNum);
|
||||
|
||||
if (lp == 1)
|
||||
{
|
||||
target.x = pos.x;
|
||||
|
@ -294,11 +292,11 @@ void SubEffects(short itemNum)
|
|||
source.roomNumber = UPVItem->RoomNumber;
|
||||
}
|
||||
|
||||
TriggerDynamicLight(pos.x, pos.y, pos.z, 16 + (lp << 3), r, r, r);
|
||||
TriggerDynamicLight(pos.x, pos.y, pos.z, 16 + (lp << 3), random, random, random);
|
||||
}
|
||||
|
||||
if (UPV->WeaponTimer)
|
||||
UPV->WeaponTimer--;
|
||||
if (UPV->HarpoonTimer)
|
||||
UPV->HarpoonTimer--;
|
||||
}
|
||||
|
||||
static bool TestUPVDismount(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
|
@ -309,14 +307,14 @@ static bool TestUPVDismount(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
return false;
|
||||
|
||||
short moveAngle = UPVItem->Position.yRot + ANGLE(180.0f);
|
||||
int speed = GETOFF_DIST * phd_cos(UPVItem->Position.xRot);
|
||||
int x = UPVItem->Position.xPos + speed * phd_sin(moveAngle);
|
||||
int z = UPVItem->Position.zPos + speed * phd_cos(moveAngle);
|
||||
int y = UPVItem->Position.yPos - GETOFF_DIST * phd_sin(-UPVItem->Position.xRot);
|
||||
auto probe = GetCollisionResult(x, y, z, UPVItem->RoomNumber);
|
||||
int velocity = DISMOUNT_DISTANCE * phd_cos(UPVItem->Position.xRot);
|
||||
int x = UPVItem->Position.xPos + velocity * phd_sin(moveAngle);
|
||||
int z = UPVItem->Position.zPos + velocity * phd_cos(moveAngle);
|
||||
int y = UPVItem->Position.yPos - DISMOUNT_DISTANCE * phd_sin(-UPVItem->Position.xRot);
|
||||
|
||||
if (probe.Position.Floor < y ||
|
||||
(probe.Position.Floor - probe.Position.Ceiling) < STEP_SIZE ||
|
||||
auto probe = GetCollisionResult(x, y, z, UPVItem->RoomNumber);
|
||||
if ((probe.Position.Floor - probe.Position.Ceiling) < CLICK(1) ||
|
||||
probe.Position.Floor < y ||
|
||||
probe.Position.Ceiling > y ||
|
||||
probe.Position.Floor == NO_HEIGHT ||
|
||||
probe.Position.Ceiling == NO_HEIGHT)
|
||||
|
@ -338,97 +336,99 @@ static bool TestUPVMount(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
return false;
|
||||
}
|
||||
|
||||
int y = abs(laraItem->Position.yPos - (UPVItem->Position.yPos - STEP_SIZE / 2));
|
||||
int dist = pow(laraItem->Position.xPos - UPVItem->Position.xPos, 2) + pow(laraItem->Position.zPos - UPVItem->Position.zPos, 2);
|
||||
short rotDelta = abs(laraItem->Position.yRot - UPVItem->Position.yRot);
|
||||
|
||||
if (y > STEP_SIZE ||
|
||||
dist > pow(STEP_SIZE * 2, 2) ||
|
||||
rotDelta > ANGLE(35.0f) || rotDelta < -ANGLE(35.0f) ||
|
||||
GetCollisionResult(UPVItem).Position.Floor < -32000)
|
||||
{
|
||||
int y = abs(laraItem->Position.yPos - (UPVItem->Position.yPos - CLICK(0.5f)));
|
||||
if (y > CLICK(1))
|
||||
return false;
|
||||
|
||||
int distance = pow(laraItem->Position.xPos - UPVItem->Position.xPos, 2) + pow(laraItem->Position.zPos - UPVItem->Position.zPos, 2);
|
||||
if (distance > pow(CLICK(2), 2))
|
||||
return false;
|
||||
|
||||
short deltaAngle = abs(laraItem->Position.yRot - UPVItem->Position.yRot);
|
||||
if (deltaAngle > ANGLE(35.0f) || deltaAngle < -ANGLE(35.0f))
|
||||
return false;
|
||||
|
||||
if (GetCollisionResult(UPVItem).Position.Floor < -32000)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DoCurrent(ITEM_INFO* item)
|
||||
static void DoCurrent(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
|
||||
PHD_VECTOR target;
|
||||
|
||||
if (!Lara.Control.WaterCurrentActive)
|
||||
if (!lara->Control.WaterCurrentActive)
|
||||
{
|
||||
long shifter, absvel;
|
||||
|
||||
absvel = abs(Lara.ExtraVelocity.x);
|
||||
|
||||
if (absvel > 16)
|
||||
shifter = 4;
|
||||
else if (absvel > 8)
|
||||
shifter = 3;
|
||||
int absVel = abs(lara->ExtraVelocity.x);
|
||||
int shift;
|
||||
if (absVel > 16)
|
||||
shift = 4;
|
||||
else if (absVel > 8)
|
||||
shift = 3;
|
||||
else
|
||||
shifter = 2;
|
||||
shift = 2;
|
||||
|
||||
Lara.ExtraVelocity.x -= Lara.ExtraVelocity.x >> shifter;
|
||||
lara->ExtraVelocity.x -= lara->ExtraVelocity.x >> shift;
|
||||
|
||||
if (abs(Lara.ExtraVelocity.x) < 4)
|
||||
Lara.ExtraVelocity.x = 0;
|
||||
if (abs(lara->ExtraVelocity.x) < 4)
|
||||
lara->ExtraVelocity.x = 0;
|
||||
|
||||
absvel = abs(Lara.ExtraVelocity.z);
|
||||
if (absvel > 16)
|
||||
shifter = 4;
|
||||
else if (absvel > 8)
|
||||
shifter = 3;
|
||||
absVel = abs(lara->ExtraVelocity.z);
|
||||
if (absVel > 16)
|
||||
shift = 4;
|
||||
else if (absVel > 8)
|
||||
shift = 3;
|
||||
else
|
||||
shifter = 2;
|
||||
shift = 2;
|
||||
|
||||
Lara.ExtraVelocity.z -= Lara.ExtraVelocity.z >> shifter;
|
||||
if (abs(Lara.ExtraVelocity.z) < 4)
|
||||
Lara.ExtraVelocity.z = 0;
|
||||
lara->ExtraVelocity.z -= lara->ExtraVelocity.z >> shift;
|
||||
if (abs(lara->ExtraVelocity.z) < 4)
|
||||
lara->ExtraVelocity.z = 0;
|
||||
|
||||
if (Lara.ExtraVelocity.x == 0 && Lara.ExtraVelocity.z == 0)
|
||||
if (lara->ExtraVelocity.x == 0 && lara->ExtraVelocity.z == 0)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
long angle, dx, dz, speed, sinkval;
|
||||
int sinkVal = lara->Control.WaterCurrentActive - 1;
|
||||
target.x = g_Level.Sinks[sinkVal].x;
|
||||
target.y = g_Level.Sinks[sinkVal].y;
|
||||
target.z = g_Level.Sinks[sinkVal].z;
|
||||
|
||||
int angle = ((mGetAngle(target.x, target.z, laraItem->Position.xPos, laraItem->Position.zPos) - ANGLE(90.0f)) / 16) & 4095;
|
||||
|
||||
sinkval = Lara.Control.WaterCurrentActive - 1;
|
||||
target.x = g_Level.Sinks[sinkval].x;
|
||||
target.y = g_Level.Sinks[sinkval].y;
|
||||
target.z = g_Level.Sinks[sinkval].z;
|
||||
angle = ((mGetAngle(target.x, target.z, LaraItem->Position.xPos, LaraItem->Position.zPos) - ANGLE(90)) / 16) & 4095;
|
||||
int dx = target.x - laraItem->Position.xPos;
|
||||
int dz = target.z - laraItem->Position.zPos;
|
||||
|
||||
dx = target.x - LaraItem->Position.xPos;
|
||||
dz = target.z - LaraItem->Position.zPos;
|
||||
int velocity = g_Level.Sinks[sinkVal].strength;
|
||||
dx = phd_sin(angle * 16) * velocity * 1024;
|
||||
dz = phd_cos(angle * 16) * velocity * 1024;
|
||||
|
||||
speed = g_Level.Sinks[sinkval].strength;
|
||||
dx = phd_sin(angle * 16) * speed * 1024;
|
||||
dz = phd_cos(angle * 16) * speed * 1024;
|
||||
|
||||
Lara.ExtraVelocity.x += ((dx - Lara.ExtraVelocity.x) / 16);
|
||||
Lara.ExtraVelocity.z += ((dz - Lara.ExtraVelocity.z) / 16);
|
||||
lara->ExtraVelocity.x += ((dx - lara->ExtraVelocity.x) / 16);
|
||||
lara->ExtraVelocity.z += ((dz - lara->ExtraVelocity.z) / 16);
|
||||
}
|
||||
|
||||
item->Position.xPos += (Lara.ExtraVelocity.x / 256);
|
||||
item->Position.zPos += (Lara.ExtraVelocity.z / 256);
|
||||
Lara.Control.WaterCurrentActive = 0;
|
||||
lara->Control.WaterCurrentActive = 0;
|
||||
UPVItem->Position.xPos += lara->ExtraVelocity.x / CLICK(1);
|
||||
UPVItem->Position.zPos += lara->ExtraVelocity.z / CLICK(1);
|
||||
}
|
||||
|
||||
static void BackgroundCollision(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
UPVInfo* UPV = UPVItem->Data;
|
||||
auto* UPV = (UPVInfo*)UPVItem->Data;
|
||||
COLL_INFO cinfo, * coll = &cinfo; // ??
|
||||
|
||||
coll->Setup.LowerFloorBound = NO_LOWER_BOUND;
|
||||
coll->Setup.UpperFloorBound = -SUB_HEIGHT;
|
||||
coll->Setup.LowerCeilingBound = SUB_HEIGHT;
|
||||
coll->Setup.UpperFloorBound = -UPV_HEIGHT;
|
||||
coll->Setup.LowerCeilingBound = UPV_HEIGHT;
|
||||
coll->Setup.OldPosition.x = UPVItem->Position.xPos;
|
||||
coll->Setup.OldPosition.y = UPVItem->Position.yPos;
|
||||
coll->Setup.OldPosition.z = UPVItem->Position.zPos;
|
||||
coll->Setup.Radius = SUB_RADIUS;
|
||||
coll->Setup.Radius = UPV_RADIUS;
|
||||
coll->Setup.FloorSlopeIsWall = false;
|
||||
coll->Setup.FloorSlopeIsPit = false;
|
||||
coll->Setup.DeathFlagIsPit = false;
|
||||
|
@ -436,12 +436,18 @@ static void BackgroundCollision(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
coll->Setup.EnableObjectPush = true;
|
||||
coll->Setup.Mode = CollProbeMode::Quadrants;
|
||||
|
||||
if ((UPVItem->Position.xRot >= -16384) && (UPVItem->Position.xRot <= 16384))
|
||||
coll->Setup.ForwardAngle = lara->Control.MoveAngle = UPVItem->Position.yRot;
|
||||
if ((UPVItem->Position.xRot >= -(SHRT_MAX / 2 + 1)) && (UPVItem->Position.xRot <= (SHRT_MAX / 2 + 1)))
|
||||
{
|
||||
lara->Control.MoveAngle = UPVItem->Position.yRot;
|
||||
coll->Setup.ForwardAngle = lara->Control.MoveAngle;
|
||||
}
|
||||
else
|
||||
coll->Setup.ForwardAngle = lara->Control.MoveAngle = UPVItem->Position.yRot - ANGLE(180.0f);
|
||||
{
|
||||
lara->Control.MoveAngle = UPVItem->Position.yRot - ANGLE(180.0f);
|
||||
coll->Setup.ForwardAngle = lara->Control.MoveAngle;
|
||||
}
|
||||
|
||||
int height = phd_sin(UPVItem->Position.xRot) * SUB_LENGTH;
|
||||
int height = phd_sin(UPVItem->Position.xRot) * UPV_LENGTH;
|
||||
if (height < 0)
|
||||
height = -height;
|
||||
if (height < 200)
|
||||
|
@ -455,28 +461,28 @@ static void BackgroundCollision(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
|
||||
if (coll->CollisionType == CT_FRONT)
|
||||
{
|
||||
if (UPV->RotX > FRONT_TOLERANCE)
|
||||
UPV->RotX += WALLDEFLECT;
|
||||
else if (UPV->RotX < -FRONT_TOLERANCE)
|
||||
UPV->RotX -= WALLDEFLECT;
|
||||
if (UPV->XRot > FRONT_TOLERANCE)
|
||||
UPV->XRot += WALL_DEFLECT;
|
||||
else if (UPV->XRot < -FRONT_TOLERANCE)
|
||||
UPV->XRot -= WALL_DEFLECT;
|
||||
else
|
||||
{
|
||||
if (abs(UPV->Vel) >= MAX_VELOCITY)
|
||||
if (abs(UPV->Velocity) >= MAX_VELOCITY)
|
||||
{
|
||||
laraItem->TargetState = UPV_STATE_HIT;
|
||||
UPV->Vel = -UPV->Vel / 2;
|
||||
UPV->Velocity = -UPV->Velocity / 2;
|
||||
}
|
||||
else
|
||||
UPV->Vel = 0;
|
||||
UPV->Velocity = 0;
|
||||
}
|
||||
}
|
||||
else if (coll->CollisionType == CT_TOP)
|
||||
{
|
||||
if (UPV->RotX >= -TOP_TOLERANCE)
|
||||
UPV->RotX -= WALLDEFLECT;
|
||||
if (UPV->XRot >= -TOP_TOLERANCE)
|
||||
UPV->XRot -= WALL_DEFLECT;
|
||||
}
|
||||
else if (coll->CollisionType == CT_TOP_FRONT)
|
||||
UPV->Vel = 0;
|
||||
UPV->Velocity = 0;
|
||||
else if (coll->CollisionType == CT_LEFT)
|
||||
UPVItem->Position.yRot += ANGLE(5.0f);
|
||||
else if (coll->CollisionType == CT_RIGHT)
|
||||
|
@ -486,21 +492,21 @@ static void BackgroundCollision(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
UPVItem->Position.xPos = coll->Setup.OldPosition.x;
|
||||
UPVItem->Position.yPos = coll->Setup.OldPosition.y;
|
||||
UPVItem->Position.zPos = coll->Setup.OldPosition.z;
|
||||
UPV->Vel = 0;
|
||||
UPV->Velocity = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if (coll->Middle.Floor < 0)
|
||||
{
|
||||
UPVItem->Position.yPos += coll->Middle.Floor;
|
||||
UPV->RotX += WALLDEFLECT;
|
||||
UPV->XRot += WALL_DEFLECT;
|
||||
}
|
||||
}
|
||||
|
||||
static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
static void UPVControl(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
||||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
UPVInfo* UPV = UPVItem->Data;
|
||||
auto* UPV = (UPVInfo*)UPVItem->Data;
|
||||
|
||||
TestUPVDismount(laraItem, UPVItem);
|
||||
|
||||
|
@ -547,9 +553,9 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
else
|
||||
{
|
||||
if (TrInput & UPV_IN_UP)
|
||||
UPV->RotX -= UPDOWN_ACCEL;
|
||||
UPV->XRot -= UPDOWN_ACCEL;
|
||||
else if (TrInput & UPV_IN_DOWN)
|
||||
UPV->RotX += UPDOWN_ACCEL;
|
||||
UPV->XRot += UPDOWN_ACCEL;
|
||||
}
|
||||
|
||||
if (TrInput & UPV_IN_PROPEL)
|
||||
|
@ -561,7 +567,7 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
UPV->Flags |= UPV_DIVE;
|
||||
}
|
||||
|
||||
UPV->Vel += ACCELERATION;
|
||||
UPV->Velocity += ACCELERATION;
|
||||
}
|
||||
|
||||
else
|
||||
|
@ -605,19 +611,19 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
else
|
||||
{
|
||||
if (TrInput & UPV_IN_UP)
|
||||
UPV->RotX -= UPDOWN_ACCEL;
|
||||
UPV->XRot -= UPDOWN_ACCEL;
|
||||
else if (TrInput & UPV_IN_DOWN)
|
||||
UPV->RotX += UPDOWN_ACCEL;
|
||||
UPV->XRot += UPDOWN_ACCEL;
|
||||
}
|
||||
|
||||
if (TrInput & UPV_IN_DISMOUNT && TestUPVDismount(laraItem, UPVItem))
|
||||
{
|
||||
if (UPV->Vel > 0)
|
||||
UPV->Vel -= ACCELERATION;
|
||||
if (UPV->Velocity > 0)
|
||||
UPV->Velocity -= ACCELERATION;
|
||||
else
|
||||
{
|
||||
if (UPV->Flags & UPV_SURFACE)
|
||||
laraItem->TargetState = UPV_STATE_DISMOUNT_SURFACE;
|
||||
laraItem->TargetState = UPV_STATE_DISMOUNT_WATER_SURFACE;
|
||||
else
|
||||
laraItem->TargetState = UPV_STATE_DISMOUNT_UNDERWATER;
|
||||
|
||||
|
@ -631,8 +637,8 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
else if (TrInput & UPV_IN_PROPEL)
|
||||
{
|
||||
if (TrInput & UPV_IN_UP &&
|
||||
UPV->Flags & UPV_SURFACE &&
|
||||
UPVItem->Position.xRot > -DIVE_ANGLE)
|
||||
UPVItem->Position.xRot > -DIVE_ANGLE &&
|
||||
UPV->Flags & UPV_SURFACE)
|
||||
{
|
||||
UPV->Flags |= UPV_DIVE;
|
||||
}
|
||||
|
@ -670,15 +676,17 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
if (anim == UPV_ANIM_DISMOUNT_UNDERWATER && frame == DISMOUNT_UNDERWATER_FRAME)
|
||||
{
|
||||
UPV->Flags &= ~UPV_CONTROL;
|
||||
PHD_VECTOR vec = { 0, 0, 0 };
|
||||
GAME_VECTOR VPos, LPos;
|
||||
|
||||
PHD_VECTOR vec = { 0, 0, 0 };
|
||||
GetLaraJointPosition(&vec, LM_HIPS);
|
||||
|
||||
GAME_VECTOR LPos;
|
||||
LPos.x = vec.x;
|
||||
LPos.y = vec.y;
|
||||
LPos.z = vec.z;
|
||||
LPos.roomNumber = UPVItem->RoomNumber;
|
||||
|
||||
GAME_VECTOR VPos;
|
||||
VPos.x = UPVItem->Position.xPos;
|
||||
VPos.y = UPVItem->Position.yPos;
|
||||
VPos.z = UPVItem->Position.zPos;
|
||||
|
@ -705,12 +713,11 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
|
||||
break;
|
||||
|
||||
case UPV_STATE_DISMOUNT_SURFACE:
|
||||
case UPV_STATE_DISMOUNT_WATER_SURFACE:
|
||||
if (anim == UPV_ANIM_DISMOUNT_SURFACE && frame == DISMOUNT_SURFACE_FRAME)
|
||||
{
|
||||
UPV->Flags &= ~UPV_CONTROL;
|
||||
int waterDepth, waterHeight, heightFromWater;
|
||||
PHD_VECTOR vec = { 0, 0, 0 };
|
||||
|
||||
waterDepth = GetWaterSurface(laraItem);
|
||||
waterHeight = GetWaterHeight(laraItem);
|
||||
|
@ -720,6 +727,7 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
else
|
||||
heightFromWater = NO_HEIGHT;
|
||||
|
||||
PHD_VECTOR vec = { 0, 0, 0 };
|
||||
GetLaraJointPosition(&vec, LM_HIPS);
|
||||
|
||||
laraItem->Position.xPos = vec.x;
|
||||
|
@ -730,14 +738,15 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
SetAnimation(laraItem, LA_ONWATER_IDLE);
|
||||
laraItem->VerticalVelocity = 0;
|
||||
laraItem->Airborne = false;
|
||||
laraItem->Position.xRot = laraItem->Position.zRot = 0;
|
||||
laraItem->Position.xRot = 0;
|
||||
laraItem->Position.zRot = 0;
|
||||
|
||||
UpdateItemRoom(laraItem, -LARA_HEIGHT / 2);
|
||||
|
||||
ResetLaraFlex(laraItem);
|
||||
lara->Control.WaterStatus = WaterStatus::TreadWater;
|
||||
lara->WaterSurfaceDist = -heightFromWater;
|
||||
lara->Control.Count.Dive = 11;
|
||||
ResetLaraFlex(laraItem);
|
||||
lara->Control.HandStatus = HandStatus::Free;
|
||||
lara->Vehicle = NO_ITEM;
|
||||
|
||||
|
@ -745,7 +754,7 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
}
|
||||
else
|
||||
{
|
||||
UPV->RotX -= UPDOWN_ACCEL;
|
||||
UPV->XRot -= UPDOWN_ACCEL;
|
||||
if (UPVItem->Position.xRot < 0)
|
||||
UPVItem->Position.xRot = 0;
|
||||
}
|
||||
|
@ -756,7 +765,6 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
if (anim == UPV_ANIM_DEATH && (frame == DEATH_FRAME_1 || frame == DEATH_FRAME_2))
|
||||
{
|
||||
PHD_VECTOR vec = { 0, 0, 0 };
|
||||
|
||||
GetLaraJointPosition(&vec, LM_HIPS);
|
||||
|
||||
laraItem->Position.xPos = vec.x;
|
||||
|
@ -767,7 +775,7 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
|
||||
SetAnimation(UPVItem, LA_UNDERWATER_DEATH, 17);
|
||||
laraItem->VerticalVelocity = 0;
|
||||
laraItem->Airborne = 0;
|
||||
laraItem->Airborne = false;
|
||||
|
||||
UPV->Flags |= UPV_DEAD;
|
||||
}
|
||||
|
@ -784,23 +792,23 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
UPV->Flags &= ~UPV_DIVE;
|
||||
}
|
||||
|
||||
if (UPV->Vel > 0)
|
||||
if (UPV->Velocity > 0)
|
||||
{
|
||||
UPV->Vel -= FRICTION;
|
||||
if (UPV->Vel < 0)
|
||||
UPV->Vel = 0;
|
||||
UPV->Velocity -= FRICTION;
|
||||
if (UPV->Velocity < 0)
|
||||
UPV->Velocity = 0;
|
||||
}
|
||||
else if (UPV->Vel < 0)
|
||||
else if (UPV->Velocity < 0)
|
||||
{
|
||||
UPV->Vel += FRICTION;
|
||||
if (UPV->Vel > 0)
|
||||
UPV->Vel = 0;
|
||||
UPV->Velocity += FRICTION;
|
||||
if (UPV->Velocity > 0)
|
||||
UPV->Velocity = 0;
|
||||
}
|
||||
|
||||
if (UPV->Vel > MAX_VELOCITY)
|
||||
UPV->Vel = MAX_VELOCITY;
|
||||
else if (UPV->Vel < -MAX_VELOCITY)
|
||||
UPV->Vel = -MAX_VELOCITY;
|
||||
if (UPV->Velocity > MAX_VELOCITY)
|
||||
UPV->Velocity = MAX_VELOCITY;
|
||||
else if (UPV->Velocity < -MAX_VELOCITY)
|
||||
UPV->Velocity = -MAX_VELOCITY;
|
||||
|
||||
if (UPV->Rot > 0)
|
||||
{
|
||||
|
@ -815,17 +823,17 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
UPV->Rot = 0;
|
||||
}
|
||||
|
||||
if (UPV->RotX > 0)
|
||||
if (UPV->XRot > 0)
|
||||
{
|
||||
UPV->RotX -= UPDOWN_FRICTION;
|
||||
if (UPV->RotX < 0)
|
||||
UPV->RotX = 0;
|
||||
UPV->XRot -= UPDOWN_FRICTION;
|
||||
if (UPV->XRot < 0)
|
||||
UPV->XRot = 0;
|
||||
}
|
||||
else if (UPV->RotX < 0)
|
||||
else if (UPV->XRot < 0)
|
||||
{
|
||||
UPV->RotX += UPDOWN_FRICTION;
|
||||
if (UPV->RotX > 0)
|
||||
UPV->RotX = 0;
|
||||
UPV->XRot += UPDOWN_FRICTION;
|
||||
if (UPV->XRot > 0)
|
||||
UPV->XRot = 0;
|
||||
}
|
||||
|
||||
if (UPV->Rot > MAX_ROTATION)
|
||||
|
@ -833,54 +841,53 @@ static void UserInput(ITEM_INFO* laraItem, ITEM_INFO* UPVItem)
|
|||
else if (UPV->Rot < -MAX_ROTATION)
|
||||
UPV->Rot = -MAX_ROTATION;
|
||||
|
||||
if (UPV->RotX > MAX_UPDOWN)
|
||||
UPV->RotX = MAX_UPDOWN;
|
||||
else if (UPV->RotX < -MAX_UPDOWN)
|
||||
UPV->RotX = -MAX_UPDOWN;
|
||||
if (UPV->XRot > MAX_UPDOWN)
|
||||
UPV->XRot = MAX_UPDOWN;
|
||||
else if (UPV->XRot < -MAX_UPDOWN)
|
||||
UPV->XRot = -MAX_UPDOWN;
|
||||
}
|
||||
|
||||
void NoGetOnCollision(short itemNum, ITEM_INFO* laraitem, COLL_INFO* coll)
|
||||
void NoGetOnCollision(short itemNumber, ITEM_INFO* laraItem, COLL_INFO* coll)
|
||||
{
|
||||
ITEM_INFO* item = &g_Level.Items[itemNum];
|
||||
auto* item = &g_Level.Items[itemNumber];
|
||||
|
||||
if (!TestBoundsCollide(item, laraitem, coll->Setup.Radius))
|
||||
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||
return;
|
||||
if (!TestCollision(item, laraitem))
|
||||
if (!TestCollision(item, laraItem))
|
||||
return;
|
||||
|
||||
ItemPushItem(item, laraitem, coll, 0, 0);
|
||||
ItemPushItem(item, laraItem, coll, 0, 0);
|
||||
}
|
||||
|
||||
void SubCollision(short itemNum, ITEM_INFO* laraItem, COLL_INFO* coll)
|
||||
void UPVCollision(short itemNumber, ITEM_INFO* laraItem, COLL_INFO* coll)
|
||||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
auto* UPVItem = &g_Level.Items[itemNumber];
|
||||
|
||||
if (laraItem->HitPoints <= 0 || lara->Vehicle != NO_ITEM)
|
||||
return;
|
||||
|
||||
ITEM_INFO* UPVItem = &g_Level.Items[itemNum];
|
||||
|
||||
if (TestUPVMount(laraItem, UPVItem))
|
||||
{
|
||||
lara->Vehicle = itemNum;
|
||||
lara->Vehicle = itemNumber;
|
||||
lara->Control.WaterStatus = WaterStatus::Dry;
|
||||
|
||||
if (lara->Control.WeaponControl.GunType == WEAPON_FLARE)
|
||||
{
|
||||
CreateFlare(LaraItem, ID_FLARE_ITEM, 0);
|
||||
CreateFlare(laraItem, ID_FLARE_ITEM, 0);
|
||||
UndrawFlareMeshes(laraItem);
|
||||
|
||||
lara->Flare.ControlLeft = false;
|
||||
lara->Control.WeaponControl.RequestGunType = lara->Control.WeaponControl.GunType = WEAPON_NONE;
|
||||
}
|
||||
|
||||
lara->Control.HandStatus = HandStatus::Busy;
|
||||
laraItem->Position.xPos = UPVItem->Position.xPos;
|
||||
laraItem->Position.yPos = UPVItem->Position.yPos;
|
||||
laraItem->Position.zPos = UPVItem->Position.zPos;
|
||||
laraItem->Position.xRot = UPVItem->Position.xRot;
|
||||
laraItem->Position.yRot = UPVItem->Position.yRot;
|
||||
laraItem->Position.zRot = UPVItem->Position.zRot;
|
||||
lara->Control.HandStatus = HandStatus::Busy;
|
||||
UPVItem->HitPoints = 1;
|
||||
|
||||
if (laraItem->ActiveState == LS_ONWATER_STOP || laraItem->ActiveState == LS_ONWATER_FORWARD)
|
||||
|
@ -893,36 +900,36 @@ void SubCollision(short itemNum, ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
laraItem->AnimNumber = Objects[ID_UPV_LARA_ANIMS].animIndex + UPV_ANIM_MOUNT_UNDERWATER;
|
||||
laraItem->ActiveState = laraItem->TargetState = UPV_STATE_MOUNT;
|
||||
}
|
||||
laraItem->FrameNumber = g_Level.Anims[laraItem->AnimNumber].frameBase;
|
||||
|
||||
laraItem->FrameNumber = g_Level.Anims[laraItem->AnimNumber].frameBase;
|
||||
AnimateItem(laraItem);
|
||||
}
|
||||
else
|
||||
{
|
||||
UPVItem->Position.yPos += SUB_DRAW_SHIFT;
|
||||
NoGetOnCollision(itemNum, laraItem, coll);
|
||||
UPVItem->Position.yPos -= SUB_DRAW_SHIFT;
|
||||
UPVItem->Position.yPos += UPV_DRAW_SHIFT;
|
||||
NoGetOnCollision(itemNumber, laraItem, coll);
|
||||
UPVItem->Position.yPos -= UPV_DRAW_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
||||
bool UPVControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
||||
{
|
||||
auto* lara = GetLaraInfo(laraItem);
|
||||
ITEM_INFO* UPVItem = &g_Level.Items[lara->Vehicle];
|
||||
UPVInfo* UPV = UPVItem->Data;
|
||||
auto* UPVItem = &g_Level.Items[lara->Vehicle];
|
||||
auto* UPV = (UPVInfo*)UPVItem->Data;
|
||||
|
||||
auto oldPos = UPVItem->Position;
|
||||
auto probe = GetCollisionResult(UPVItem);
|
||||
|
||||
if (!(UPV->Flags & UPV_DEAD))
|
||||
{
|
||||
UserInput(laraItem, UPVItem);
|
||||
UPVControl(laraItem, UPVItem);
|
||||
|
||||
UPVItem->VerticalVelocity = UPV->Vel / 65536;
|
||||
UPVItem->VerticalVelocity = UPV->Velocity / (USHRT_MAX + 1);
|
||||
|
||||
UPVItem->Position.xRot += UPV->RotX / 65536;
|
||||
UPVItem->Position.yRot += UPV->Rot / 65536;
|
||||
UPVItem->Position.zRot = UPV->Rot / 65536;
|
||||
UPVItem->Position.xRot += UPV->XRot / (USHRT_MAX + 1);
|
||||
UPVItem->Position.yRot += UPV->Rot / (USHRT_MAX + 1);
|
||||
UPVItem->Position.zRot = UPV->Rot / (USHRT_MAX + 1);
|
||||
|
||||
if (UPVItem->Position.xRot > UPDOWN_LIMIT)
|
||||
UPVItem->Position.xRot = UPDOWN_LIMIT;
|
||||
|
@ -937,7 +944,7 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
int newHeight = GetCollisionResult(UPVItem).Position.Floor;
|
||||
int waterHeight = GetWaterHeight(UPVItem);
|
||||
|
||||
if ((newHeight - waterHeight) < SUB_HEIGHT || (newHeight < UPVItem->Position.yPos - SUB_HEIGHT / 2))
|
||||
if ((newHeight - waterHeight) < UPV_HEIGHT || (newHeight < UPVItem->Position.yPos - UPV_HEIGHT / 2))
|
||||
{
|
||||
UPVItem->Position.xPos = oldPos.xPos;
|
||||
UPVItem->Position.yPos = oldPos.yPos;
|
||||
|
@ -949,7 +956,7 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
|
||||
if (UPV->Flags & UPV_CONTROL && !(UPV->Flags & UPV_DEAD))
|
||||
{
|
||||
if (!(g_Level.Rooms[UPVItem->RoomNumber].flags & ENV_FLAG_WATER) &&
|
||||
if (!TestEnvironment(ENV_FLAG_WATER, UPVItem->RoomNumber) &&
|
||||
waterHeight != NO_HEIGHT)
|
||||
{
|
||||
if ((waterHeight - UPVItem->Position.yPos) >= -SURFACE_DIST)
|
||||
|
@ -957,7 +964,7 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
|
||||
if (!(UPV->Flags & UPV_SURFACE))
|
||||
{
|
||||
SoundEffect(SFX_TR4_LARA_BREATH, &LaraItem->Position, 2);
|
||||
SoundEffect(SFX_TR4_LARA_BREATH, &laraItem->Position, 2);
|
||||
UPV->Flags &= ~UPV_DIVE;
|
||||
}
|
||||
|
||||
|
@ -970,7 +977,7 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
|
||||
if (!(UPV->Flags & UPV_SURFACE))
|
||||
{
|
||||
SoundEffect(SFX_TR4_LARA_BREATH, &LaraItem->Position, 2);
|
||||
SoundEffect(SFX_TR4_LARA_BREATH, &laraItem->Position, 2);
|
||||
UPV->Flags &= ~UPV_DIVE;
|
||||
}
|
||||
|
||||
|
@ -985,7 +992,6 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
if (laraItem->HitPoints > 0)
|
||||
{
|
||||
lara->Air--;
|
||||
|
||||
if (lara->Air < 0)
|
||||
{
|
||||
lara->Air = -1;
|
||||
|
@ -998,31 +1004,30 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
if (laraItem->HitPoints >= 0)
|
||||
{
|
||||
lara->Air += 10;
|
||||
|
||||
if (lara->Air > 1800)
|
||||
lara->Air = 1800;
|
||||
if (lara->Air > LARA_AIR_MAX)
|
||||
lara->Air = LARA_AIR_MAX;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
TestTriggers(UPVItem, false);
|
||||
SubEffects(lara->Vehicle);
|
||||
UPVEffects(lara->Vehicle);
|
||||
|
||||
if (!(UPV->Flags & UPV_DEAD) &&
|
||||
lara->Vehicle != NO_ITEM)
|
||||
{
|
||||
DoCurrent(UPVItem);
|
||||
DoCurrent(laraItem, UPVItem);
|
||||
|
||||
if (TrInput & UPV_IN_FIRE &&
|
||||
UPV->Flags & UPV_CONTROL &&
|
||||
!UPV->WeaponTimer)
|
||||
!UPV->HarpoonTimer)
|
||||
{
|
||||
if (laraItem->ActiveState != UPV_STATE_DISMOUNT_UNDERWATER &&
|
||||
laraItem->ActiveState != UPV_STATE_DISMOUNT_SURFACE &&
|
||||
laraItem->ActiveState != UPV_STATE_DISMOUNT_WATER_SURFACE &&
|
||||
laraItem->ActiveState != UPV_STATE_MOUNT)
|
||||
{
|
||||
FireSubHarpoon(laraItem, UPVItem);
|
||||
UPV->WeaponTimer = HARPOON_RELOAD;
|
||||
FireUPVHarpoon(laraItem, UPVItem);
|
||||
UPV->HarpoonTimer = HARPOON_RELOAD;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1043,7 +1048,7 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
BackgroundCollision(laraItem, UPVItem);
|
||||
|
||||
if (UPV->Flags & UPV_CONTROL)
|
||||
SoundEffect(SFX_TR3_LITTLE_SUB_LOOP, (PHD_3DPOS*)&UPVItem->Position.xPos, 2 | 4 | 0x1000000 | (UPVItem->VerticalVelocity * 65536));
|
||||
SoundEffect(SFX_TR3_LITTLE_SUB_LOOP, (PHD_3DPOS*)&UPVItem->Position.xPos, 2 | 4 | 0x1000000 | (UPVItem->VerticalVelocity * (USHRT_MAX + 1)));
|
||||
|
||||
UPVItem->AnimNumber = Objects[ID_UPV].animIndex + (laraItem->AnimNumber - Objects[ID_UPV_LARA_ANIMS].animIndex);
|
||||
UPVItem->FrameNumber = g_Level.Anims[UPVItem->AnimNumber].frameBase + (laraItem->FrameNumber - g_Level.Anims[laraItem->AnimNumber].frameBase);
|
||||
|
@ -1064,11 +1069,10 @@ bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll)
|
|||
|
||||
BackgroundCollision(laraItem, UPVItem);
|
||||
|
||||
UPV->RotX = 0;
|
||||
UPV->XRot = 0;
|
||||
|
||||
SetAnimation(UPVItem, UPV_ANIM_IDLE);
|
||||
UPVItem->VerticalVelocity = 0;
|
||||
UPVItem->VerticalVelocity = 0;
|
||||
UPVItem->Airborne = true;
|
||||
AnimateItem(UPVItem);
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "Game/items.h"
|
||||
#include "Game/collision/collide_room.h"
|
||||
|
||||
void UPVInitialise(short itemNum);
|
||||
void SubCollision(short itemNum, ITEM_INFO* laraItem, COLL_INFO* coll);
|
||||
void SubEffects(short itemNum);
|
||||
bool SubControl(ITEM_INFO* laraItem, COLL_INFO* coll);
|
||||
void UPVInitialise(short itemNumber);
|
||||
void UPVCollision(short itemNumber, ITEM_INFO* laraItem, COLL_INFO* coll);
|
||||
void UPVEffects(short itemNumber);
|
||||
bool UPVControl(ITEM_INFO* laraItem, COLL_INFO* coll);
|
||||
|
|
|
@ -2,10 +2,12 @@
|
|||
|
||||
struct UPVInfo
|
||||
{
|
||||
int Vel;
|
||||
int Velocity;
|
||||
int Rot;
|
||||
int RotX;
|
||||
int XRot;
|
||||
short FanRot;
|
||||
unsigned int HarpoonTimer;
|
||||
bool HarpoonLeft;
|
||||
|
||||
char Flags;
|
||||
char WeaponTimer;
|
||||
};
|
||||
|
|
|
@ -445,8 +445,8 @@ static void StartVehicles(OBJECT_INFO* obj)
|
|||
if (obj->loaded)
|
||||
{
|
||||
obj->initialise = UPVInitialise;
|
||||
obj->control = SubEffects;
|
||||
obj->collision = SubCollision;
|
||||
obj->control = UPVEffects;
|
||||
obj->collision = UPVCollision;
|
||||
// obj->drawRoutine = SubDraw;
|
||||
obj->hitEffect = HIT_RICOCHET;
|
||||
obj->saveAnim = true;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue