mirror of
https://github.com/TombEngine/TombEngine.git
synced 2025-04-28 15:57:59 +03:00
Dynamic bridge collision (#1137)
* Initial commit * Don't update bridge offset if not necessary * Don't stick to bridge when in air * Update Changes.txt * Minor simplification * Simplify * Update collide_room.h * Update collide_room.h * Use real floor height to determine bridge collision * Detect bridges first to avoid potential issues with item init * Remove incorrect forward declaration * Move pickups on dynamic bridges * Push player away from moving bridges * Update Changes.txt * Use actual pickup bounds for collision detection * Stabilize collision by using both abs Y and bb Y ref points * Update collide_item.cpp * Swap function parameters * Update collide_room.cpp * Increase movement tolerance --------- Co-authored-by: Sezz <sezzary@outlook.com> Co-authored-by: Jakub <80340234+Kubsy@users.noreply.github.com>
This commit is contained in:
parent
ba368be4b7
commit
35304ce84a
20 changed files with 223 additions and 77 deletions
|
@ -14,6 +14,8 @@ Version 1.1.0
|
||||||
* Add multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger.
|
* Add multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger.
|
||||||
* Pause all sounds when entering inventory or pause menu.
|
* Pause all sounds when entering inventory or pause menu.
|
||||||
* Improve deflection against slopes.
|
* Improve deflection against slopes.
|
||||||
|
* Move and rotate Lara together with dynamic bridge objects.
|
||||||
|
* Move and rotate activated pickups together with dynamic bridge objects.
|
||||||
* Add TR1 skateboard kid.
|
* Add TR1 skateboard kid.
|
||||||
* Add TR1 Kold.
|
* Add TR1 Kold.
|
||||||
|
|
||||||
|
|
|
@ -48,6 +48,10 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
|
||||||
ShiftItem(item, coll);
|
ShiftItem(item, coll);
|
||||||
item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE);
|
item->Pose.Orientation.y -= ANGLE(coll->DiagonalStepAtRight() ? DEFLECT_DIAGONAL_ANGLE : DEFLECT_STRAIGHT_ANGLE);
|
||||||
}
|
}
|
||||||
|
else if (coll->LastBridgeItemNumber != NO_ITEM)
|
||||||
|
{
|
||||||
|
ShiftItem(item, coll);
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -202,8 +206,8 @@ bool LaraDeflectEdgeCrawl(ItemInfo* item, CollisionInfo* coll)
|
||||||
bool LaraDeflectEdgeMonkey(ItemInfo* item, CollisionInfo* coll)
|
bool LaraDeflectEdgeMonkey(ItemInfo* item, CollisionInfo* coll)
|
||||||
{
|
{
|
||||||
// HACK
|
// HACK
|
||||||
if (coll->Shift.y >= 0 && coll->Shift.y <= CLICK(1.25f))
|
if (coll->Shift.Position.y >= 0 && coll->Shift.Position.y <= CLICK(1.25f))
|
||||||
coll->Shift.y = 0;
|
coll->Shift.Position.y = 0;
|
||||||
|
|
||||||
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT ||
|
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT ||
|
||||||
coll->HitTallObject)
|
coll->HitTallObject)
|
||||||
|
|
|
@ -140,8 +140,8 @@ void lara_col_monkey_idle(ItemInfo* item, CollisionInfo* coll)
|
||||||
GetCollisionInfo(coll, item);
|
GetCollisionInfo(coll, item);
|
||||||
|
|
||||||
// HACK: Prevent ShiftItem() from causing an instantaneous snap, thereby interfering with DoLaraMonkeyStep(), when going down a step. @Sezz 2022.01.28
|
// HACK: Prevent ShiftItem() from causing an instantaneous snap, thereby interfering with DoLaraMonkeyStep(), when going down a step. @Sezz 2022.01.28
|
||||||
if (coll->Shift.y >= 0 && coll->Shift.y <= CLICK(1.25f))
|
if (coll->Shift.Position.y >= 0 && coll->Shift.Position.y <= CLICK(1.25f))
|
||||||
coll->Shift.y = 0;
|
coll->Shift.Position.y = 0;
|
||||||
ShiftItem(item, coll);
|
ShiftItem(item, coll);
|
||||||
|
|
||||||
if (TestLaraMonkeyFall(item, coll))
|
if (TestLaraMonkeyFall(item, coll))
|
||||||
|
|
|
@ -250,9 +250,9 @@ bool TestLaraHang(ItemInfo* item, CollisionInfo* coll)
|
||||||
else // Death, incorrect ledge or ACTION release
|
else // Death, incorrect ledge or ACTION release
|
||||||
{
|
{
|
||||||
SetAnimation(item, LA_JUMP_UP, 9);
|
SetAnimation(item, LA_JUMP_UP, 9);
|
||||||
item->Pose.Position.x += coll->Shift.x;
|
item->Pose.Position.x += coll->Shift.Position.x;
|
||||||
item->Pose.Position.y += GameBoundingBox(item).Y2 * 1.8f;
|
item->Pose.Position.y += GameBoundingBox(item).Y2 * 1.8f;
|
||||||
item->Pose.Position.z += coll->Shift.z;
|
item->Pose.Position.z += coll->Shift.Position.z;
|
||||||
item->Animation.IsAirborne = true;
|
item->Animation.IsAirborne = true;
|
||||||
item->Animation.Velocity.z = 2;
|
item->Animation.Velocity.z = 2;
|
||||||
item->Animation.Velocity.y = 1;
|
item->Animation.Velocity.y = 1;
|
||||||
|
@ -472,12 +472,12 @@ bool TestLaraHangOnClimbableWall(ItemInfo* item, CollisionInfo* coll)
|
||||||
{
|
{
|
||||||
case NORTH:
|
case NORTH:
|
||||||
case SOUTH:
|
case SOUTH:
|
||||||
item->Pose.Position.z += coll2.Shift.z;
|
item->Pose.Position.z += coll2.Shift.Position.z;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EAST:
|
case EAST:
|
||||||
case WEST:
|
case WEST:
|
||||||
item->Pose.Position.x += coll2.Shift.x;
|
item->Pose.Position.x += coll2.Shift.Position.x;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -753,6 +753,54 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool ena
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simplified version of ItemPushItem for basic pushes.
|
||||||
|
bool ItemPushItem(ItemInfo* item, ItemInfo* item2)
|
||||||
|
{
|
||||||
|
float sinY = phd_sin(item->Pose.Orientation.y);
|
||||||
|
float cosY = phd_cos(item->Pose.Orientation.y);
|
||||||
|
|
||||||
|
// Get direction vector from item to player.
|
||||||
|
auto direction = item2->Pose.Position - item->Pose.Position;
|
||||||
|
|
||||||
|
// Rotate Lara vector into item frame.
|
||||||
|
int rx = (direction.x * cosY) - (direction.z * sinY);
|
||||||
|
int rz = (direction.z * cosY) + (direction.x * sinY);
|
||||||
|
|
||||||
|
const auto& bounds = GetBestFrame(*item).BoundingBox;
|
||||||
|
|
||||||
|
int minX = bounds.X1;
|
||||||
|
int maxX = bounds.X2;
|
||||||
|
int minZ = bounds.Z1;
|
||||||
|
int maxZ = bounds.Z2;
|
||||||
|
|
||||||
|
// Big enemies
|
||||||
|
if (abs(direction.x) > BLOCK(4.5f) || abs(direction.z) > BLOCK(4.5f) ||
|
||||||
|
rx <= minX || rx >= maxX ||
|
||||||
|
rz <= minZ || rz >= maxZ)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = rx - minX;
|
||||||
|
int top = maxZ - rz;
|
||||||
|
int bottom = rz - minZ;
|
||||||
|
int right = maxX - rx;
|
||||||
|
|
||||||
|
if (right <= left && right <= top && right <= bottom)
|
||||||
|
rx += right;
|
||||||
|
else if (left <= right && left <= top && left <= bottom)
|
||||||
|
rx -= left;
|
||||||
|
else if (top <= left && top <= right && top <= bottom)
|
||||||
|
rz += top;
|
||||||
|
else
|
||||||
|
rz -= bottom;
|
||||||
|
|
||||||
|
item2->Pose.Position.x = item->Pose.Position.x + (rx * cosY) + (rz * sinY);
|
||||||
|
item2->Pose.Position.z = item->Pose.Position.z + (rz * cosY) - (rx * sinY);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: Previously ItemPushLaraStatic().
|
// NOTE: Previously ItemPushLaraStatic().
|
||||||
bool ItemPushStatic(ItemInfo* item, const MESH_INFO& mesh, CollisionInfo* coll)
|
bool ItemPushStatic(ItemInfo* item, const MESH_INFO& mesh, CollisionInfo* coll)
|
||||||
{
|
{
|
||||||
|
@ -828,6 +876,62 @@ bool ItemPushStatic(ItemInfo* item, const MESH_INFO& mesh, CollisionInfo* coll)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ItemPushBridge(ItemInfo& item, CollisionInfo& coll)
|
||||||
|
{
|
||||||
|
coll.Setup.ForwardAngle = item.Pose.Orientation.y;
|
||||||
|
coll.Setup.OldPosition = item.Pose.Position;
|
||||||
|
GetCollisionInfo(&coll, &item);
|
||||||
|
ShiftItem(&item, &coll);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& collResult)
|
||||||
|
{
|
||||||
|
// Store an offset for a bridge item into shifts, if exists.
|
||||||
|
if (coll.LastBridgeItemNumber == collResult.Position.Bridge && coll.LastBridgeItemNumber != NO_ITEM)
|
||||||
|
{
|
||||||
|
auto& bridgeItem = g_Level.Items[collResult.Position.Bridge];
|
||||||
|
|
||||||
|
auto deltaPos = bridgeItem.Pose.Position - coll.LastBridgeItemPose.Position;
|
||||||
|
auto deltaOrient = bridgeItem.Pose.Orientation - coll.LastBridgeItemPose.Orientation;
|
||||||
|
auto deltaPose = Pose(deltaPos, deltaOrient);
|
||||||
|
|
||||||
|
int absDeltaHeight = item.Pose.Position.y - collResult.Position.Floor;
|
||||||
|
int relDeltaHeight = absDeltaHeight + GameBoundingBox(&item).Y2;
|
||||||
|
|
||||||
|
if (deltaPose != Pose::Zero &&
|
||||||
|
(abs(absDeltaHeight) <= CLICK(1 / 8.0f) || abs(relDeltaHeight) <= CLICK(1 / 8.0f)))
|
||||||
|
{
|
||||||
|
const auto& bridgePos = bridgeItem.Pose.Position;
|
||||||
|
|
||||||
|
// Calculate offset.
|
||||||
|
auto relOffset = (item.Pose.Position - bridgePos).ToVector3();
|
||||||
|
auto rotMatrix = deltaPose.Orientation.ToRotationMatrix();
|
||||||
|
auto offset = bridgePos.ToVector3() + Vector3::Transform(relOffset, rotMatrix);
|
||||||
|
|
||||||
|
deltaPose.Position -= item.Pose.Position - Vector3i(offset);
|
||||||
|
|
||||||
|
// Don't update shifts if difference is too big (possibly bridge was teleported or just entered bridge).
|
||||||
|
if (deltaPose.Position.ToVector3().Length() <= coll.Setup.Radius * 2)
|
||||||
|
coll.Shift = deltaPose;
|
||||||
|
}
|
||||||
|
else if (deltaPos.ToVector3().Length() <= coll.Setup.Radius && relDeltaHeight > 0 &&
|
||||||
|
(deltaPos != Vector3i::Zero || deltaOrient != EulerAngles::Zero))
|
||||||
|
{
|
||||||
|
// Push item away if not directly above bridge, and bridge position was changed.
|
||||||
|
ItemPushItem(&bridgeItem, &item);
|
||||||
|
}
|
||||||
|
|
||||||
|
coll.LastBridgeItemPose = bridgeItem.Pose;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
coll.LastBridgeItemPose = Pose::Zero;
|
||||||
|
coll.LastBridgeItemNumber = NO_ITEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
coll.LastBridgeItemNumber = collResult.Position.Bridge;
|
||||||
|
}
|
||||||
|
|
||||||
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll)
|
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll)
|
||||||
{
|
{
|
||||||
coll->HitTallObject = false;
|
coll->HitTallObject = false;
|
||||||
|
@ -1057,20 +1161,20 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
|
||||||
case NORTH:
|
case NORTH:
|
||||||
if (rawShift.x > coll->Setup.Radius || rawShift.x < -coll->Setup.Radius)
|
if (rawShift.x > coll->Setup.Radius || rawShift.x < -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.z = rawShift.z;
|
coll->Shift.Position.z = rawShift.z;
|
||||||
coll->Shift.x = ox - x;
|
coll->Shift.Position.x = ox - x;
|
||||||
coll->CollisionType = CT_FRONT;
|
coll->CollisionType = CT_FRONT;
|
||||||
}
|
}
|
||||||
else if (rawShift.x > 0 && rawShift.x <= coll->Setup.Radius)
|
else if (rawShift.x > 0 && rawShift.x <= coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.x = rawShift.x;
|
coll->Shift.Position.x = rawShift.x;
|
||||||
coll->Shift.z = 0;
|
coll->Shift.Position.z = 0;
|
||||||
coll->CollisionType = CT_LEFT;
|
coll->CollisionType = CT_LEFT;
|
||||||
}
|
}
|
||||||
else if (rawShift.x < 0 && rawShift.x >= -coll->Setup.Radius)
|
else if (rawShift.x < 0 && rawShift.x >= -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.x = rawShift.x;
|
coll->Shift.Position.x = rawShift.x;
|
||||||
coll->Shift.z = 0;
|
coll->Shift.Position.z = 0;
|
||||||
coll->CollisionType = CT_RIGHT;
|
coll->CollisionType = CT_RIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1079,20 +1183,20 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
|
||||||
case SOUTH:
|
case SOUTH:
|
||||||
if (rawShift.x > coll->Setup.Radius || rawShift.x < -coll->Setup.Radius)
|
if (rawShift.x > coll->Setup.Radius || rawShift.x < -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.z = rawShift.z;
|
coll->Shift.Position.z = rawShift.z;
|
||||||
coll->Shift.x = ox - x;
|
coll->Shift.Position.x = ox - x;
|
||||||
coll->CollisionType = CT_FRONT;
|
coll->CollisionType = CT_FRONT;
|
||||||
}
|
}
|
||||||
else if (rawShift.x > 0 && rawShift.x <= coll->Setup.Radius)
|
else if (rawShift.x > 0 && rawShift.x <= coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.x = rawShift.x;
|
coll->Shift.Position.x = rawShift.x;
|
||||||
coll->Shift.z = 0;
|
coll->Shift.Position.z = 0;
|
||||||
coll->CollisionType = CT_RIGHT;
|
coll->CollisionType = CT_RIGHT;
|
||||||
}
|
}
|
||||||
else if (rawShift.x < 0 && rawShift.x >= -coll->Setup.Radius)
|
else if (rawShift.x < 0 && rawShift.x >= -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.x = rawShift.x;
|
coll->Shift.Position.x = rawShift.x;
|
||||||
coll->Shift.z = 0;
|
coll->Shift.Position.z = 0;
|
||||||
coll->CollisionType = CT_LEFT;
|
coll->CollisionType = CT_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1101,20 +1205,20 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
|
||||||
case EAST:
|
case EAST:
|
||||||
if (rawShift.z > coll->Setup.Radius || rawShift.z < -coll->Setup.Radius)
|
if (rawShift.z > coll->Setup.Radius || rawShift.z < -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.x = rawShift.x;
|
coll->Shift.Position.x = rawShift.x;
|
||||||
coll->Shift.z = oz - z;
|
coll->Shift.Position.z = oz - z;
|
||||||
coll->CollisionType = CT_FRONT;
|
coll->CollisionType = CT_FRONT;
|
||||||
}
|
}
|
||||||
else if (rawShift.z > 0 && rawShift.z <= coll->Setup.Radius)
|
else if (rawShift.z > 0 && rawShift.z <= coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.z = rawShift.z;
|
coll->Shift.Position.z = rawShift.z;
|
||||||
coll->Shift.x = 0;
|
coll->Shift.Position.x = 0;
|
||||||
coll->CollisionType = CT_RIGHT;
|
coll->CollisionType = CT_RIGHT;
|
||||||
}
|
}
|
||||||
else if (rawShift.z < 0 && rawShift.z >= -coll->Setup.Radius)
|
else if (rawShift.z < 0 && rawShift.z >= -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.z = rawShift.z;
|
coll->Shift.Position.z = rawShift.z;
|
||||||
coll->Shift.x = 0;
|
coll->Shift.Position.x = 0;
|
||||||
coll->CollisionType = CT_LEFT;
|
coll->CollisionType = CT_LEFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1123,20 +1227,20 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
|
||||||
case WEST:
|
case WEST:
|
||||||
if (rawShift.z > coll->Setup.Radius || rawShift.z < -coll->Setup.Radius)
|
if (rawShift.z > coll->Setup.Radius || rawShift.z < -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.x = rawShift.x;
|
coll->Shift.Position.x = rawShift.x;
|
||||||
coll->Shift.z = oz - z;
|
coll->Shift.Position.z = oz - z;
|
||||||
coll->CollisionType = CT_FRONT;
|
coll->CollisionType = CT_FRONT;
|
||||||
}
|
}
|
||||||
else if (rawShift.z > 0 && rawShift.z <= coll->Setup.Radius)
|
else if (rawShift.z > 0 && rawShift.z <= coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.z = rawShift.z;
|
coll->Shift.Position.z = rawShift.z;
|
||||||
coll->Shift.x = 0;
|
coll->Shift.Position.x = 0;
|
||||||
coll->CollisionType = CT_LEFT;
|
coll->CollisionType = CT_LEFT;
|
||||||
}
|
}
|
||||||
else if (rawShift.z < 0 && rawShift.z >= -coll->Setup.Radius)
|
else if (rawShift.z < 0 && rawShift.z >= -coll->Setup.Radius)
|
||||||
{
|
{
|
||||||
coll->Shift.z = rawShift.z;
|
coll->Shift.Position.z = rawShift.z;
|
||||||
coll->Shift.x = 0;
|
coll->Shift.Position.x = 0;
|
||||||
coll->CollisionType = CT_RIGHT;
|
coll->CollisionType = CT_RIGHT;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1144,15 +1248,15 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose&
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine final shifts orientation/distance.
|
// Determine final shifts orientation/distance.
|
||||||
distance = Vector3(x + coll->Shift.x, y, z + coll->Shift.z) - pose.Position.ToVector3();
|
distance = Vector3(x + coll->Shift.Position.x, y, z + coll->Shift.Position.z) - pose.Position.ToVector3();
|
||||||
sinY = phd_sin(-pose.Orientation.y);
|
sinY = phd_sin(-pose.Orientation.y);
|
||||||
cosY = phd_cos(-pose.Orientation.y);
|
cosY = phd_cos(-pose.Orientation.y);
|
||||||
|
|
||||||
// Calculate final shifts orientation/distance.
|
// Calculate final shifts orientation/distance.
|
||||||
coll->Shift.x = (round((distance.x * cosY) - (distance.z * sinY)) + pose.Position.x) - item->Pose.Position.x;
|
coll->Shift.Position.x = (round((distance.x * cosY) - (distance.z * sinY)) + pose.Position.x) - item->Pose.Position.x;
|
||||||
coll->Shift.z = (round((distance.x * sinY) + (distance.z * cosY)) + pose.Position.z) - item->Pose.Position.z;
|
coll->Shift.Position.z = (round((distance.x * sinY) + (distance.z * cosY)) + pose.Position.z) - item->Pose.Position.z;
|
||||||
|
|
||||||
if (coll->Shift.x == 0 && coll->Shift.z == 0)
|
if (coll->Shift.Position.x == 0 && coll->Shift.Position.z == 0)
|
||||||
coll->CollisionType = CT_NONE; // Paranoid.
|
coll->CollisionType = CT_NONE; // Paranoid.
|
||||||
|
|
||||||
// Set splat state flag if item is Lara and bounds are taller than Lara's headroom.
|
// Set splat state flag if item is Lara and bounds are taller than Lara's headroom.
|
||||||
|
@ -1838,7 +1942,7 @@ void ObjectCollision(const short itemNumber, ItemInfo* laraItem, CollisionInfo*
|
||||||
if (TestCollision(item, laraItem))
|
if (TestCollision(item, laraItem))
|
||||||
{
|
{
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(item, laraItem, coll, false, true);
|
ItemPushItem(item, laraItem, coll, false, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
|
|
||||||
using std::pair;
|
|
||||||
|
|
||||||
class FloorInfo;
|
class FloorInfo;
|
||||||
struct CollisionInfo;
|
struct CollisionInfo;
|
||||||
|
struct CollisionResult;
|
||||||
struct ItemInfo;
|
struct ItemInfo;
|
||||||
struct MESH_INFO;
|
struct MESH_INFO;
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ extern MESH_INFO* CollidedMeshes[MAX_COLLIDED_OBJECTS];
|
||||||
struct ObjectCollisionBounds
|
struct ObjectCollisionBounds
|
||||||
{
|
{
|
||||||
GameBoundingBox BoundingBox = GameBoundingBox::Zero;
|
GameBoundingBox BoundingBox = GameBoundingBox::Zero;
|
||||||
pair<EulerAngles, EulerAngles> OrientConstraint = {};
|
std::pair<EulerAngles, EulerAngles> OrientConstraint = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
void GenericSphereBoxCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
||||||
|
@ -40,10 +39,13 @@ bool Move3DPosTo3DPos(ItemInfo* item, Pose& fromPose, const Pose& toPose, int ve
|
||||||
bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius);
|
bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius);
|
||||||
bool TestBoundsCollideStatic(ItemInfo* item, const MESH_INFO& mesh, int radius);
|
bool TestBoundsCollideStatic(ItemInfo* item, const MESH_INFO& mesh, int radius);
|
||||||
bool ItemPushItem(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll, bool enableSpasm, char bigPush);
|
bool ItemPushItem(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll, bool enableSpasm, char bigPush);
|
||||||
|
bool ItemPushItem(ItemInfo* item, ItemInfo* item2);
|
||||||
bool ItemPushStatic(ItemInfo* laraItem, const MESH_INFO& mesh, CollisionInfo* coll);
|
bool ItemPushStatic(ItemInfo* laraItem, const MESH_INFO& mesh, CollisionInfo* coll);
|
||||||
|
void ItemPushBridge(ItemInfo& item, CollisionInfo& coll);
|
||||||
|
|
||||||
bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose& pose, CollisionInfo* coll);
|
bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose& pose, CollisionInfo* coll);
|
||||||
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll);
|
void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll);
|
||||||
|
void CollideBridgeItems(ItemInfo& item, CollisionInfo& coll, const CollisionResult& collResult);
|
||||||
|
|
||||||
void AIPickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
void AIPickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
||||||
void ObjectCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
void ObjectCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
|
||||||
|
|
|
@ -18,7 +18,8 @@ using namespace TEN::Renderer;
|
||||||
|
|
||||||
void ShiftItem(ItemInfo* item, CollisionInfo* coll)
|
void ShiftItem(ItemInfo* item, CollisionInfo* coll)
|
||||||
{
|
{
|
||||||
item->Pose.Position += coll->Shift;
|
item->Pose.Position += coll->Shift.Position;
|
||||||
|
item->Pose.Orientation += coll->Shift.Orientation;
|
||||||
coll->Shift = Vector3i::Zero;
|
coll->Shift = Vector3i::Zero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +228,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
|
|
||||||
// Reset collision parameters.
|
// Reset collision parameters.
|
||||||
coll->CollisionType = CollisionType::CT_NONE;
|
coll->CollisionType = CollisionType::CT_NONE;
|
||||||
coll->Shift = Vector3i::Zero;
|
coll->Shift = Pose::Zero;
|
||||||
|
|
||||||
// Offset base probe position by provided offset, if any.
|
// Offset base probe position by provided offset, if any.
|
||||||
auto entityPos = item->Pose.Position + offset;
|
auto entityPos = item->Pose.Position + offset;
|
||||||
|
@ -348,6 +349,9 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
coll->Middle.Floor = height;
|
coll->Middle.Floor = height;
|
||||||
coll->Middle.Ceiling = ceiling;
|
coll->Middle.Ceiling = ceiling;
|
||||||
|
|
||||||
|
// Additionally calculate bridge shifts, if present.
|
||||||
|
CollideBridgeItems(*item, *coll, collResult);
|
||||||
|
|
||||||
// TEST 3: FRONTAL PROBE
|
// TEST 3: FRONTAL PROBE
|
||||||
|
|
||||||
probePos.x = entityPos.x + xFront;
|
probePos.x = entityPos.x + xFront;
|
||||||
|
@ -698,21 +702,21 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
|
|
||||||
if (coll->Middle.Floor == NO_HEIGHT)
|
if (coll->Middle.Floor == NO_HEIGHT)
|
||||||
{
|
{
|
||||||
coll->Shift = coll->Setup.OldPosition - entityPos;
|
coll->Shift.Position += coll->Setup.OldPosition - entityPos;
|
||||||
coll->CollisionType = CT_FRONT;
|
coll->CollisionType = CT_FRONT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coll->Middle.Floor - coll->Middle.Ceiling <= 0)
|
if (coll->Middle.Floor - coll->Middle.Ceiling <= 0)
|
||||||
{
|
{
|
||||||
coll->Shift = coll->Setup.OldPosition - entityPos;
|
coll->Shift.Position += coll->Setup.OldPosition - entityPos;
|
||||||
coll->CollisionType = CT_CLAMP;
|
coll->CollisionType = CT_CLAMP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (coll->Middle.Ceiling >= 0)
|
if (coll->Middle.Ceiling >= 0)
|
||||||
{
|
{
|
||||||
coll->Shift.y = coll->Middle.Ceiling;
|
coll->Shift.Position.y += coll->Middle.Ceiling;
|
||||||
coll->CollisionType = CT_TOP;
|
coll->CollisionType = CT_TOP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -724,8 +728,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
{
|
{
|
||||||
if (coll->Front.HasDiagonalSplit())
|
if (coll->Front.HasDiagonalSplit())
|
||||||
{
|
{
|
||||||
coll->Shift.x = coll->Setup.OldPosition.x - entityPos.x;
|
coll->Shift.Position.x += coll->Setup.OldPosition.x - entityPos.x;
|
||||||
coll->Shift.z = coll->Setup.OldPosition.z - entityPos.z;
|
coll->Shift.Position.z += coll->Setup.OldPosition.z - entityPos.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -733,14 +737,14 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
coll->Shift.x = coll->Setup.OldPosition.x - entityPos.x;
|
coll->Shift.Position.x += coll->Setup.OldPosition.x - entityPos.x;
|
||||||
coll->Shift.z = FindGridShift(entityPos.z + zFront, entityPos.z);
|
coll->Shift.Position.z += FindGridShift(entityPos.z + zFront, entityPos.z);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
coll->Shift.x = FindGridShift(entityPos.x + xFront, entityPos.x);
|
coll->Shift.Position.x += FindGridShift(entityPos.x + xFront, entityPos.x);
|
||||||
coll->Shift.z = coll->Setup.OldPosition.z - entityPos.z;
|
coll->Shift.Position.z += coll->Setup.OldPosition.z - entityPos.z;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -752,7 +756,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
if (coll->Front.Ceiling > coll->Setup.LowerCeilingBound ||
|
if (coll->Front.Ceiling > coll->Setup.LowerCeilingBound ||
|
||||||
coll->Front.Ceiling < coll->Setup.UpperCeilingBound)
|
coll->Front.Ceiling < coll->Setup.UpperCeilingBound)
|
||||||
{
|
{
|
||||||
coll->Shift = coll->Setup.OldPosition - entityPos;
|
coll->Shift.Position += coll->Setup.OldPosition - entityPos;
|
||||||
coll->CollisionType = CT_TOP_FRONT;
|
coll->CollisionType = CT_TOP_FRONT;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -768,8 +772,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
// HACK: Force slight push-out to the left side to avoid stucking
|
// HACK: Force slight push-out to the left side to avoid stucking
|
||||||
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(8.0f), item->Animation.Velocity.z);
|
TranslateItem(item, coll->Setup.ForwardAngle + ANGLE(8.0f), item->Animation.Velocity.z);
|
||||||
|
|
||||||
coll->Shift.x = coll->Setup.OldPosition.x - entityPos.x;
|
coll->Shift.Position.x += coll->Setup.OldPosition.x - entityPos.x;
|
||||||
coll->Shift.z = coll->Setup.OldPosition.z - entityPos.z;
|
coll->Shift.Position.z += coll->Setup.OldPosition.z - entityPos.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -777,12 +781,12 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
coll->Shift.x = FindGridShift(entityPos.x + xLeft, entityPos.x + xFront);
|
coll->Shift.Position.x += FindGridShift(entityPos.x + xLeft, entityPos.x + xFront);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
coll->Shift.z = FindGridShift(entityPos.z + zLeft, entityPos.z + zFront);
|
coll->Shift.Position.z += FindGridShift(entityPos.z + zLeft, entityPos.z + zFront);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -822,8 +826,8 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
// HACK: Force slight push out to the right side to avoid getting stuck.
|
// HACK: Force slight push out to the right side to avoid getting stuck.
|
||||||
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(8.0f), item->Animation.Velocity.z);
|
TranslateItem(item, coll->Setup.ForwardAngle - ANGLE(8.0f), item->Animation.Velocity.z);
|
||||||
|
|
||||||
coll->Shift.x = coll->Setup.OldPosition.x - entityPos.x;
|
coll->Shift.Position.x += coll->Setup.OldPosition.x - entityPos.x;
|
||||||
coll->Shift.z = coll->Setup.OldPosition.z - entityPos.z;
|
coll->Shift.Position.z += coll->Setup.OldPosition.z - entityPos.z;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -831,12 +835,12 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
case 2:
|
case 2:
|
||||||
coll->Shift.x = FindGridShift(entityPos.x + xRight, entityPos.x + xFront);
|
coll->Shift.Position.x += FindGridShift(entityPos.x + xRight, entityPos.x + xFront);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
coll->Shift.z = FindGridShift(entityPos.z + zRight, entityPos.z + zFront);
|
coll->Shift.Position.z += FindGridShift(entityPos.z + zRight, entityPos.z + zFront);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Math/Math.h"
|
#include "Math/Math.h"
|
||||||
#include "Objects/game_object_ids.h"
|
#include "Objects/game_object_ids.h"
|
||||||
|
|
||||||
struct ItemInfo;
|
struct ItemInfo;
|
||||||
struct CollisionInfo;
|
|
||||||
class FloorInfo;
|
class FloorInfo;
|
||||||
struct ROOM_INFO;
|
struct ROOM_INFO;
|
||||||
struct MESH_INFO;
|
struct MESH_INFO;
|
||||||
|
@ -105,13 +105,16 @@ struct CollisionInfo
|
||||||
CollisionPosition FrontLeft;
|
CollisionPosition FrontLeft;
|
||||||
CollisionPosition FrontRight;
|
CollisionPosition FrontRight;
|
||||||
|
|
||||||
Vector3i Shift;
|
Pose Shift = Pose::Zero;
|
||||||
CollisionType CollisionType;
|
CollisionType CollisionType;
|
||||||
Vector2 FloorTilt; // x = x, y = z
|
Vector2 FloorTilt; // x = x, y = z
|
||||||
Vector2 CeilingTilt; // x = x, y = z
|
Vector2 CeilingTilt; // x = x, y = z
|
||||||
short NearestLedgeAngle;
|
short NearestLedgeAngle;
|
||||||
float NearestLedgeDistance;
|
float NearestLedgeDistance;
|
||||||
|
|
||||||
|
int LastBridgeItemNumber;
|
||||||
|
Pose LastBridgeItemPose;
|
||||||
|
|
||||||
bool HitStatic;
|
bool HitStatic;
|
||||||
bool HitTallObject;
|
bool HitTallObject;
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <variant>
|
#include <variant>
|
||||||
|
|
||||||
|
#include "Game/collision/collide_room.h"
|
||||||
#include "Game/itemdata/creature_info.h"
|
#include "Game/itemdata/creature_info.h"
|
||||||
#include "Game/itemdata/door_data.h"
|
#include "Game/itemdata/door_data.h"
|
||||||
#include "Game/Lara/lara_struct.h"
|
#include "Game/Lara/lara_struct.h"
|
||||||
|
@ -56,6 +57,7 @@ class ItemData
|
||||||
PushableInfo,
|
PushableInfo,
|
||||||
ItemInfo*,
|
ItemInfo*,
|
||||||
LaraInfo*,
|
LaraInfo*,
|
||||||
|
CollisionInfo,
|
||||||
CreatureInfo,
|
CreatureInfo,
|
||||||
WraithInfo,
|
WraithInfo,
|
||||||
GuardianInfo,
|
GuardianInfo,
|
||||||
|
|
|
@ -959,6 +959,8 @@ void PickupControl(short itemNumber)
|
||||||
{
|
{
|
||||||
auto* item = &g_Level.Items[itemNumber];
|
auto* item = &g_Level.Items[itemNumber];
|
||||||
|
|
||||||
|
ItemPushBridge(*item, *(CollisionInfo*)item->Data);
|
||||||
|
|
||||||
short roomNumber;
|
short roomNumber;
|
||||||
short triggerFlags = item->TriggerFlags & 0x3F;
|
short triggerFlags = item->TriggerFlags & 0x3F;
|
||||||
|
|
||||||
|
@ -1056,9 +1058,13 @@ const GameBoundingBox* FindPlinth(ItemInfo* item)
|
||||||
void InitializePickup(short itemNumber)
|
void InitializePickup(short itemNumber)
|
||||||
{
|
{
|
||||||
auto* item = &g_Level.Items[itemNumber];
|
auto* item = &g_Level.Items[itemNumber];
|
||||||
|
|
||||||
auto bounds = GameBoundingBox(item);
|
auto bounds = GameBoundingBox(item);
|
||||||
|
|
||||||
|
item->Data = CollisionInfo();
|
||||||
|
auto* coll = (CollisionInfo*)item->Data;
|
||||||
|
coll->Setup.Radius = std::max(bounds.GetWidth(), bounds.GetDepth());
|
||||||
|
coll->Setup.Height = bounds.GetHeight();
|
||||||
|
|
||||||
short triggerFlags = item->TriggerFlags & 0x3F;
|
short triggerFlags = item->TriggerFlags & 0x3F;
|
||||||
if (triggerFlags == 5)
|
if (triggerFlags == 5)
|
||||||
{
|
{
|
||||||
|
|
|
@ -253,7 +253,7 @@ namespace TEN::Entities::Doors
|
||||||
if (!(doorItem->ObjectNumber >= ID_LIFT_DOORS1 &&
|
if (!(doorItem->ObjectNumber >= ID_LIFT_DOORS1 &&
|
||||||
doorItem->ObjectNumber <= ID_LIFT_DOORS2) || doorItem->ItemFlags[0])
|
doorItem->ObjectNumber <= ID_LIFT_DOORS2) || doorItem->ItemFlags[0])
|
||||||
{
|
{
|
||||||
ItemPushItem(doorItem, laraItem, coll, FALSE, TRUE);
|
ItemPushItem(doorItem, laraItem, coll, false, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -112,7 +112,7 @@ namespace TEN::Entities::Traps::TR1
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(&item, laraItem, coll, false, true);
|
ItemPushItem(&item, laraItem, coll, false, 1);
|
||||||
|
|
||||||
if (item.Animation.IsAirborne)
|
if (item.Animation.IsAirborne)
|
||||||
{
|
{
|
||||||
|
|
|
@ -184,7 +184,7 @@ namespace TEN::Entities::Vehicles
|
||||||
{
|
{
|
||||||
// HACK: Collision in water behaves differently? @Sezz 2022.06.28
|
// HACK: Collision in water behaves differently? @Sezz 2022.06.28
|
||||||
if (TestBoundsCollide(UPVItem, laraItem, coll->Setup.Radius) && TestCollision(UPVItem, laraItem))
|
if (TestBoundsCollide(UPVItem, laraItem, coll->Setup.Radius) && TestCollision(UPVItem, laraItem))
|
||||||
ItemPushItem(UPVItem, laraItem, coll, false, false);
|
ItemPushItem(UPVItem, laraItem, coll, false, 0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -152,7 +152,7 @@ namespace TEN::Entities::TR4
|
||||||
if (TestCollision(item, laraItem))
|
if (TestCollision(item, laraItem))
|
||||||
{
|
{
|
||||||
if (coll->Setup.EnableObjectPush)
|
if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(item, laraItem, coll, 0, 0);
|
ItemPushItem(item, laraItem, coll, false, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,17 +106,17 @@ void ScalesCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
|
||||||
GlobalCollisionBounds.Z1 = -256;
|
GlobalCollisionBounds.Z1 = -256;
|
||||||
GlobalCollisionBounds.Z2 = 384;
|
GlobalCollisionBounds.Z2 = 384;
|
||||||
|
|
||||||
ItemPushItem(item, laraItem, coll, 0, 2);
|
ItemPushItem(item, laraItem, coll, false, 2);
|
||||||
|
|
||||||
GlobalCollisionBounds.X1 = -256;
|
GlobalCollisionBounds.X1 = -256;
|
||||||
GlobalCollisionBounds.X2 = 256;
|
GlobalCollisionBounds.X2 = 256;
|
||||||
|
|
||||||
ItemPushItem(item, laraItem, coll, 0, 2);
|
ItemPushItem(item, laraItem, coll, false, 2);
|
||||||
|
|
||||||
GlobalCollisionBounds.X1 = -1280;
|
GlobalCollisionBounds.X1 = -1280;
|
||||||
GlobalCollisionBounds.X2 = -640;
|
GlobalCollisionBounds.X2 = -640;
|
||||||
|
|
||||||
ItemPushItem(item, laraItem, coll, 0, 2);
|
ItemPushItem(item, laraItem, coll, false, 2);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace TEN::Entities::TR4
|
||||||
int dy = 0;
|
int dy = 0;
|
||||||
int dz = 0;
|
int dz = 0;
|
||||||
|
|
||||||
if (ItemPushItem(bladeItem, laraItem, coll, 1, 1))
|
if (ItemPushItem(bladeItem, laraItem, coll, true, 1))
|
||||||
{
|
{
|
||||||
DoDamage(laraItem, bladeItem->ItemFlags[3]);
|
DoDamage(laraItem, bladeItem->ItemFlags[3]);
|
||||||
|
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace TEN::Entities::TR4
|
||||||
DoDamage(laraItem, 10);
|
DoDamage(laraItem, 10);
|
||||||
}
|
}
|
||||||
else if (coll->Setup.EnableObjectPush)
|
else if (coll->Setup.EnableObjectPush)
|
||||||
ItemPushItem(cogItem, laraItem, coll, 0, 0);
|
ItemPushItem(cogItem, laraItem, coll, false, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ namespace TEN::Entities::Traps
|
||||||
GlobalCollisionBounds.Z1 = bounds.z;
|
GlobalCollisionBounds.Z1 = bounds.z;
|
||||||
|
|
||||||
if (TestWithGlobalCollisionBounds(item, laraItem, coll))
|
if (TestWithGlobalCollisionBounds(item, laraItem, coll))
|
||||||
ItemPushItem(item, laraItem, coll, 0, 2);
|
ItemPushItem(item, laraItem, coll, false, 2);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "framework.h"
|
#include "framework.h"
|
||||||
|
|
||||||
#include "Game/items.h"
|
#include "Game/items.h"
|
||||||
|
#include "Game/collision/floordata.h"
|
||||||
#include "Game/control/lot.h"
|
#include "Game/control/lot.h"
|
||||||
#include "Game/effects/debris.h"
|
#include "Game/effects/debris.h"
|
||||||
#include "Game/effects/item_fx.h"
|
#include "Game/effects/item_fx.h"
|
||||||
|
@ -21,6 +22,7 @@
|
||||||
#include "Scripting/Internal/TEN/Rotation/Rotation.h"
|
#include "Scripting/Internal/TEN/Rotation/Rotation.h"
|
||||||
#include "Scripting/Internal/TEN/Vec3/Vec3.h"
|
#include "Scripting/Internal/TEN/Vec3/Vec3.h"
|
||||||
|
|
||||||
|
using namespace TEN::Collision::Floordata;
|
||||||
using namespace TEN::Effects::Items;
|
using namespace TEN::Effects::Items;
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -576,6 +578,10 @@ void Moveable::SetPos(Vec3 const& pos, sol::optional<bool> updateRoom)
|
||||||
SetRoomNumber(potentialNewRoom);
|
SetRoomNumber(potentialNewRoom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto& object = Objects[m_item->ObjectNumber];
|
||||||
|
if (object.floor != nullptr || object.ceiling != nullptr)
|
||||||
|
UpdateBridgeItem((int)m_item->Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vec3 Moveable::GetJointPos(int jointIndex) const
|
Vec3 Moveable::GetJointPos(int jointIndex) const
|
||||||
|
@ -598,11 +604,15 @@ Rotation Moveable::GetRot() const
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Moveable::SetRot(Rotation const& rot)
|
void Moveable::SetRot(const Rotation& rot)
|
||||||
{
|
{
|
||||||
m_item->Pose.Orientation.x = ANGLE(rot.x);
|
m_item->Pose.Orientation.x = ANGLE(rot.x);
|
||||||
m_item->Pose.Orientation.y = ANGLE(rot.y);
|
m_item->Pose.Orientation.y = ANGLE(rot.y);
|
||||||
m_item->Pose.Orientation.z = ANGLE(rot.z);
|
m_item->Pose.Orientation.z = ANGLE(rot.z);
|
||||||
|
|
||||||
|
const auto& object = Objects[m_item->ObjectNumber];
|
||||||
|
if (object.floor != nullptr || object.ceiling != nullptr)
|
||||||
|
UpdateBridgeItem(m_item->Index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get current HP (hit points/health points)
|
/// Get current HP (hit points/health points)
|
||||||
|
|
|
@ -187,9 +187,18 @@ void LoadItems()
|
||||||
memcpy(&item->StartPose, &item->Pose, sizeof(Pose));
|
memcpy(&item->StartPose, &item->Pose, sizeof(Pose));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initialize all bridges first.
|
||||||
|
// It is needed because some other items need final floor height to init properly.
|
||||||
|
|
||||||
|
for (int isFloor = 0; isFloor <= 1; isFloor++)
|
||||||
|
{
|
||||||
for (int i = 0; i < g_Level.NumItems; i++)
|
for (int i = 0; i < g_Level.NumItems; i++)
|
||||||
|
{
|
||||||
|
if ((Objects[g_Level.Items[i].ObjectNumber].floor == nullptr) == (bool)isFloor)
|
||||||
InitializeItem(i);
|
InitializeItem(i);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadObjects()
|
void LoadObjects()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue