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 - + @@ -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 @@

    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.
    - - + + + + + + @@ -121,28 +125,28 @@ - + + + + + - - - - - - + + - - + + - - + +
    Room:GetActive()Determine whether the room is active or notRoom:GetRoomNumber()Get the room's number.
    Room:GetName()Get the room's unique string identifier.
    Room:GetColor()Get the room's reverb type.
    Room:SetReverbType(new)Room:SetName(name)Set the room's unique string identifier.
    Room:SetReverbType(Reverb) Set the room's reverb type.
    Room:GetName()Get the room's unique string identifier.
    Room:SetName(name)Set the room's name (its unique string identifier).Room:SetFlag(flagID, Boolean)Set the room's specified flag.
    Room:GetFlag(flagID) Get the room's specified flag value (true or false).
    Room:SetFlag(flagID, the)Set the room's specified flag value.Room:IsTagPresent(tag)Check if the specified tag is set for the room.
    Room:IsTagPresent(tag)Checks if specified tag is set for this room.Room:GetActive()Check if the room is active.
    @@ -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:

    -
      -
    • new - RoomReverb - reverb type of the room -
    • -
    - - - - - -
    -
    - - 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