mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
object: move bridge, drawbridge and trapdoor to TRX
This moves the three bridges, drawbridge and trapdoor implementations to TRX, and makes the config option to fix collision issues available in TR2. Resolves #2752. Resolves #2294.
This commit is contained in:
parent
5d096fe311
commit
ecab0d92e6
25 changed files with 49 additions and 415 deletions
|
@ -20,6 +20,8 @@
|
|||
- fixed the final two levels not allowing for secrets to be counted in the statistics (#1582)
|
||||
- fixed Lara's holsters being empty if a game flow level removes all weapons but also re-adds the pistols (#2677)
|
||||
- fixed the console opening when remapping its key (#2641)
|
||||
- fixed collision issues with drawbridges, trapdoors, and bridges when stacked over each other, over slopes, and near the ground (#2752)
|
||||
- fixed the drawbridge producing dynamic light when open (#2294)
|
||||
- fixed sprites rendering black if no shade value is assigned in the level (#2701, regression from 0.8)
|
||||
- fixed a crash if an image was missing
|
||||
- fixed a crash on level load if an animation has no frames (#2746, regression from 0.8)
|
||||
|
|
|
@ -219,6 +219,7 @@ as Notepad.
|
|||
- fixed the game crashing if a cinematic is triggered but the level contains no cinematic frames
|
||||
- fixed smashed windows blocking enemy pathing after loading a save
|
||||
- fixed Lara getting stuck in a T-pose after jumping/falling and then dying before reaching fast fall speed
|
||||
- fixed collision issues with drawbridges, trapdoors, and bridges when stacked over each other, over slopes, and near the ground
|
||||
- fixed several issues with pushblocks:
|
||||
- fixed an invisible wall above stacked pushblocks if near a ceiling portal
|
||||
- fixed floor height issues with pushblocks poised to fall in various scenarios
|
||||
|
@ -289,6 +290,7 @@ as Notepad.
|
|||
- fixed bubbles spawning from flares if Lara is in shallow water
|
||||
- fixed the inventory up arrow at times overlapping the health bar
|
||||
- fixed blood spawning on Lara from gunshots using incorrect positioning data
|
||||
- fixed the drawbridge producing dynamic light when open
|
||||
- improved FMV mode behavior - stopped switching screen resolutions
|
||||
- improved vertex movement when looking through water portals
|
||||
- improved support for non-4:3 aspect ratios
|
||||
|
|
|
@ -14,12 +14,8 @@ static bool M_IsOnWalkable(
|
|||
const SECTOR *const sector, const int32_t x, const int32_t y,
|
||||
const int32_t z, const int32_t room_height)
|
||||
{
|
||||
#if TR_VERSION == 1
|
||||
return g_Config.gameplay.fix_bridge_collision
|
||||
&& Room_IsOnWalkable(sector, x, y, z, room_height);
|
||||
#elif TR_VERSION >= 2
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
int32_t Collide_GetSpheres(
|
||||
|
@ -291,11 +287,7 @@ void Collide_GetCollisionInfo(
|
|||
coll->side_front.ceiling = ceiling;
|
||||
coll->side_front.type = Room_GetHeightType();
|
||||
|
||||
#if TR_VERSION == 1
|
||||
is_on_walkable = M_IsOnWalkable(sector, x, y_top, z, room_height);
|
||||
#elif TR_VERSION >= 2
|
||||
is_on_walkable = false;
|
||||
#endif
|
||||
if (!is_on_walkable) {
|
||||
if (coll->slopes_are_walls && coll->side_front.type == HT_BIG_SLOPE
|
||||
&& coll->side_front.floor < 0) {
|
||||
|
|
|
@ -1,18 +1,16 @@
|
|||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
#include "game/items.h"
|
||||
#include "game/room.h"
|
||||
#include "global/const.h"
|
||||
#include "config.h"
|
||||
#include "game/rooms.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
#include <libtrx/utils.h>
|
||||
|
||||
bool Bridge_IsSameSector(int32_t x, int32_t z, const ITEM *item)
|
||||
bool Bridge_IsSameSector(
|
||||
const int32_t x, const int32_t z, const ITEM *const item)
|
||||
{
|
||||
int32_t sector_x = x / WALL_L;
|
||||
int32_t sector_z = z / WALL_L;
|
||||
int32_t item_sector_x = item->pos.x / WALL_L;
|
||||
int32_t item_sector_z = item->pos.z / WALL_L;
|
||||
const int32_t sector_x = x / WALL_L;
|
||||
const int32_t sector_z = z / WALL_L;
|
||||
const int32_t item_sector_x = item->pos.x / WALL_L;
|
||||
const int32_t item_sector_z = item->pos.z / WALL_L;
|
||||
|
||||
return sector_x == item_sector_x && sector_z == item_sector_z;
|
||||
}
|
||||
|
@ -74,9 +72,9 @@ void Bridge_FixEmbeddedPosition(int16_t item_num)
|
|||
// and moves them up.
|
||||
ITEM *const item = Item_Get(item_num);
|
||||
|
||||
int32_t x = item->pos.x;
|
||||
int32_t y = item->pos.y;
|
||||
int32_t z = item->pos.z;
|
||||
const int32_t x = item->pos.x;
|
||||
const int32_t y = item->pos.y;
|
||||
const int32_t z = item->pos.z;
|
||||
int16_t room_num = item->room_num;
|
||||
|
||||
const BOUNDS_16 *const bounds = Item_GetBoundsAccurate(item);
|
|
@ -1,7 +1,8 @@
|
|||
#include "config.h"
|
||||
#include "game/const.h"
|
||||
#include "game/objects.h"
|
||||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
|
@ -1,7 +1,8 @@
|
|||
#include "config.h"
|
||||
#include "game/const.h"
|
||||
#include "game/objects.h"
|
||||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
|
@ -1,7 +1,8 @@
|
|||
#include "config.h"
|
||||
#include "game/const.h"
|
||||
#include "game/objects.h"
|
||||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
|
@ -1,8 +1,8 @@
|
|||
#include "config.h"
|
||||
#include "game/items.h"
|
||||
#include "game/objects.h"
|
||||
#include "game/objects/general/door.h"
|
||||
#include "game/room.h"
|
||||
|
||||
#include <libtrx/config.h>
|
||||
#include "game/rooms.h"
|
||||
|
||||
typedef enum {
|
||||
DRAWBRIDGE_STATE_CLOSED = DOOR_STATE_CLOSED,
|
|
@ -1,4 +1,5 @@
|
|||
#include "game/items.h"
|
||||
#include "game/const.h"
|
||||
#include "game/objects.h"
|
||||
|
||||
typedef enum {
|
||||
TRAPDOOR_STATE_CLOSED,
|
|
@ -1,6 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "global/types.h"
|
||||
#include "../../items.h"
|
||||
|
||||
bool Bridge_IsSameSector(int32_t x, int32_t z, const ITEM *item);
|
||||
int32_t Bridge_GetOffset(const ITEM *item, int32_t x, int32_t y, int32_t z);
|
10
src/libtrx/include/libtrx/game/objects/general/door.h
Normal file
10
src/libtrx/include/libtrx/game/objects/general/door.h
Normal file
|
@ -0,0 +1,10 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../collision.h"
|
||||
|
||||
typedef enum {
|
||||
DOOR_STATE_CLOSED = 0,
|
||||
DOOR_STATE_OPEN = 1,
|
||||
} DOOR_STATE;
|
||||
|
||||
extern void Door_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);
|
|
@ -169,6 +169,12 @@ sources = [
|
|||
'game/matrix.c',
|
||||
'game/music.c',
|
||||
'game/objects/common.c',
|
||||
'game/objects/general/bridge_common.c',
|
||||
'game/objects/general/bridge_flat.c',
|
||||
'game/objects/general/bridge_tilt1.c',
|
||||
'game/objects/general/bridge_tilt2.c',
|
||||
'game/objects/general/drawbridge.c',
|
||||
'game/objects/general/trapdoor.c',
|
||||
'game/objects/names.c',
|
||||
'game/objects/creatures/bear.c',
|
||||
'game/objects/creatures/wolf.c',
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#include "game/objects/general/door.h"
|
||||
|
||||
#include "game/box.h"
|
||||
#include "game/items.h"
|
||||
#include "game/lara/common.h"
|
||||
|
@ -9,6 +7,7 @@
|
|||
|
||||
#include <libtrx/game/collision.h>
|
||||
#include <libtrx/game/game_buf.h>
|
||||
#include <libtrx/game/objects/general/door.h>
|
||||
#include <libtrx/utils.h>
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "global/types.h"
|
||||
|
||||
typedef enum {
|
||||
DOOR_STATE_CLOSED,
|
||||
DOOR_STATE_OPEN,
|
||||
} DOOR_STATE;
|
||||
|
||||
void Door_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);
|
|
@ -1,113 +0,0 @@
|
|||
#include "game/items.h"
|
||||
#include "global/const.h"
|
||||
|
||||
#include <libtrx/utils.h>
|
||||
|
||||
typedef enum {
|
||||
TRAPDOOR_STATE_CLOSED,
|
||||
TRAPDOOR_STATE_OPEN,
|
||||
} TRAPDOOR_STATE;
|
||||
|
||||
static bool M_IsItemOnTop(const ITEM *item, int32_t x, int32_t z);
|
||||
static void M_Setup(OBJECT *obj);
|
||||
static void M_Control(int16_t item_num);
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
|
||||
static bool M_IsItemOnTop(const ITEM *item, int32_t x, int32_t z)
|
||||
{
|
||||
const BOUNDS_16 *const orig_bounds = &Item_GetBestFrame(item)->bounds;
|
||||
if (orig_bounds == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
BOUNDS_16 fixed_bounds = {};
|
||||
|
||||
// Bounds need to change in order to account for 2 sector trapdoors
|
||||
// and the trapdoor angle.
|
||||
if (item->rot.y == 0) {
|
||||
fixed_bounds.min.x = orig_bounds->min.x;
|
||||
fixed_bounds.max.x = orig_bounds->max.x;
|
||||
fixed_bounds.min.z = orig_bounds->min.z;
|
||||
fixed_bounds.max.z = orig_bounds->max.z;
|
||||
} else if (item->rot.y == DEG_90) {
|
||||
fixed_bounds.min.x = orig_bounds->min.z;
|
||||
fixed_bounds.max.x = orig_bounds->max.z;
|
||||
fixed_bounds.min.z = -orig_bounds->max.x;
|
||||
fixed_bounds.max.z = -orig_bounds->min.x;
|
||||
} else if (item->rot.y == -DEG_180) {
|
||||
fixed_bounds.min.x = -orig_bounds->max.x;
|
||||
fixed_bounds.max.x = -orig_bounds->min.x;
|
||||
fixed_bounds.min.z = -orig_bounds->max.z;
|
||||
fixed_bounds.max.z = -orig_bounds->min.z;
|
||||
} else if (item->rot.y == -DEG_90) {
|
||||
fixed_bounds.min.x = -orig_bounds->max.z;
|
||||
fixed_bounds.max.x = -orig_bounds->min.z;
|
||||
fixed_bounds.min.z = orig_bounds->min.x;
|
||||
fixed_bounds.max.z = orig_bounds->max.x;
|
||||
}
|
||||
|
||||
if (x <= item->pos.x + fixed_bounds.max.x
|
||||
&& x >= item->pos.x + fixed_bounds.min.x
|
||||
&& z <= item->pos.z + fixed_bounds.max.z
|
||||
&& z >= item->pos.z + fixed_bounds.min.z) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void M_Setup(OBJECT *const obj)
|
||||
{
|
||||
obj->control_func = M_Control;
|
||||
obj->floor_height_func = M_GetFloorHeight;
|
||||
obj->ceiling_height_func = M_GetCeilingHeight;
|
||||
obj->save_anim = 1;
|
||||
obj->save_flags = 1;
|
||||
}
|
||||
|
||||
static void M_Control(const int16_t item_num)
|
||||
{
|
||||
ITEM *const item = Item_Get(item_num);
|
||||
if (Item_IsTriggerActive(item)) {
|
||||
if (item->current_anim_state == TRAPDOOR_STATE_CLOSED) {
|
||||
item->goal_anim_state = TRAPDOOR_STATE_OPEN;
|
||||
}
|
||||
} else if (item->current_anim_state == TRAPDOOR_STATE_OPEN) {
|
||||
item->goal_anim_state = TRAPDOOR_STATE_CLOSED;
|
||||
}
|
||||
Item_Animate(item);
|
||||
}
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
if (!M_IsItemOnTop(item, x, z)) {
|
||||
return height;
|
||||
}
|
||||
if (item->current_anim_state == TRAPDOOR_STATE_OPEN || y > item->pos.y
|
||||
|| item->pos.y >= height) {
|
||||
return height;
|
||||
}
|
||||
return item->pos.y;
|
||||
}
|
||||
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
if (!M_IsItemOnTop(item, x, z)) {
|
||||
return height;
|
||||
}
|
||||
if (item->current_anim_state == TRAPDOOR_STATE_OPEN || y <= item->pos.y
|
||||
|| item->pos.y <= height) {
|
||||
return height;
|
||||
}
|
||||
return item->pos.y + STEP_L;
|
||||
}
|
||||
|
||||
REGISTER_OBJECT(O_TRAPDOOR_TYPE_1, M_Setup)
|
||||
REGISTER_OBJECT(O_TRAPDOOR_TYPE_2, M_Setup)
|
|
@ -194,15 +194,10 @@ sources = [
|
|||
'game/objects/effects/splash.c',
|
||||
'game/objects/effects/twinkle.c',
|
||||
'game/objects/general/boat.c',
|
||||
'game/objects/general/bridge_common.c',
|
||||
'game/objects/general/bridge_flat.c',
|
||||
'game/objects/general/bridge_tilt1.c',
|
||||
'game/objects/general/bridge_tilt2.c',
|
||||
'game/objects/general/cabin.c',
|
||||
'game/objects/general/camera_target.c',
|
||||
'game/objects/general/cog.c',
|
||||
'game/objects/general/door.c',
|
||||
'game/objects/general/drawbridge.c',
|
||||
'game/objects/general/earthquake.c',
|
||||
'game/objects/general/keyhole.c',
|
||||
'game/objects/general/moving_bar.c',
|
||||
|
@ -214,7 +209,6 @@ sources = [
|
|||
'game/objects/general/scion4.c',
|
||||
'game/objects/general/scion_holder.c',
|
||||
'game/objects/general/switch.c',
|
||||
'game/objects/general/trapdoor.c',
|
||||
'game/objects/general/waterfall.c',
|
||||
'game/objects/setup.c',
|
||||
'game/objects/traps/damocles_sword.c',
|
||||
|
|
|
@ -1,16 +0,0 @@
|
|||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
int32_t Bridge_GetOffset(
|
||||
const ITEM *const item, const int32_t x, const int32_t z)
|
||||
{
|
||||
switch (item->rot.y) {
|
||||
case 0:
|
||||
return (WALL_L - x) & (WALL_L - 1);
|
||||
case -DEG_180:
|
||||
return x & (WALL_L - 1);
|
||||
case DEG_90:
|
||||
return z & (WALL_L - 1);
|
||||
default:
|
||||
return (WALL_L - z) & (WALL_L - 1);
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "global/types.h"
|
||||
|
||||
int32_t Bridge_GetOffset(const ITEM *item, int32_t x, int32_t z);
|
|
@ -1,35 +0,0 @@
|
|||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static void M_Setup(OBJECT *obj);
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
if (y > item->pos.y) {
|
||||
return height;
|
||||
}
|
||||
return item->pos.y;
|
||||
}
|
||||
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
if (y <= item->pos.y) {
|
||||
return height;
|
||||
}
|
||||
return item->pos.y + STEP_L;
|
||||
}
|
||||
|
||||
static void M_Setup(OBJECT *const obj)
|
||||
{
|
||||
obj->floor_height_func = M_GetFloorHeight;
|
||||
obj->ceiling_height_func = M_GetCeilingHeight;
|
||||
}
|
||||
|
||||
REGISTER_OBJECT(O_BRIDGE_FLAT, M_Setup)
|
|
@ -1,39 +0,0 @@
|
|||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static void M_Setup(OBJECT *obj);
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
const int32_t offset_height =
|
||||
item->pos.y + (Bridge_GetOffset(item, x, z) / 4);
|
||||
if (y > offset_height) {
|
||||
return height;
|
||||
}
|
||||
return offset_height;
|
||||
}
|
||||
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
const int32_t offset_height =
|
||||
item->pos.y + (Bridge_GetOffset(item, x, z) / 4);
|
||||
if (y <= offset_height) {
|
||||
return height;
|
||||
}
|
||||
return offset_height + STEP_L;
|
||||
}
|
||||
|
||||
static void M_Setup(OBJECT *const obj)
|
||||
{
|
||||
obj->floor_height_func = M_GetFloorHeight;
|
||||
obj->ceiling_height_func = M_GetCeilingHeight;
|
||||
}
|
||||
|
||||
REGISTER_OBJECT(O_BRIDGE_TILT_1, M_Setup)
|
|
@ -1,39 +0,0 @@
|
|||
#include "game/objects/general/bridge_common.h"
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static void M_Setup(OBJECT *obj);
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
const int32_t offset_height =
|
||||
item->pos.y + (Bridge_GetOffset(item, x, z) / 2);
|
||||
if (y > offset_height) {
|
||||
return height;
|
||||
}
|
||||
return offset_height;
|
||||
}
|
||||
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
const int32_t offset_height =
|
||||
item->pos.y + (Bridge_GetOffset(item, x, z) / 2);
|
||||
if (y <= offset_height) {
|
||||
return height;
|
||||
}
|
||||
return offset_height + STEP_L;
|
||||
}
|
||||
|
||||
static void M_Setup(OBJECT *const obj)
|
||||
{
|
||||
obj->floor_height_func = M_GetFloorHeight;
|
||||
obj->ceiling_height_func = M_GetCeilingHeight;
|
||||
}
|
||||
|
||||
REGISTER_OBJECT(O_BRIDGE_TILT_2, M_Setup)
|
|
@ -1,5 +1,3 @@
|
|||
#include "game/objects/general/door.h"
|
||||
|
||||
#include "game/box.h"
|
||||
#include "game/items.h"
|
||||
#include "game/objects/common.h"
|
||||
|
@ -9,6 +7,7 @@
|
|||
#include <libtrx/game/collision.h>
|
||||
#include <libtrx/game/game_buf.h>
|
||||
#include <libtrx/game/lara/common.h>
|
||||
#include <libtrx/game/objects/general/door.h>
|
||||
|
||||
typedef struct {
|
||||
DOORPOS_DATA d1;
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
#pragma once
|
||||
|
||||
#include "global/types.h"
|
||||
|
||||
typedef enum {
|
||||
DOOR_STATE_CLOSED = 0,
|
||||
DOOR_STATE_OPEN = 1,
|
||||
} DOOR_STATE;
|
||||
|
||||
void Door_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);
|
|
@ -1,99 +0,0 @@
|
|||
#include "game/objects/general/door.h"
|
||||
#include "game/objects/general/general.h"
|
||||
|
||||
typedef enum {
|
||||
DRAWBRIDGE_STATE_CLOSED = DOOR_STATE_CLOSED,
|
||||
DRAWBRIDGE_STATE_OPEN = DOOR_STATE_OPEN,
|
||||
} DRAWBRIDGE_STATE;
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *item, int32_t x, int32_t y, int32_t z, int16_t height);
|
||||
static bool M_IsItemOnTop(const ITEM *item, int32_t z, int32_t x);
|
||||
static void M_Setup(OBJECT *obj);
|
||||
static void M_Collision(int16_t item_num, ITEM *lara_item, COLL_INFO *coll);
|
||||
|
||||
static int16_t M_GetFloorHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
if (item->current_anim_state != DRAWBRIDGE_STATE_OPEN) {
|
||||
return height;
|
||||
} else if (!M_IsItemOnTop(item, z, x)) {
|
||||
return height;
|
||||
} else if (item->pos.y < y) {
|
||||
return height;
|
||||
}
|
||||
return item->pos.y;
|
||||
}
|
||||
|
||||
static int16_t M_GetCeilingHeight(
|
||||
const ITEM *const item, const int32_t x, const int32_t y, const int32_t z,
|
||||
const int16_t height)
|
||||
{
|
||||
if (item->current_anim_state != DRAWBRIDGE_STATE_OPEN) {
|
||||
return height;
|
||||
} else if (!M_IsItemOnTop(item, z, x)) {
|
||||
return height;
|
||||
} else if (item->pos.y >= y) {
|
||||
return height;
|
||||
}
|
||||
return item->pos.y + STEP_L;
|
||||
}
|
||||
|
||||
static bool M_IsItemOnTop(
|
||||
const ITEM *const item, const int32_t z, const int32_t x)
|
||||
{
|
||||
// drawbridge sector
|
||||
const XZ_32 obj = {
|
||||
.x = item->pos.x >> WALL_SHIFT,
|
||||
.z = item->pos.z >> WALL_SHIFT,
|
||||
};
|
||||
|
||||
// test sector
|
||||
const XZ_32 test = {
|
||||
.x = x >> WALL_SHIFT,
|
||||
.z = z >> WALL_SHIFT,
|
||||
};
|
||||
|
||||
switch (item->rot.y) {
|
||||
case 0:
|
||||
return test.x == obj.x && (test.z == obj.z - 1 || test.z == obj.z - 2);
|
||||
|
||||
case -DEG_180:
|
||||
return test.x == obj.x && (test.z == obj.z + 1 || test.z == obj.z + 2);
|
||||
|
||||
case -DEG_90:
|
||||
return test.z == obj.z && (test.x == obj.x + 1 || test.x == obj.x + 2);
|
||||
|
||||
case DEG_90:
|
||||
return test.z == obj.z && (test.x == obj.x - 1 || test.x == obj.x - 2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static void M_Setup(OBJECT *const obj)
|
||||
{
|
||||
if (!obj->loaded) {
|
||||
return;
|
||||
}
|
||||
obj->control_func = General_Control;
|
||||
obj->collision_func = M_Collision;
|
||||
obj->floor_height_func = M_GetFloorHeight;
|
||||
obj->ceiling_height_func = M_GetCeilingHeight;
|
||||
obj->save_flags = 1;
|
||||
obj->save_anim = 1;
|
||||
}
|
||||
|
||||
static void M_Collision(
|
||||
const int16_t item_num, ITEM *const lara_item, COLL_INFO *const coll)
|
||||
{
|
||||
const ITEM *const item = Item_Get(item_num);
|
||||
if (item->current_anim_state == DRAWBRIDGE_STATE_CLOSED) {
|
||||
Door_Collision(item_num, lara_item, coll);
|
||||
}
|
||||
}
|
||||
|
||||
REGISTER_OBJECT(O_DRAWBRIDGE, M_Setup)
|
|
@ -189,10 +189,6 @@ sources = [
|
|||
'game/objects/general/bell.c',
|
||||
'game/objects/general/big_bowl.c',
|
||||
'game/objects/general/bird_tweeter.c',
|
||||
'game/objects/general/bridge_common.c',
|
||||
'game/objects/general/bridge_flat.c',
|
||||
'game/objects/general/bridge_tilt_1.c',
|
||||
'game/objects/general/bridge_tilt_2.c',
|
||||
'game/objects/general/camera_target.c',
|
||||
'game/objects/general/clock_chimes.c',
|
||||
'game/objects/general/copter.c',
|
||||
|
@ -200,7 +196,6 @@ sources = [
|
|||
'game/objects/general/detonator.c',
|
||||
'game/objects/general/ding_dong.c',
|
||||
'game/objects/general/door.c',
|
||||
'game/objects/general/drawbridge.c',
|
||||
'game/objects/general/earthquake.c',
|
||||
'game/objects/general/final_cutscene.c',
|
||||
'game/objects/general/final_level_counter.c',
|
||||
|
@ -218,7 +213,6 @@ sources = [
|
|||
'game/objects/general/puzzle_hole.c',
|
||||
'game/objects/general/sphere_of_doom.c',
|
||||
'game/objects/general/switch.c',
|
||||
'game/objects/general/trapdoor.c',
|
||||
'game/objects/general/waterfall.c',
|
||||
'game/objects/general/window.c',
|
||||
'game/objects/general/zipline.c',
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue