From a3bc674c255f7cc57c0cbfd7dd0eb2403e307385 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Thu, 10 Oct 2024 14:15:43 +0300
Subject: [PATCH 1/5] Fixed LOS and laserhead player teleportation/invisibility
(#1416)
---
CHANGELOG.md | 2 +
TombEngine/Game/control/los.cpp | 84 ++-----------------
.../Objects/TR5/Entity/tr5_laser_head.cpp | 10 ++-
.../Objects/TR5/Entity/tr5_laserhead_info.h | 1 -
4 files changed, 15 insertions(+), 82 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 12f2bfe14..be12a6acd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,8 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
### Bug fixes
* Fixed original issue with classic switch off trigger incorrectly activating some trigger actions.
* Fixed leveljump vehicle transfer.
+* Fixed weapons not properly hitting enemies.
+* Fixed laserhead teleporting Lara and making her invisible on death.
* Fixed sarcophagus pick-ups.
* Fixed several binocular bugs.
* Fixed incorrect climbing out of water on bridge objects.
diff --git a/TombEngine/Game/control/los.cpp b/TombEngine/Game/control/los.cpp
index 61fc6a5e6..7cd0b2c5f 100644
--- a/TombEngine/Game/control/los.cpp
+++ b/TombEngine/Game/control/los.cpp
@@ -312,7 +312,7 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo
ShatterImpactData.impactDirection = dir;
ShatterImpactData.impactLocation = ShatterItem.sphere.Center;
ShatterObject(&ShatterItem, 0, 128, target2.RoomNumber, 0);
- TriggerRicochetSpark(target2, LaraItem->Pose.Orientation.y, 3, 0);
+ TriggerRicochetSpark(target2, LaraItem->Pose.Orientation.y, 3, 0);
}
else
{
@@ -512,91 +512,21 @@ static bool DoRayBox(const GameVector& origin, const GameVector& target, const G
// If mesh is visible.
if (item->MeshBits & (1 << i))
{
+ float distance;
const auto& sphere = spheres[i];
- // NOTE: Not worth doing what's commented below. *Rewrite completely.*
- // TODO: this approach is the correct one but, again, Core's math is a mystery and this test was meant
- // to fail deliberately in some way. I've so added again Core's legacy test for allowing the current game logic
- // but after more testing we should trash it in the future and restore the new way.
-#if 0
- // Create the bounding sphere and test it against the ray
- BoundingSphere sph = BoundingSphere(Vector3(sphere->x, sphere->y, sphere->z), sphere->r);
- float newDist;
- if (sph.Intersects(rayStart, rayDirNormalized, newDist))
+ if (sphere.Intersects(rayOrigin, rayDir, distance))
{
- // HACK: Core seems to take in account for distance not the real hit point but the centre of the sphere.
- // This can work well for example for GUARDIAN because the head sphere is so big that would always be hit
- // and eyes would not be destroyed.
- newDist = sqrt(SQUARE(sphere->x - start->x) + SQUARE(sphere->y - start->y) + SQUARE(sphere->z - start->z));
+ // Test for minimum distance.
- // Test for min distance
- if (newDist < minDistance)
+ if (distance < minDist)
{
- minDistance = newDist;
- meshPtr = &g_Level.Meshes[obj->meshIndex + i];
+ minDist = distance;
+ meshIndex = object->meshIndex + i;
bit = 1 << i;
sp = i;
}
}
-#endif
-
- Vector3i p[4];
-
- p[1].x = origin.x;
- p[1].y = origin.y;
- p[1].z = origin.z;
- p[2].x = target.x;
- p[2].y = target.y;
- p[2].z = target.z;
- p[3].x = sphere.Center.x;
- p[3].y = sphere.Center.y;
- p[3].z = sphere.Center.z;
-
- int r0 = (p[3].x - p[1].x) * (p[2].x - p[1].x) +
- (p[3].y - p[1].y) * (p[2].y - p[1].y) +
- (p[3].z - p[1].z) * (p[2].z - p[1].z);
-
- int r1 = SQUARE(p[2].x - p[1].x) +
- SQUARE(p[2].y - p[1].y) +
- SQUARE(p[2].z - p[1].z);
-
- if (((r0 < 0 && r1 < 0) ||
- (r1 > 0 && r0 > 0)) &&
- (abs(r0) <= abs(r1)))
- {
- r1 >>= 16;
- if (r1)
- r0 /= r1;
- else
- r0 = 0;
-
- p[0].x = p[1].x + ((r0 * (p[2].x - p[1].x)) >> 16);
- p[0].y = p[1].y + ((r0 * (p[2].y - p[1].y)) >> 16);
- p[0].z = p[1].z + ((r0 * (p[2].z - p[1].z)) >> 16);
-
- int dx = SQUARE(p[0].x - p[3].x);
- int dy = SQUARE(p[0].y - p[3].y);
- int dz = SQUARE(p[0].z - p[3].z);
-
- int distance = dx + dy + dz;
-
- if (distance < SQUARE(sphere.Radius))
- {
- dx = SQUARE(sphere.Center.x - origin.x);
- dy = SQUARE(sphere.Center.y - origin.y);
- dz = SQUARE(sphere.Center.z - origin.z);
-
- distance = dx + dy + dz;
-
- if (distance < minDist)
- {
- minDist = distance;
- meshIndex = object->meshIndex + i;
- bit = 1 << i;
- sp = i;
- }
- }
- }
}
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp
index 11ff82fb0..0be4cdc39 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp
@@ -591,9 +591,12 @@ namespace TEN::Entities::Creatures::TR5
void DoGuardianDeath(int itemNumber, ItemInfo& item)
{
const auto& guardian = GetGuardianInfo(item);
-
- ExplodeItemNode(&g_Level.Items[guardian.BaseItem], 0, 0, 128);
- KillItem(guardian.BaseItem);
+
+ if (g_Level.Items[guardian.BaseItem].ObjectNumber == ID_LASERHEAD_BASE)
+ {
+ ExplodeItemNode(&g_Level.Items[guardian.BaseItem], 0, 0, 128);
+ KillItem(guardian.BaseItem);
+ }
ExplodeItemNode(&item, 0, 0, 128);
@@ -605,7 +608,6 @@ namespace TEN::Entities::Creatures::TR5
TriggerShockwave(&item.Pose, 32, 160, 64, 0, 128, 64, 36, EulerAngles(0x3000, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
TriggerShockwave(&item.Pose, 32, 160, 64, 0, 128, 64, 36, EulerAngles(0x6000, 0.0f, 0.0f), 0, true, false, false, (int)ShockwaveStyle::Normal);
- g_Level.Items[guardian.PuzzleItem].Pose.Position.y = item.Pose.Position.y;
TestTriggers(&item, true);
SoundEffect(SFX_TR5_GOD_HEAD_BLAST, &item.Pose, SoundEnvironment::Land, 0.5f);
diff --git a/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h b/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h
index b32f7ea90..393348eeb 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h
+++ b/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h
@@ -21,6 +21,5 @@ namespace TEN::Entities::Creatures::TR5
short yRot;
int BaseItem;
std::array Tentacles = {};
- int PuzzleItem;
};
}
From 9ea62f711a3cac4bcf00fd20e92175e595d632af Mon Sep 17 00:00:00 2001
From: MontyTRC89
Date: Tue, 15 Oct 2024 15:18:51 +0200
Subject: [PATCH 2/5] Fixed vehicle and Lara in HUB system level change
---
Documentation/doc/1 modules/Flow.html | 26 ++
.../doc/2 classes/Objects.Moveable.html | 8 +-
Documentation/doc/2 classes/Objects.Room.html | 229 ++++++++++--------
Documentation/doc/4 enums/Objects.ObjID.html | 4 +-
Documentation/doc/index.html | 2 +-
TombEngine/Game/Lara/lara_initialise.cpp | 8 +-
TombEngine/Game/Lara/lara_initialise.h | 1 +
TombEngine/Game/control/control.cpp | 5 +
TombEngine/Game/savegame.cpp | 12 +
9 files changed, 177 insertions(+), 118 deletions(-)
diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html
index 81fc6b1b0..481749867 100644
--- a/Documentation/doc/1 modules/Flow.html
+++ b/Documentation/doc/1 modules/Flow.html
@@ -234,6 +234,10 @@ scripts too.
Get translated string. |
+ IsStringPresent(string) |
+ Check if translated string is present. |
+
+
SetLanguageNames(table) |
Set language names for translations. |
@@ -927,6 +931,28 @@ You will not need to call them manually.
+
+
+
+ IsStringPresent(string)
+
+
+ Check if translated string is present.
+
+
+
+ Parameters:
+
+ - string
+ key
+ key for translated string
+
+
+
+
+
+
+
diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html
index 00671976d..fe4d7c91a 100644
--- a/Documentation/doc/2 classes/Objects.Moveable.html
+++ b/Documentation/doc/2 classes/Objects.Moveable.html
@@ -108,7 +108,7 @@ pickups, and Lara herself (see also Functions
- Moveable(object, name, position, rotation, roomID, animNumber, frameNumber, hp, OCB, AIBits) |
+ Moveable(object, name, position, rotation, roomNumber, animNumber, frameNumber, hp, OCB, AIBits) |
Used to generate a new moveable dynamically at runtime. |
@@ -390,7 +390,7 @@ pickups, and Lara herself (see also
- Moveable(object, name, position, rotation, roomID, animNumber, frameNumber, hp, OCB, AIBits)
+ Moveable(object, name, position, rotation, roomNumber, animNumber, frameNumber, hp, OCB, AIBits)
Used to generate a new moveable dynamically at runtime.
@@ -418,9 +418,9 @@ most can just be ignored (see usage).
Rotation
rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
- roomID
+ roomNumber
int
- room ID item is in (default: calculated automatically)
+ the room number the moveable is in (default: calculated automatically).
animNumber
int
diff --git a/Documentation/doc/2 classes/Objects.Room.html b/Documentation/doc/2 classes/Objects.Room.html
index d49f8c93b..d2efc7718 100644
--- a/Documentation/doc/2 classes/Objects.Room.html
+++ b/Documentation/doc/2 classes/Objects.Room.html
@@ -100,7 +100,7 @@
Class Objects.Room
-
Rooms
+
Room object.
@@ -109,8 +109,12 @@
@@ -154,11 +158,11 @@
-
-
- Room:GetActive()
+
+ Room:GetRoomNumber()
-
- Determine whether the room is active or not
+ Get the room's number. ()
@@ -166,8 +170,29 @@
Returns:
- bool
- true if the room is active
+ int
+ Room number.
+
+
+
+
+
+
+ -
+
+ Room:GetName()
+
+ -
+ Get the room's unique string identifier. ()
+
+
+
+
+
Returns:
+
+
+ string
+ Room name.
@@ -179,7 +204,7 @@
Room:GetColor()
-
- Get the room's ambient light color.
+ Get the room's ambient light color. ()
@@ -188,7 +213,7 @@
Color
- ambient light color of the room
+ Ambient light color.
@@ -200,7 +225,7 @@
Room:GetReverbType()
-
- Get the room's reverb type.
+ Get the room's reverb type. ()
@@ -209,50 +234,7 @@
RoomReverb
- room's reverb type
-
-
-
-
-
-
- -
-
- Room:SetReverbType(new)
-
- -
- Set the room's reverb type.
-
-
-
-
Parameters:
-
-
-
-
-
-
-
- -
-
- Room:GetName()
-
- -
- Get the room's unique string identifier.
-
-
-
-
-
Returns:
-
-
- string
- the room's name
+ Reverb type.
@@ -264,7 +246,7 @@
Room:SetName(name)
-
- Set the room's name (its unique string identifier).
+ Set the room's unique string identifier. ()
@@ -272,7 +254,55 @@
- name
string
- The room's new name
+ New name.
+
+
+
+
+
+
+
+
+ -
+
+ Room:SetReverbType(Reverb)
+
+ -
+ Set the room's reverb type. ()
+
+
+
+
Parameters:
+
+
+
+
+
+
+
+ -
+
+ Room:SetFlag(flagID, Boolean)
+
+ -
+ Set the room's specified flag. ()
+
+
+
+
Parameters:
+
+ - flagID
+ RoomFlagID
+ Room flag ID.
+
+ - Boolean
+ bool
+ to set the flag to.
@@ -286,7 +316,7 @@
Room:GetFlag(flagID)
-
- Get the room's specified flag value (true or false).
+ Get the room's specified flag value (true or false). ()
@@ -294,39 +324,7 @@
-
-
Returns:
-
-
- bool
- the room's specified flag value
-
-
-
-
-
-
- -
-
- Room:SetFlag(flagID, the)
-
- -
- Set the room's specified flag value.
-
-
-
-
Parameters:
-
- - flagID
- RoomFlagID
- The room's flag ID
-
- - the
- bool
- room's new flag value
+ Room flag ID.
@@ -340,7 +338,7 @@
Room:IsTagPresent(tag)
-
- Checks if specified tag is set for this room.
+ Check if the specified tag is set for the room. ()
@@ -348,7 +346,7 @@
- tag
string
- A text tag to check (case sensitive)
+ Text tag to check (case sensitive).
@@ -356,7 +354,28 @@
bool
- true if tag is present, false if not
+ Boolean of the tag's presence.
+
+
+
+
+
+
+ -
+
+ Room:GetActive()
+
+ -
+ Check if the room is active. ()
+
+
+
+
+
Returns:
+
+
+ bool
+ Boolean of the room's active status.
diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html
index 4328065c5..099a2d745 100644
--- a/Documentation/doc/4 enums/Objects.ObjID.html
+++ b/Documentation/doc/4 enums/Objects.ObjID.html
@@ -171,8 +171,8 @@ LARA_PETROL_MESH
LARA_DIRT_MESH
LARA_CROWBAR_ANIM
LARA_TORCH_ANIM
-SINGLE_BRAID_HAIR
-DUAL_PIGTAIL_HAIR
+HAIR_PRIMARY
+HAIR_SECONDARY
SNOWMOBILE_LARA_ANIMS
SNOWMOBILE
QUAD_LARA_ANIMS
diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html
index e481a6133..ef744a16b 100644
--- a/Documentation/doc/index.html
+++ b/Documentation/doc/index.html
@@ -217,7 +217,7 @@ local door = GetMoveableByName("door_type4_14")
Objects.Room |
- Rooms |
+ Room object. |
Objects.Sink |
diff --git a/TombEngine/Game/Lara/lara_initialise.cpp b/TombEngine/Game/Lara/lara_initialise.cpp
index 736a07eec..507491f1e 100644
--- a/TombEngine/Game/Lara/lara_initialise.cpp
+++ b/TombEngine/Game/Lara/lara_initialise.cpp
@@ -182,7 +182,7 @@ void InitializeLaraStartPosition(ItemInfo& playerItem)
playerItem.Location.Height = playerItem.Pose.Position.y;
}
-static void InitializePlayerVehicle(ItemInfo& playerItem)
+void InitializePlayerVehicle(ItemInfo& playerItem)
{
if (PlayerVehicleObjectID == GAME_OBJECT_ID::ID_NO_OBJECT)
return;
@@ -194,7 +194,6 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
// Restore vehicle.
TENLog("Transferring vehicle " + GetObjectName(PlayerVehicleObjectID) + " from the previous level.");
vehicle->Pose = playerItem.Pose;
- ItemNewRoom(vehicle->Index, playerItem.RoomNumber);
SetLaraVehicle(&playerItem, vehicle);
playerItem.Animation = PlayerAnim;
@@ -251,7 +250,7 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
if (vehicle->ObjectNumber == GAME_OBJECT_ID::ID_RUBBER_BOAT ||
vehicle->ObjectNumber == GAME_OBJECT_ID::ID_SPEEDBOAT)
{
- g_Level.Items[vehicle->Index].Active = false;
+ RemoveActiveItem(vehicle->Index, false);
AddActiveItem(vehicle->Index);
g_Level.Items[vehicle->Index].Status = ITEM_ACTIVE;
}
@@ -297,9 +296,6 @@ void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup)
// Restore hit points.
item->HitPoints = PlayerHitPoints;
-
- // Restore vehicle.
- InitializePlayerVehicle(*item);
}
void InitializeLaraDefaultInventory(ItemInfo& item)
diff --git a/TombEngine/Game/Lara/lara_initialise.h b/TombEngine/Game/Lara/lara_initialise.h
index a218a7ccf..86ecd4829 100644
--- a/TombEngine/Game/Lara/lara_initialise.h
+++ b/TombEngine/Game/Lara/lara_initialise.h
@@ -9,3 +9,4 @@ void InitializeLaraAnims(ItemInfo* item);
void InitializeLaraStartPosition(ItemInfo& playerItem);
void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup);
void InitializeLaraDefaultInventory(ItemInfo& item);
+void InitializePlayerVehicle(ItemInfo& playerItem);
\ No newline at end of file
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index e5b63c261..204324201 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -59,6 +59,7 @@
#include "Specific/Input/Input.h"
#include "Specific/level.h"
#include "Specific/winmain.h"
+#include "Game/Lara/lara_initialise.h"
using namespace std::chrono;
using namespace TEN::Effects;
@@ -531,6 +532,10 @@ void InitializeOrLoadGame(bool loadGame)
{
SaveGame::LoadHub(CurrentLevel);
TENLog("Starting new level.", LogLevel::Info);
+
+ // Restore vehicle.
+ auto* item = FindItem(ID_LARA);
+ InitializePlayerVehicle(*item);
}
g_GameScript->OnStart();
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index 221d50862..a2a906d95 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -2299,10 +2299,22 @@ static void ParseLevel(const Save::SaveGame* s, bool hubMode)
// Don't load player data in hub mode.
if (item->ObjectNumber == ID_LARA && hubMode)
+ {
+ //item->Pose = ToPose(*savedItem->pose());
+ item->RoomNumber = savedItem->room_number();
+ item->Floor = savedItem->floor();
+ item->BoxNumber = savedItem->box_number();
continue;
+ }
if (item->Index == Lara.Context.Vehicle && hubMode)
+ {
+ //item->Pose = ToPose(*savedItem->pose());
+ item->RoomNumber = savedItem->room_number();
+ item->Floor = savedItem->floor();
+ item->BoxNumber = savedItem->box_number();
continue;
+ }
// Position
item->Pose = ToPose(*savedItem->pose());
From b1bbd55328bce2c9a5e4bd3b30308fa69504bf17 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 16 Oct 2024 00:11:51 +0200
Subject: [PATCH 3/5] Fixed issue with Lara not rotating together with bridges
while picking up items
---
CHANGELOG.md | 1 +
TombEngine/Game/Lara/PlayerStateMachine.cpp | 4 ++--
TombEngine/Game/Lara/lara_basic.cpp | 12 +-----------
TombEngine/Game/Lara/lara_collide.cpp | 16 ++++++++++++++++
TombEngine/Game/Lara/lara_collide.h | 1 +
TombEngine/Game/Lara/lara_objects.cpp | 7 +++++++
TombEngine/Game/Lara/lara_objects.h | 1 +
7 files changed, 29 insertions(+), 13 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index be12a6acd..3b7c54e6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed weapons not properly hitting enemies.
* Fixed laserhead teleporting Lara and making her invisible on death.
* Fixed sarcophagus pick-ups.
+* Fixed issue with Lara not rotating together with bridges while picking up items.
* Fixed several binocular bugs.
* Fixed incorrect climbing out of water on bridge objects.
* Fixed faulty death sectors.
diff --git a/TombEngine/Game/Lara/PlayerStateMachine.cpp b/TombEngine/Game/Lara/PlayerStateMachine.cpp
index feab50981..84cc003f9 100644
--- a/TombEngine/Game/Lara/PlayerStateMachine.cpp
+++ b/TombEngine/Game/Lara/PlayerStateMachine.cpp
@@ -71,7 +71,7 @@ namespace TEN::Entities::Player
PlayerBehaviorStateRoutines[LS_PUSHABLE_PUSH] = std::pair(lara_as_pushable_push, lara_default_col);
PlayerBehaviorStateRoutines[LS_PUSHABLE_PULL] = std::pair(lara_as_pushable_pull, lara_default_col);
PlayerBehaviorStateRoutines[LS_PUSHABLE_GRAB] = std::pair(lara_as_pushable_grab, lara_default_col);
- PlayerBehaviorStateRoutines[LS_PICKUP] = std::pair(lara_as_pickup, lara_default_col);
+ PlayerBehaviorStateRoutines[LS_PICKUP] = std::pair(lara_as_pickup, lara_col_pickup);
PlayerBehaviorStateRoutines[LS_SWITCH_DOWN] = std::pair(lara_as_switch_on, lara_default_col);
PlayerBehaviorStateRoutines[LS_SWITCH_UP] = std::pair(lara_as_switch_off, lara_default_col);
PlayerBehaviorStateRoutines[LS_INSERT_KEY] = std::pair(lara_as_use_key, lara_default_col);
@@ -99,7 +99,7 @@ namespace TEN::Entities::Player
PlayerBehaviorStateRoutines[LS_TEST_3] = std::pair(lara_void_func, lara_void_func);
PlayerBehaviorStateRoutines[LS_WADE_FORWARD] = std::pair(lara_as_wade_forward, lara_col_wade_forward);
PlayerBehaviorStateRoutines[LS_UNDERWATER_ROLL] = std::pair(lara_as_underwater_roll_180, lara_col_underwater_roll_180);
- PlayerBehaviorStateRoutines[LS_PICKUP_FLARE] = std::pair(lara_as_pickup_flare, lara_default_col);
+ PlayerBehaviorStateRoutines[LS_PICKUP_FLARE] = std::pair(lara_as_pickup_flare, lara_col_pickup);
PlayerBehaviorStateRoutines[LS_JUMP_ROLL_180] = std::pair(lara_void_func, lara_void_func);
PlayerBehaviorStateRoutines[LS_KICK] = std::pair(lara_void_func, lara_void_func);
PlayerBehaviorStateRoutines[LS_ZIP_LINE] = std::pair(lara_as_zip_line, lara_void_func);
diff --git a/TombEngine/Game/Lara/lara_basic.cpp b/TombEngine/Game/Lara/lara_basic.cpp
index 8fbf4ec2f..5e65451a7 100644
--- a/TombEngine/Game/Lara/lara_basic.cpp
+++ b/TombEngine/Game/Lara/lara_basic.cpp
@@ -39,17 +39,7 @@ void lara_void_func(ItemInfo* item, CollisionInfo* coll)
void lara_default_col(ItemInfo* item, CollisionInfo* coll)
{
- auto& player = GetLaraInfo(*item);
-
- player.Control.MoveAngle = item->Pose.Orientation.y;
- coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
- coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
- coll->Setup.LowerCeilingBound = 0;
- coll->Setup.BlockFloorSlopeDown = true;
- coll->Setup.BlockFloorSlopeUp = true;
- coll->Setup.ForwardAngle = player.Control.MoveAngle;
- GetCollisionInfo(coll, item);
- LaraResetGravityStatus(item, coll);
+ LaraDefaultCollision(item, coll);
}
// Boulder death.
diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp
index 377d0ee7b..7e38ded7a 100644
--- a/TombEngine/Game/Lara/lara_collide.cpp
+++ b/TombEngine/Game/Lara/lara_collide.cpp
@@ -507,6 +507,22 @@ void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll)
}
}
+
+void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll)
+{
+ auto& player = GetLaraInfo(*item);
+
+ player.Control.MoveAngle = item->Pose.Orientation.y;
+ coll->Setup.LowerFloorBound = STEPUP_HEIGHT;
+ coll->Setup.UpperFloorBound = -STEPUP_HEIGHT;
+ coll->Setup.LowerCeilingBound = 0;
+ coll->Setup.BlockFloorSlopeDown = true;
+ coll->Setup.BlockFloorSlopeUp = true;
+ coll->Setup.ForwardAngle = player.Control.MoveAngle;
+ GetCollisionInfo(coll, item);
+ LaraResetGravityStatus(item, coll);
+}
+
void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
diff --git a/TombEngine/Game/Lara/lara_collide.h b/TombEngine/Game/Lara/lara_collide.h
index 41a6bf3b1..705cb373c 100644
--- a/TombEngine/Game/Lara/lara_collide.h
+++ b/TombEngine/Game/Lara/lara_collide.h
@@ -25,6 +25,7 @@ void GetLaraDeadlyBounds();
void LaraJumpCollision(ItemInfo* item, CollisionInfo* coll, short moveAngle);
void LaraSurfaceCollision(ItemInfo* item, CollisionInfo* coll);
void LaraSwimCollision(ItemInfo* item, CollisionInfo* coll);
+void LaraDefaultCollision(ItemInfo* item, CollisionInfo* coll);
void LaraWaterCurrent(ItemInfo* item, CollisionInfo* coll);
diff --git a/TombEngine/Game/Lara/lara_objects.cpp b/TombEngine/Game/Lara/lara_objects.cpp
index bee098072..3f4989534 100644
--- a/TombEngine/Game/Lara/lara_objects.cpp
+++ b/TombEngine/Game/Lara/lara_objects.cpp
@@ -8,6 +8,7 @@
#include "Game/items.h"
#include "Game/Lara/PlayerContext.h"
#include "Game/Lara/lara.h"
+#include "Game/Lara/lara_collide.h"
#include "Game/Lara/lara_helpers.h"
#include "Game/Lara/lara_tests.h"
#include "Objects/Generic/Object/rope.h"
@@ -45,6 +46,12 @@ void lara_as_pickup(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = GetNextAnimState(item);
}
+void lara_col_pickup(ItemInfo* item, CollisionInfo* coll)
+{
+ LaraDefaultCollision(item, coll);
+ ShiftItem(item, coll);
+}
+
// State: LS_PICKUP_FLARE (67)
// Collision: lara_default_col()
void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll)
diff --git a/TombEngine/Game/Lara/lara_objects.h b/TombEngine/Game/Lara/lara_objects.h
index 18636c583..c53ffd84d 100644
--- a/TombEngine/Game/Lara/lara_objects.h
+++ b/TombEngine/Game/Lara/lara_objects.h
@@ -14,6 +14,7 @@ struct CollisionInfo;
void lara_as_pickup(ItemInfo* item, CollisionInfo* coll);
void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll);
+void lara_col_pickup(ItemInfo* item, CollisionInfo* coll);
// ------
// SWITCH
From 0638756d908e5a79deabeb654a36194c8ebdc688 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 16 Oct 2024 00:59:37 +0200
Subject: [PATCH 4/5] Fixed ghost collision with moveables with zero bounds
---
CHANGELOG.md | 1 +
TombEngine/Game/collision/collide_item.cpp | 3 +++
2 files changed, 4 insertions(+)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3b7c54e6a..eba472893 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -15,6 +15,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed laserhead teleporting Lara and making her invisible on death.
* Fixed sarcophagus pick-ups.
* Fixed issue with Lara not rotating together with bridges while picking up items.
+* Fixed ghost collision with moveables with zero bounds.
* Fixed several binocular bugs.
* Fixed incorrect climbing out of water on bridge objects.
* Fixed faulty death sectors.
diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp
index 502d36654..b4e9035a2 100644
--- a/TombEngine/Game/collision/collide_item.cpp
+++ b/TombEngine/Game/collision/collide_item.cpp
@@ -566,6 +566,9 @@ bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius)
const auto& bounds = GetBestFrame(*item).BoundingBox;
const auto& playerBounds = GetBestFrame(*laraItem).BoundingBox;
+ if (bounds.GetExtents() == Vector3::Zero || playerBounds.GetExtents() == Vector3::Zero)
+ return false;
+
if ((item->Pose.Position.y + bounds.Y2) <= (laraItem->Pose.Position.y + playerBounds.Y1))
return false;
From f7a22ea1a75eb77b5a1a90427996925cd7e4c7e5 Mon Sep 17 00:00:00 2001
From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com>
Date: Fri, 18 Oct 2024 00:14:02 +0100
Subject: [PATCH 5/5] Clarify Lua API for SetOnCollidedWithObject()
---
.../Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp | 3 +++
1 file changed, 3 insertions(+)
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index e808c33f4..b54b8bf96 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -428,6 +428,9 @@ ScriptReserved_GetSlotHP, & Moveable::GetSlotHP,
// @function Moveable:SetOnCollidedWithObject
// @tparam function func callback function to be called (must be in LevelFuncs hierarchy). This function can take two arguments; these will store the two @{Moveable}s taking part in the collision.
// @usage
+// -- obj1 is the collision moveable
+// -- obj2 is the collider moveable
+//
// LevelFuncs.objCollided = function(obj1, obj2)
// print(obj1:GetName() .. " collided with " .. obj2:GetName())
// end