2020-05-27 09:21:20 +02:00
|
|
|
#include "framework.h"
|
2021-12-24 03:32:19 +03:00
|
|
|
#include "Objects/TR3/Vehicles/minecart.h"
|
2021-12-24 11:08:16 +03:00
|
|
|
|
|
|
|
#include "Game/animation.h"
|
|
|
|
#include "Game/camera.h"
|
|
|
|
#include "Game/collision/sphere.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Game/collision/collide_item.h"
|
|
|
|
#include "Game/effects/effects.h"
|
|
|
|
#include "Game/items.h"
|
2021-12-24 11:08:16 +03:00
|
|
|
#include "Game/Lara/lara.h"
|
|
|
|
#include "Game/Lara/lara_flare.h"
|
2022-02-23 22:15:51 +11:00
|
|
|
#include "Game/Lara/lara_helpers.h"
|
2021-12-24 11:08:16 +03:00
|
|
|
#include "Objects/TR3/Vehicles/minecart_info.h"
|
|
|
|
#include "Sound/sound.h"
|
|
|
|
#include "Specific/input.h"
|
2021-12-22 16:23:57 +03:00
|
|
|
#include "Specific/level.h"
|
|
|
|
#include "Specific/setup.h"
|
2021-09-25 11:27:47 +02:00
|
|
|
|
2020-06-20 23:39:08 +02:00
|
|
|
using std::vector;
|
2021-08-26 15:54:52 +03:00
|
|
|
|
2022-01-09 13:44:37 +11:00
|
|
|
enum MinecartState
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
CART_STATE_MOUNT,
|
|
|
|
CART_STATE_DISMOUNT,
|
|
|
|
CART_STATE_DISMOUNT_LEFT,
|
|
|
|
CART_STATE_DISMOUNT_RIGHT,
|
|
|
|
CART_STATE_IDLE,
|
|
|
|
CART_STATE_DUCK,
|
|
|
|
CART_STATE_MOVE,
|
|
|
|
CART_STATE_RIGHT,
|
|
|
|
CART_STATE_HARD_LEFT, // Unused.
|
|
|
|
CART_STATE_LEFT,
|
|
|
|
CART_STATE_HARD_RIGHT, // Unused.
|
|
|
|
CART_STATE_BRAKE,
|
|
|
|
CART_STATE_FORWARD,
|
|
|
|
CART_STATE_BACK,
|
|
|
|
CART_TURN_DEATH,
|
|
|
|
CART_FALL_DEATH,
|
|
|
|
CART_WALL_DEATH,
|
|
|
|
CART_STATE_HIT,
|
2022-02-23 22:15:51 +11:00
|
|
|
CART_STATE_SWIPE,
|
2022-02-23 14:40:08 +11:00
|
|
|
CART_STATE_BRAKING
|
2019-11-30 13:51:37 +01:00
|
|
|
};
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
enum MinecartAnim
|
|
|
|
{
|
|
|
|
CART_ANIM_MOUNT_LEFT = 0,
|
|
|
|
CART_ANIM_DISMOUNT_LEFT = 1,
|
|
|
|
CART_ANIM_DUCK_START = 2,
|
|
|
|
CART_ANIM_DUCK_CONTINUE = 3,
|
|
|
|
CART_ANIM_DUCK_END = 4,
|
|
|
|
CART_ANIM_PICK_UP_WRENCH = 5,
|
|
|
|
CART_ANIM_SWIPE_WRENCH = 6,
|
|
|
|
CART_ANIM_PUT_DOWN_WRENCH = 7,
|
|
|
|
CART_ANIM_LEAN_LEFT_START = 8,
|
|
|
|
CART_ANIM_LEAN_RIGHT_CONTINUE = 9,
|
|
|
|
CART_ANIM_BRAKE_DISENGAGE = 10, // Unused?
|
|
|
|
CART_ANIM_BRAKE_ENGAGE = 11, // Unused?
|
|
|
|
CART_ANIM_LEAN_RIGHT_START = 12,
|
|
|
|
CART_ANIM_LEAN_LEFT_CONTINUE = 13,
|
|
|
|
CART_ANIM_LEAN_RIGHT_BRAKE_ENGAGE = 14,
|
|
|
|
CART_ANIM_LEAN_LEFT_BRAKE_ENGAGE = 15,
|
|
|
|
CART_ANIM_LEAN_RIGHT_HARD_CONTINUE = 16, // Unused?
|
|
|
|
CART_ANIM_LEAN_LEFT_HARD_CONTINUE = 17, // Unused?
|
|
|
|
CART_ANIM_LEAN_RIGHT_HARD_START = 18, // Unused?
|
|
|
|
CART_ANIM_LEAN_RIGHT_HARD_END = 19, // Unused?
|
|
|
|
CART_ANIM_LEAN_LEFT_HARD_START = 20, // Unused?
|
|
|
|
CART_ANIM_LEAN_LEFT_HARD_END = 21, // Unused?
|
|
|
|
CART_ANIM_RIDE_FORWARD = 22,
|
|
|
|
CART_ANIM_WALL_DEATH = 23,
|
|
|
|
CART_ANIM_LEAN_FORWARD_START = 24,
|
|
|
|
CART_ANIM_LEAN_FORWARD_CONTINUE = 25,
|
|
|
|
CART_ANIM_LEAN_FORWARD_END = 26,
|
|
|
|
CART_ANIM_LEAN_BACK_START = 27,
|
|
|
|
CART_ANIM_LEAN_BACK_CONTINUE = 28,
|
|
|
|
CART_ANIM_LEAN_BACK_END = 29,
|
|
|
|
CART_ANIM_FALL_DEATH = 30, // Unused?
|
|
|
|
CART_ANIM_TURN_DEATH = 31, // Unused?
|
|
|
|
CART_ANIM_FALL_OUT_START = 32,
|
|
|
|
CART_ANIM_FALL_OUT_END = 33,
|
|
|
|
CART_ANIM_BONK_HEAD = 34,
|
|
|
|
CART_ANIM_LEAN_FORWARD_DUCK_START = 35,
|
|
|
|
CART_ANIM_LEAN_FORWARD_DUCK_CONTINUE = 36,
|
|
|
|
CART_ANIM_LEAN_FORWARD_DUCK_END = 37,
|
|
|
|
CART_ANIM_LEAN_BACK_DUCK_START = 38,
|
|
|
|
CART_ANIM_LEAN_BACK_DUCK_CONTINUE = 39,
|
|
|
|
CART_ANIM_LEAN_BACK_DUCK_END = 40,
|
|
|
|
CART_ANIM_LEAN_RIGHT_BRAKE_DISENGAGE = 41, // Unused?
|
|
|
|
CART_ANIM_LEAN_LEFT_BRAKE_DISENGAGE = 42, // Unused?
|
|
|
|
CART_ANIM_LEAN_RIGHT_END = 43,
|
|
|
|
CART_ANIM_LEAN_LEFT_END = 44,
|
|
|
|
CART_ANIM_IDLE = 45,
|
|
|
|
CART_ANIM_MOUNT_RIGHT = 46,
|
|
|
|
CART_ANIM_DISMOUNT_RIGHT = 47,
|
|
|
|
CART_ANIM_BRAKE = 48,
|
|
|
|
};
|
|
|
|
|
2022-02-20 00:43:58 +11:00
|
|
|
enum MinecartFlags
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-20 00:43:58 +11:00
|
|
|
CART_FLAG_MESH = 1,
|
2022-02-23 14:40:08 +11:00
|
|
|
CART_FLAG_TURNING_LEFT = 2,
|
|
|
|
CART_FLAG_TURNING_RIGHT = 4,
|
2022-02-23 22:15:51 +11:00
|
|
|
CART_FLAG_RDIR = 8, // TODO
|
2022-02-20 00:43:58 +11:00
|
|
|
CART_FLAG_CONTROL = 16,
|
|
|
|
CART_FLAG_STOPPED = 32,
|
2022-02-23 14:40:08 +11:00
|
|
|
CART_FLAG_NO_ANIM = 64,
|
2022-02-20 00:43:58 +11:00
|
|
|
CART_FLAG_DEAD = 128
|
2019-11-30 13:51:37 +01:00
|
|
|
};
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
#define DISMOUNT_DISTANCE 330
|
2019-11-30 13:51:37 +01:00
|
|
|
#define CART_DEC -1536
|
|
|
|
#define CART_MIN_SPEED 2560
|
|
|
|
#define CART_MIN_VEL 32
|
|
|
|
#define TURN_DEATH_VEL 128
|
2022-02-23 14:40:08 +11:00
|
|
|
#define CART_FORWARD_GRADIENT -128
|
|
|
|
#define CART_BACK_GRADIENT 128
|
|
|
|
#define CART_JUMP_VELOCITY 64512
|
|
|
|
#define CART_GRAVITY (SECTOR(1) + 1)
|
2022-02-23 22:15:51 +11:00
|
|
|
#define CART_MAX_VERTICAL_VELOCITY 16128
|
2022-02-23 14:40:08 +11:00
|
|
|
#define TERMINAL_ANGLE SECTOR(4)
|
2019-11-30 13:51:37 +01:00
|
|
|
#define CART_RADIUS 100
|
2022-02-23 14:40:08 +11:00
|
|
|
#define CART_HEIGHT CLICK(3)
|
2019-11-30 13:51:37 +01:00
|
|
|
#define CART_NHITS 25
|
2022-02-23 14:40:08 +11:00
|
|
|
#define CART_ENTITY_RADIUS CLICK(1)
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
#define CART_IN_SWIPE IN_ACTION
|
2022-02-23 14:40:08 +11:00
|
|
|
#define CART_IN_DUCK IN_CROUCH
|
2022-02-23 22:15:51 +11:00
|
|
|
#define CART_IN_DISMOUNT IN_ROLL
|
2022-02-23 14:40:08 +11:00
|
|
|
#define CART_IN_BRAKE (IN_BACK | IN_JUMP)
|
|
|
|
#define CART_IN_LEFT IN_LEFT
|
|
|
|
#define CART_IN_RIGHT IN_RIGHT
|
|
|
|
|
|
|
|
void InitialiseMineCart(short itemNumber)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
auto* cartItem = &g_Level.Items[itemNumber];
|
|
|
|
cartItem->Data = MinecartInfo();
|
|
|
|
auto* cartInfo = (MinecartInfo*)cartItem->Data;
|
|
|
|
|
|
|
|
cartInfo->Velocity = 0;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->VerticalVelocity = 0;
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Gradient = 0;
|
|
|
|
cartInfo->Flags = NULL;
|
|
|
|
}
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
static int TestMinecartHeight(ITEM_INFO* cartItem, int xOffset, int zOffset)
|
|
|
|
{
|
|
|
|
float s = phd_sin(cartItem->Position.yRot);
|
2022-02-23 22:15:51 +11:00
|
|
|
float c = phd_cos(cartItem->Position.yRot);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
PHD_VECTOR pos;
|
|
|
|
pos.x = cartItem->Position.xPos + zOffset * s + xOffset * c;
|
|
|
|
pos.y = cartItem->Position.yPos - zOffset * phd_sin(cartItem->Position.xRot) + xOffset * phd_sin(cartItem->Position.zRot);
|
|
|
|
pos.z = cartItem->Position.zPos + zOffset * c - xOffset * s;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
return GetCollisionResult(pos.x, pos.y, pos.z, cartItem->RoomNumber).Position.Floor;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
static short GetMinecartCollision(ITEM_INFO* cartItem, short angle, int distance)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
auto probe = GetCollisionResult(cartItem, angle, distance, -LARA_HEIGHT);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (probe.Position.Floor != NO_HEIGHT)
|
|
|
|
probe.Position.Floor -= cartItem->Position.yPos;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
return (short)probe.Position.Floor;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
static bool GetInMineCart(ITEM_INFO* cartItem, ITEM_INFO* laraItem, COLL_INFO* coll)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
auto* laraInfo = GetLaraInfo(laraItem);
|
|
|
|
|
|
|
|
if (!(TrInput & CART_IN_SWIPE) || laraInfo->Control.HandStatus != HandStatus::Free ||
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->Airborne)
|
|
|
|
{
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
2022-02-23 14:40:08 +11:00
|
|
|
}
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (!TestBoundsCollide(cartItem, laraItem, coll->Setup.Radius))
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (!TestCollision(cartItem, laraItem))
|
|
|
|
return false;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
int x = laraItem->Position.xPos - cartItem->Position.xPos;
|
|
|
|
int z = laraItem->Position.zPos - cartItem->Position.zPos;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
int distance = pow(x, 2) + pow(z, 2);
|
|
|
|
if (distance > pow(CLICK(2), 2))
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (GetCollisionResult(cartItem).Position.Floor < -32000)
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
static bool TestMinecartDismount(ITEM_INFO* laraItem, int direction)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
auto* laraInfo = GetLaraInfo(laraItem);
|
|
|
|
auto* cartItem = &g_Level.Items[laraInfo->Vehicle];
|
|
|
|
|
2021-08-24 16:54:26 +03:00
|
|
|
short angle;
|
2019-11-30 13:51:37 +01:00
|
|
|
if (direction < 0)
|
2022-02-23 22:15:51 +11:00
|
|
|
angle = cartItem->Position.yRot + ANGLE(90.0f);
|
2019-11-30 13:51:37 +01:00
|
|
|
else
|
2022-02-23 22:15:51 +11:00
|
|
|
angle = cartItem->Position.yRot - ANGLE(90.0f);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
auto probe = GetCollisionResult(cartItem, angle, -DISMOUNT_DISTANCE);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (probe.Position.FloorSlope || probe.Position.Floor == NO_HEIGHT)
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (abs(probe.Position.Floor - cartItem->Position.yPos) > CLICK(2))
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if ((probe.Position.Ceiling - cartItem->Position.yPos) > -LARA_HEIGHT ||
|
|
|
|
(probe.Position.Floor - probe.Position.Ceiling) < LARA_HEIGHT)
|
|
|
|
{
|
2019-11-30 13:51:37 +01:00
|
|
|
return false;
|
2022-02-23 22:15:51 +11:00
|
|
|
}
|
2019-11-30 13:51:37 +01:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
static void CartToEntityCollision(ITEM_INFO* laraItem, ITEM_INFO* cartItem)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
|
|
|
vector<short> roomsList;
|
2022-02-23 14:40:08 +11:00
|
|
|
roomsList.push_back(cartItem->RoomNumber);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
auto* room = &g_Level.Rooms[cartItem->RoomNumber];
|
2020-06-26 07:06:18 +02:00
|
|
|
for (int i = 0; i < room->doors.size(); i++)
|
|
|
|
roomsList.push_back(room->doors[i].room);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
|
|
|
for (int i = 0; i < roomsList.size(); i++)
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
short itemNumber = g_Level.Rooms[roomsList[i]].itemNumber;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
while (itemNumber != NO_ITEM)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
auto* item = &g_Level.Items[itemNumber];
|
2022-02-23 22:15:51 +11:00
|
|
|
if (item->Collidable &&
|
|
|
|
item->Status != ITEM_INVISIBLE &&
|
|
|
|
item != laraItem && item != cartItem)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
auto* object = &Objects[item->ObjectNumber];
|
2022-02-23 22:15:51 +11:00
|
|
|
if (object->collision &&
|
|
|
|
(object->intelligent || item->ObjectNumber == ID_ROLLINGBALL || item->ObjectNumber == ID_ANIMATING2))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
int x = cartItem->Position.xPos - item->Position.xPos;
|
|
|
|
int y = cartItem->Position.yPos - item->Position.yPos;
|
|
|
|
int z = cartItem->Position.zPos - item->Position.zPos;
|
|
|
|
if (x > -2048 && x < 2048 &&
|
|
|
|
y > -2048 && y < 2048 &&
|
|
|
|
z > -2048 && z < 2048)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TestBoundsCollide(item, laraItem, CART_ENTITY_RADIUS))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
if (item->ObjectNumber == ID_ANIMATING2)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (item->FrameNumber == g_Level.Anims[item->AnimNumber].frameBase &&
|
2022-02-23 22:15:51 +11:00
|
|
|
(laraItem->ActiveState == CART_STATE_SWIPE &&
|
|
|
|
laraItem->AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 6))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
int frame = laraItem->FrameNumber - g_Level.Anims[laraItem->AnimNumber].frameBase;
|
2022-02-23 14:40:08 +11:00
|
|
|
if (frame >= 12 && frame <= 22)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-09 16:55:46 +11:00
|
|
|
SoundEffect(220, &item->Position, 2);
|
2021-09-15 16:58:53 +03:00
|
|
|
TestTriggers(item, true);
|
2022-02-09 16:55:46 +11:00
|
|
|
item->FrameNumber++;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-02-09 16:55:46 +11:00
|
|
|
else if (item->ObjectNumber == ID_ROLLINGBALL)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2021-03-24 12:49:36 -05:00
|
|
|
/*code, kill lara and stop both the boulder and the minecart*/
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
DoLotsOfBlood(item->Position.xPos, cartItem->Position.yPos - CLICK(1), item->Position.zPos, GetRandomControl() & 3, cartItem->Position.yRot, item->RoomNumber, 3);
|
2022-02-09 16:55:46 +11:00
|
|
|
item->HitPoints = 0;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
|
|
|
itemNumber = item->NextItem;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
static void MoveCart(ITEM_INFO* laraItem, ITEM_INFO* cartItem)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
auto* laraInfo = GetLaraInfo(laraItem);
|
|
|
|
auto* cartInfo = (MinecartInfo*)cartItem->Data;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->StopDelay)
|
|
|
|
cartInfo->StopDelay--;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if ((laraInfo->mineL && laraInfo->mineR && !cartInfo->StopDelay) &&
|
2022-02-23 14:40:08 +11:00
|
|
|
(cartItem->Position.xPos & 0x380 == 512 ||
|
|
|
|
cartItem->Position.zRot & 0x380 == 512))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Velocity < 0xf000)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Velocity = 0;
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Velocity = 0;
|
|
|
|
cartInfo->Flags |= CART_FLAG_STOPPED | CART_FLAG_CONTROL;
|
2019-11-30 13:51:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->StopDelay = 16;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if ((laraInfo->mineL || laraInfo->mineR) &&
|
|
|
|
!(laraInfo->mineL && laraInfo->mineR) &&
|
2022-02-23 14:40:08 +11:00
|
|
|
!cartInfo->StopDelay &&
|
|
|
|
!(cartInfo->Flags & (CART_FLAG_TURNING_LEFT | CART_FLAG_TURNING_RIGHT)))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
short angle;
|
2022-02-23 22:15:51 +11:00
|
|
|
unsigned short rotation = (((unsigned short)cartItem->Position.yRot) / ANGLE(90.0f)) | (laraInfo->mineL * 4);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
switch (rotation)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = (cartItem->Position.xPos + 4096) & ~1023;
|
|
|
|
cartInfo->TurnZ = cartItem->Position.zPos & ~1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 1:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = cartItem->Position.xPos & ~1023;
|
|
|
|
cartInfo->TurnZ = (cartItem->Position.zPos - 4096) | 1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 2:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = (cartItem->Position.xPos - 4096) | 1023;
|
|
|
|
cartInfo->TurnZ = cartItem->Position.zPos | 1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 3:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = cartItem->Position.xPos | 1023;
|
|
|
|
cartInfo->TurnZ = (cartItem->Position.zPos + 4096) & ~1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = (cartItem->Position.xPos - 4096) | 1023;
|
|
|
|
cartInfo->TurnZ = cartItem->Position.zPos & ~1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 5:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = cartItem->Position.xPos & ~1023;
|
|
|
|
cartInfo->TurnZ = (cartItem->Position.zPos + 4096) & ~1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 6:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = (cartItem->Position.xPos + 4096) & ~1023;
|
|
|
|
cartInfo->TurnZ = cartItem->Position.zPos | 1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 7:
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnX = cartItem->Position.xPos | 1023;
|
|
|
|
cartInfo->TurnZ = (cartItem->Position.zPos - 4096) | 1023;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
angle = mGetAngle(cartItem->Position.xPos, cartItem->Position.zPos, cartInfo->TurnX, cartInfo->TurnZ) & 0x3fff;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (rotation < 4)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnRot = cartItem->Position.yRot;
|
|
|
|
cartInfo->TurnLen = angle;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnRot = cartItem->Position.yRot;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (angle)
|
2022-02-23 22:15:51 +11:00
|
|
|
angle = ANGLE(90.0f) - angle;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->TurnLen = angle;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->Flags |= (laraInfo->mineL) ? CART_FLAG_TURNING_LEFT : CART_FLAG_TURNING_RIGHT;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Velocity < CART_MIN_SPEED)
|
|
|
|
cartInfo->Velocity = CART_MIN_SPEED;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Velocity += -cartInfo->Gradient * 4;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->Velocity /= 256; // TODO: Then why use the huge values in the first place??
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartItem->Velocity < CART_MIN_VEL)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Velocity = CART_MIN_VEL;
|
2019-11-30 13:51:37 +01:00
|
|
|
StopSoundEffect(209);
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (cartInfo->VerticalVelocity)
|
2019-11-30 13:51:37 +01:00
|
|
|
StopSoundEffect(210);
|
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
SoundEffect(210, &cartItem->Position, 2);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
StopSoundEffect(210);
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (cartInfo->VerticalVelocity)
|
2019-11-30 13:51:37 +01:00
|
|
|
StopSoundEffect(209);
|
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
SoundEffect(209, &cartItem->Position, (2 | 4) + 0x1000000 + (cartItem->Velocity * 32768));
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & (CART_FLAG_TURNING_LEFT | CART_FLAG_TURNING_RIGHT))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->TurnLen += cartItem->Velocity * 3;
|
|
|
|
if (cartInfo->TurnLen > ANGLE(90.0f))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & CART_FLAG_TURNING_LEFT)
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.yRot = cartInfo->TurnRot - ANGLE(90.0f);
|
2019-11-30 13:51:37 +01:00
|
|
|
else
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.yRot = cartInfo->TurnRot + ANGLE(90.0f);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Flags &= ~(CART_FLAG_TURNING_LEFT | CART_FLAG_TURNING_RIGHT);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & CART_FLAG_TURNING_LEFT)
|
|
|
|
cartItem->Position.yRot = cartInfo->TurnRot - cartInfo->TurnLen;
|
2019-11-30 13:51:37 +01:00
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Position.yRot = cartInfo->TurnRot + cartInfo->TurnLen;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & (CART_FLAG_TURNING_LEFT | CART_FLAG_TURNING_RIGHT))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
unsigned short quadrant = ((unsigned short)cartItem->Position.yRot) / ANGLE(90.0f);
|
2022-02-23 14:40:08 +11:00
|
|
|
unsigned short degree = cartItem->Position.yRot & 16383;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
float x, z;
|
|
|
|
switch (quadrant)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
|
|
|
case 0:
|
2022-02-23 14:40:08 +11:00
|
|
|
x = -phd_cos(degree);
|
|
|
|
z = phd_sin(degree);
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
case 1:
|
2022-02-23 14:40:08 +11:00
|
|
|
x = phd_sin(degree);
|
|
|
|
z = phd_cos(degree);
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
case 2:
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
x = phd_cos(degree);
|
|
|
|
z = -phd_sin(degree);
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
2022-02-23 22:15:51 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
default:
|
2022-02-23 14:40:08 +11:00
|
|
|
x = -phd_sin(degree);
|
|
|
|
z = -phd_cos(degree);
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & CART_FLAG_TURNING_LEFT)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
|
|
|
x = -x;
|
|
|
|
z = -z;
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Position.xPos = cartInfo->TurnX + x * 3584;
|
|
|
|
cartItem->Position.zPos = cartInfo->TurnZ + z * 3584;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Position.xPos += cartItem->Velocity * phd_sin(cartItem->Position.yRot);
|
|
|
|
cartItem->Position.zPos += cartItem->Velocity * phd_cos(cartItem->Position.yRot);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->FloorHeightMiddle = TestMinecartHeight(cartItem, 0, 0);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (!cartInfo->VerticalVelocity)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->FloorHeightFront = TestMinecartHeight(cartItem, 0, CLICK(1));
|
|
|
|
cartInfo->Gradient = cartInfo->FloorHeightMiddle - cartInfo->FloorHeightFront;
|
|
|
|
cartItem->Position.yPos = cartInfo->FloorHeightMiddle;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
if (cartItem->Position.yPos > cartInfo->FloorHeightMiddle)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
if (cartInfo->VerticalVelocity > 0)
|
2022-02-23 14:40:08 +11:00
|
|
|
SoundEffect(202, &cartItem->Position, 2);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.yPos = cartInfo->FloorHeightMiddle;
|
|
|
|
cartInfo->VerticalVelocity = 0;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->VerticalVelocity += CART_GRAVITY;
|
|
|
|
if (cartInfo->VerticalVelocity > CART_MAX_VERTICAL_VELOCITY)
|
|
|
|
cartInfo->VerticalVelocity = CART_MAX_VERTICAL_VELOCITY;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.yPos += cartInfo->VerticalVelocity / 256;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Position.xRot = cartInfo->Gradient * 32;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & (CART_FLAG_TURNING_LEFT | CART_FLAG_TURNING_RIGHT))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
short val = cartItem->Position.yRot & 16383;
|
|
|
|
if (cartInfo->Flags & CART_FLAG_TURNING_RIGHT)
|
|
|
|
cartItem->Position.zRot = -(val * cartItem->Velocity) / 512;
|
2019-11-30 13:51:37 +01:00
|
|
|
else
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.zRot = ((ANGLE(90.0f) - val) * cartItem->Velocity) / 512;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Position.zRot -= cartItem->Position.zRot / 8;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
static void DoUserInput(ITEM_INFO* cartItem, ITEM_INFO* laraItem, MinecartInfo* cartInfo)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
auto* laraInfo = GetLaraInfo(laraItem);
|
|
|
|
|
|
|
|
short floorHeight;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
switch (laraItem->ActiveState)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_MOVE:
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_SWIPE)
|
|
|
|
laraItem->TargetState = CART_STATE_SWIPE;
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (TrInput & CART_IN_DUCK)
|
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
|
|
|
else if (TrInput & CART_IN_BRAKE)
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKE;
|
|
|
|
else if (cartInfo->Velocity == CART_MIN_VEL || cartInfo->Flags & CART_FLAG_STOPPED)
|
|
|
|
laraItem->TargetState = CART_STATE_IDLE;
|
|
|
|
else if (cartInfo->Gradient < CART_FORWARD_GRADIENT)
|
|
|
|
laraItem->TargetState = CART_STATE_FORWARD;
|
|
|
|
else if (cartInfo->Gradient > CART_BACK_GRADIENT)
|
|
|
|
laraItem->TargetState = CART_STATE_BACK;
|
|
|
|
else if (TrInput & CART_IN_LEFT)
|
|
|
|
laraItem->TargetState = CART_STATE_LEFT;
|
|
|
|
else if (TrInput & CART_IN_RIGHT)
|
|
|
|
laraItem->TargetState = CART_STATE_RIGHT;
|
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_FORWARD:
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_SWIPE)
|
|
|
|
laraItem->TargetState = CART_STATE_SWIPE;
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (TrInput & CART_IN_DUCK)
|
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
|
|
|
else if (TrInput & CART_IN_BRAKE)
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKE;
|
|
|
|
else if (cartInfo->Gradient > CART_FORWARD_GRADIENT)
|
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_BACK:
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_SWIPE)
|
|
|
|
laraItem->TargetState = CART_STATE_SWIPE;
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (TrInput & CART_IN_DUCK)
|
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
|
|
|
else if (TrInput & CART_IN_BRAKE)
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKE;
|
|
|
|
else if (cartInfo->Gradient < CART_BACK_GRADIENT)
|
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_LEFT:
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_SWIPE)
|
|
|
|
laraItem->TargetState = CART_STATE_SWIPE;
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (TrInput & CART_IN_DUCK)
|
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
|
|
|
else if (TrInput & CART_IN_BRAKE)
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKE;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (!(TrInput & CART_IN_LEFT))
|
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_RIGHT:
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_SWIPE)
|
|
|
|
laraItem->TargetState = CART_STATE_SWIPE;
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (TrInput & CART_IN_DUCK)
|
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
|
|
|
else if (TrInput & CART_IN_BRAKE)
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKE;
|
|
|
|
|
|
|
|
if (!(TrInput & CART_IN_RIGHT))
|
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_IDLE:
|
|
|
|
if (!(cartInfo->Flags & CART_FLAG_CONTROL))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
SoundEffect(211, &cartItem->Position, 2);
|
|
|
|
cartInfo->Flags |= CART_FLAG_CONTROL;
|
|
|
|
cartInfo->StopDelay = 64;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (TrInput & CART_IN_DISMOUNT && cartInfo->Flags & CART_FLAG_STOPPED)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_LEFT && TestMinecartDismount(laraItem, -1))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->TargetState = CART_STATE_DISMOUNT;
|
|
|
|
cartInfo->Flags &= ~CART_FLAG_RDIR;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 22:15:51 +11:00
|
|
|
else if (TrInput & CART_IN_RIGHT && TestMinecartDismount(laraItem, 1))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->TargetState = CART_STATE_DISMOUNT;
|
|
|
|
cartInfo->Flags |= CART_FLAG_RDIR;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (TrInput & CART_IN_DUCK)
|
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
|
|
|
else if (cartInfo->Velocity > CART_MIN_VEL)
|
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_DUCK:
|
2022-02-23 22:15:51 +11:00
|
|
|
if (TrInput & CART_IN_SWIPE)
|
|
|
|
laraItem->TargetState = CART_STATE_SWIPE;
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (TrInput & CART_IN_BRAKE)
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKE;
|
|
|
|
else if (!(TrInput & CART_IN_DUCK))
|
|
|
|
laraItem->TargetState = CART_STATE_IDLE;
|
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
case CART_STATE_SWIPE:
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_BRAKING:
|
|
|
|
if (TrInput & CART_IN_DUCK)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->TargetState = CART_STATE_DUCK;
|
2019-11-30 13:51:37 +01:00
|
|
|
StopSoundEffect(219);
|
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
else if (!(TrInput & CART_IN_BRAKE) || cartInfo->Flags & CART_FLAG_STOPPED)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->TargetState = CART_STATE_MOVE;
|
2019-11-30 13:51:37 +01:00
|
|
|
StopSoundEffect(219);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Velocity += CART_DEC;
|
|
|
|
SoundEffect(219, &laraItem->Position, 2);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_BRAKE:
|
|
|
|
laraItem->TargetState = CART_STATE_BRAKING;
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_DISMOUNT:
|
|
|
|
if (laraItem->AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 7)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
if (laraItem->FrameNumber == GetFrameNumber(cartItem, 20) &&
|
|
|
|
cartInfo->Flags & CART_FLAG_MESH)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->meshPtrs[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Flags &= ~CART_FLAG_MESH;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & CART_FLAG_RDIR)
|
|
|
|
laraItem->TargetState = CART_STATE_DISMOUNT_RIGHT;
|
2019-11-30 13:51:37 +01:00
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->TargetState = CART_STATE_DISMOUNT_LEFT;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_DISMOUNT_LEFT:
|
|
|
|
if (laraItem->AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 1 &&
|
|
|
|
laraItem->FrameNumber == g_Level.Anims[laraItem->AnimNumber].frameEnd)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
PHD_VECTOR pos = { 0, 640, 0 };
|
|
|
|
GetLaraJointPosition(&pos, LM_HIPS);
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->Position.xPos = pos.x;
|
|
|
|
laraItem->Position.yPos = pos.y;
|
|
|
|
laraItem->Position.zPos = pos.z;
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->Position.xRot = 0;
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->Position.yRot = ANGLE(90.0f);
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->Position.zRot = 0;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.yRot + ANGLE(90.0f);
|
2022-02-23 14:40:08 +11:00
|
|
|
|
|
|
|
SetAnimation(laraItem, LA_STAND_SOLID);
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->Control.HandStatus = HandStatus::Free;
|
|
|
|
laraInfo->Vehicle = NO_ITEM;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_DISMOUNT_RIGHT:
|
|
|
|
if (laraItem->AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 47 &&
|
|
|
|
laraItem->FrameNumber == g_Level.Anims[laraItem->AnimNumber].frameEnd)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
PHD_VECTOR pos = { 0, 640, 0 };
|
|
|
|
GetLaraJointPosition(&pos, LM_HIPS);
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->Position.xPos = pos.x;
|
|
|
|
laraItem->Position.yPos = pos.y;
|
|
|
|
laraItem->Position.zPos = pos.z;
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->Position.xRot = 0;
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->Position.yRot = ANGLE(90.0f);
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->Position.zRot = 0;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Position.yRot + ANGLE(90.0f);
|
2022-02-23 14:40:08 +11:00
|
|
|
|
|
|
|
SetAnimation(laraItem, LA_STAND_SOLID);
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->Control.HandStatus = HandStatus::Free;
|
|
|
|
laraInfo->Vehicle = NO_ITEM;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_MOUNT:
|
|
|
|
if (laraItem->AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 5 &&
|
|
|
|
laraItem->FrameNumber == GetFrameNumber(cartItem, 20) &&
|
|
|
|
!cartInfo->Flags & CART_FLAG_MESH)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
MESH tmp = g_Level.Meshes[laraInfo->meshPtrs[LM_RHAND]];
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->meshPtrs[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
|
2020-07-21 09:56:47 +02:00
|
|
|
g_Level.Meshes[Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND] = tmp;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Flags |= CART_FLAG_MESH;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_WALL_DEATH:
|
|
|
|
Camera.targetElevation = -ANGLE(25.0f);
|
|
|
|
Camera.targetDistance = SECTOR(4);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
break;
|
|
|
|
|
|
|
|
case CART_TURN_DEATH:
|
|
|
|
Camera.targetElevation = -ANGLE(45.0f);
|
|
|
|
Camera.targetDistance = SECTOR(2);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
floorHeight = GetMinecartCollision(cartItem, cartItem->Position.yRot, CLICK(2));
|
2022-02-23 14:40:08 +11:00
|
|
|
if (floorHeight > -CLICK(1) &&
|
|
|
|
floorHeight < CLICK(1))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (Wibble & 7 == 0)
|
|
|
|
SoundEffect(SFX_TR3_QUAD_FRONT_IMPACT, &cartItem->Position, 2);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->Position.xPos += TURN_DEATH_VEL * phd_sin(cartItem->Position.yRot);
|
|
|
|
cartItem->Position.zPos += TURN_DEATH_VEL * phd_cos(cartItem->Position.yRot);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (laraItem->AnimNumber == Objects[ID_MINECART_LARA_ANIMS].animIndex + 30)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Flags |= CART_FLAG_NO_ANIM;
|
|
|
|
laraItem->HitPoints = -1;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
case CART_STATE_HIT:
|
|
|
|
if (laraItem->HitPoints <= 0 &&
|
|
|
|
laraItem->FrameNumber == GetFrameNumber(cartItem, 34) + 28)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->FrameNumber = GetFrameNumber(cartItem, 34) + 28;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Velocity = 0;
|
|
|
|
cartInfo->Flags = (cartInfo->Flags & ~CART_FLAG_CONTROL) | CART_FLAG_NO_ANIM;
|
|
|
|
cartInfo->Velocity = 0;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
|
2019-11-30 13:51:37 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (laraInfo->Vehicle != NO_ITEM &&
|
2022-02-23 14:40:08 +11:00
|
|
|
!(cartInfo->Flags & CART_FLAG_NO_ANIM))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
AnimateItem(laraItem);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
cartItem->AnimNumber = Objects[ID_MINECART].animIndex + (laraItem->AnimNumber - Objects[ID_MINECART_LARA_ANIMS].animIndex);
|
|
|
|
cartItem->FrameNumber = g_Level.Anims[cartItem->AnimNumber].frameBase + (laraItem->FrameNumber - g_Level.Anims[laraItem->AnimNumber].frameBase);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
if (laraItem->ActiveState != CART_TURN_DEATH &&
|
|
|
|
laraItem->ActiveState != CART_WALL_DEATH &&
|
|
|
|
laraItem->HitPoints > 0)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartItem->Position.zRot > TERMINAL_ANGLE ||
|
|
|
|
cartItem->Position.zRot < -TERMINAL_ANGLE)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->AnimNumber = Objects[ID_MINECART_LARA_ANIMS].animIndex + 31;
|
|
|
|
laraItem->FrameNumber = g_Level.Anims[laraItem->AnimNumber].frameBase;
|
|
|
|
laraItem->ActiveState = laraItem->TargetState = CART_TURN_DEATH;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Velocity = 0;
|
2022-02-23 14:40:08 +11:00
|
|
|
cartInfo->Flags = (cartInfo->Flags & ~CART_FLAG_CONTROL) | CART_FLAG_STOPPED | CART_FLAG_DEAD;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartInfo->Velocity = 0;
|
2019-11-30 13:51:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
floorHeight = GetMinecartCollision(cartItem, cartItem->Position.yRot, CLICK(2));
|
2022-02-23 14:40:08 +11:00
|
|
|
if (floorHeight < -CLICK(2))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->AnimNumber = Objects[ID_MINECART_LARA_ANIMS].animIndex + 23;
|
|
|
|
laraItem->FrameNumber = g_Level.Anims[laraItem->AnimNumber].frameBase;
|
|
|
|
laraItem->ActiveState = laraItem->TargetState = CART_WALL_DEATH;
|
|
|
|
laraItem->HitPoints = -1;
|
2022-02-23 22:15:51 +11:00
|
|
|
cartItem->Velocity = 0;
|
|
|
|
cartInfo->Flags = (cartInfo->Flags & ~CART_FLAG_CONTROL) | (CART_FLAG_STOPPED | CART_FLAG_DEAD);
|
|
|
|
cartInfo->Velocity = 0;
|
2019-11-30 13:51:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (laraItem->ActiveState != CART_STATE_DUCK &&
|
|
|
|
laraItem->ActiveState != CART_STATE_HIT)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
|
|
|
COLL_INFO coll;
|
2021-09-10 00:20:59 +03:00
|
|
|
coll.Setup.Radius = CART_RADIUS;
|
2022-02-23 14:40:08 +11:00
|
|
|
DoObjectCollision(cartItem, &coll);
|
2021-09-02 11:20:41 +03:00
|
|
|
|
2021-09-10 00:18:47 +03:00
|
|
|
if (coll.HitStatic)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
|
|
|
int hits;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->AnimNumber = Objects[ID_MINECART_LARA_ANIMS].animIndex + 34;
|
|
|
|
laraItem->FrameNumber = g_Level.Anims[laraItem->AnimNumber].frameBase;
|
|
|
|
laraItem->ActiveState = laraItem->TargetState = CART_STATE_HIT;
|
2022-02-23 22:15:51 +11:00
|
|
|
DoLotsOfBlood(laraItem->Position.xPos, laraItem->Position.yPos - CLICK(3), laraItem->Position.zPos, cartItem->Velocity, cartItem->Position.yRot, laraItem->RoomNumber, 3);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
hits = CART_NHITS * short(cartInfo->Velocity / 2048);
|
2019-11-30 13:51:37 +01:00
|
|
|
if (hits < 20)
|
|
|
|
hits = 20;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->HitPoints -= hits;
|
2019-11-30 13:51:37 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (floorHeight > CLICK(2.25f) && !cartInfo->VerticalVelocity)
|
|
|
|
cartInfo->VerticalVelocity = CART_JUMP_VELOCITY;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
CartToEntityCollision(laraItem, cartItem);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
void MineCartCollision(short itemNumber, ITEM_INFO* laraItem, COLL_INFO* coll)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
auto* laraInfo = GetLaraInfo(laraItem);
|
|
|
|
|
|
|
|
if (laraItem->HitPoints < 0 || laraInfo->Vehicle != NO_ITEM)
|
2019-11-30 13:51:37 +01:00
|
|
|
return;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
auto* cartItem = &g_Level.Items[itemNumber];
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
int mount = GetInMineCart(cartItem, laraItem, coll);
|
|
|
|
if (mount)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->Vehicle = itemNumber;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (laraInfo->Control.WeaponControl.GunType == WEAPON_FLARE)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
CreateFlare(laraItem, ID_FLARE_ITEM, FALSE);
|
2022-02-23 14:40:08 +11:00
|
|
|
UndrawFlareMeshes(laraItem);
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->Flare.ControlLeft = false;
|
|
|
|
laraInfo->Control.WeaponControl.RequestGunType = WEAPON_NONE;
|
|
|
|
laraInfo->Control.WeaponControl.GunType = WEAPON_NONE;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
laraInfo->Control.HandStatus = HandStatus::Busy;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
short angle = short(mGetAngle(cartItem->Position.xPos, cartItem->Position.zPos, laraItem->Position.xPos, laraItem->Position.zPos) - cartItem->Position.yRot);
|
|
|
|
if (angle > -ANGLE(45.0f) && angle < ANGLE(135.0f))
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->AnimNumber = Objects[ID_MINECART_LARA_ANIMS].animIndex + CART_ANIM_MOUNT_RIGHT;
|
2019-11-30 13:51:37 +01:00
|
|
|
else
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->AnimNumber = Objects[ID_MINECART_LARA_ANIMS].animIndex + CART_ANIM_MOUNT_LEFT;
|
2022-02-23 14:40:08 +11:00
|
|
|
|
|
|
|
laraItem->FrameNumber = g_Level.Anims[laraItem->AnimNumber].frameBase;
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->TargetState = CART_STATE_MOUNT;
|
|
|
|
laraItem->ActiveState = CART_STATE_MOUNT;
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
laraItem->Position.xPos = cartItem->Position.xPos;
|
|
|
|
laraItem->Position.yPos = cartItem->Position.yPos;
|
|
|
|
laraItem->Position.zPos = cartItem->Position.zPos;
|
|
|
|
laraItem->Position.xRot = cartItem->Position.xRot;
|
|
|
|
laraItem->Position.yRot = cartItem->Position.yRot;
|
|
|
|
laraItem->Position.zRot = cartItem->Position.zRot;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
else
|
2022-02-23 14:40:08 +11:00
|
|
|
ObjectCollision(itemNumber, laraItem, coll);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
bool MineCartControl(ITEM_INFO* laraItem)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
auto* laraInfo = GetLaraInfo(laraItem);
|
|
|
|
auto* cartItem = &g_Level.Items[laraInfo->Vehicle];
|
2021-10-31 10:50:36 +03:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (!cartItem->Data)
|
2021-10-31 10:50:36 +03:00
|
|
|
{
|
|
|
|
TENLog("Minecart data is nullptr!", LogLevel::Error);
|
2022-02-23 22:15:51 +11:00
|
|
|
return false;
|
2021-10-31 10:50:36 +03:00
|
|
|
}
|
2022-02-23 14:40:08 +11:00
|
|
|
auto* cartInfo = (MinecartInfo*)cartItem->Data;
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
DoUserInput(cartItem, laraItem, cartInfo);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (cartInfo->Flags & CART_FLAG_CONTROL)
|
2022-02-23 22:15:51 +11:00
|
|
|
MoveCart(laraItem, cartItem);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
if (laraInfo->Vehicle != NO_ITEM)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
laraItem->Position.xPos = cartItem->Position.xPos;
|
|
|
|
laraItem->Position.yPos = cartItem->Position.yPos;
|
|
|
|
laraItem->Position.zPos = cartItem->Position.zPos;
|
|
|
|
laraItem->Position.xRot = cartItem->Position.xRot;
|
|
|
|
laraItem->Position.yRot = cartItem->Position.yRot;
|
|
|
|
laraItem->Position.zRot = cartItem->Position.zRot;
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
short probedRoomNumber = GetCollisionResult(cartItem).RoomNumber;
|
|
|
|
if (probedRoomNumber != cartItem->RoomNumber)
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 22:15:51 +11:00
|
|
|
ItemNewRoom(laraInfo->Vehicle, probedRoomNumber);
|
|
|
|
ItemNewRoom(laraInfo->ItemNumber, probedRoomNumber);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
TestTriggers(cartItem, false);
|
2019-11-30 13:51:37 +01:00
|
|
|
|
2022-02-23 14:40:08 +11:00
|
|
|
if (!(cartInfo->Flags & CART_FLAG_DEAD))
|
2019-11-30 13:51:37 +01:00
|
|
|
{
|
2022-02-23 14:40:08 +11:00
|
|
|
Camera.targetElevation = -ANGLE(45.0f);
|
|
|
|
Camera.targetDistance = SECTOR(2);
|
2019-11-30 13:51:37 +01:00
|
|
|
}
|
|
|
|
|
2022-02-23 22:15:51 +11:00
|
|
|
return (laraInfo->Vehicle == NO_ITEM) ? false : true;
|
2021-08-31 17:37:15 +02:00
|
|
|
}
|