diff --git a/TombEngine/Game/Lara/lara_objects.cpp b/TombEngine/Game/Lara/lara_objects.cpp index ffbbf8415..340ea7116 100644 --- a/TombEngine/Game/Lara/lara_objects.cpp +++ b/TombEngine/Game/Lara/lara_objects.cpp @@ -285,6 +285,8 @@ void lara_as_horizontal_bar_swing(ItemInfo* item, CollisionInfo* coll) auto& player = GetLaraInfo(*item); player.Control.Look.Mode = LookMode::Horizontal; + //Camera.laraNode = LM_HEAD; + //Camera.targetAngle = ANGLE(0.0f); if (IsHeld(In::Action)) { diff --git a/TombEngine/Objects/Generic/Object/HorizontalBar.cpp b/TombEngine/Objects/Generic/Object/HorizontalBar.cpp new file mode 100644 index 000000000..cc8130bdd --- /dev/null +++ b/TombEngine/Objects/Generic/Object/HorizontalBar.cpp @@ -0,0 +1,96 @@ +#include "framework.h" +#include "Objects/Generic/Object/HorizontalBar.h" + +#include "Game/animation.h" +#include "Game/collision/collide_item.h" +#include "Game/control/control.h" +#include "Game/effects/effects.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Game/Lara/lara_helpers.h" +#include "Game/Setup.h" +#include "Math/Math.h" +#include "Renderer/RendererEnums.h" +#include "Sound/sound.h" +#include "Specific/Input/Input.h" +#include "Specific/level.h" + +using namespace TEN::Input; +using namespace TEN::Math; + +namespace TEN::Entities::Generic +{ + static const auto HORIZONTAL_BAR_STATES = std::vector + { + LS_HORIZONTAL_BAR_SWING, + LS_HORIZONTAL_BAR_JUMP, + LS_HORIZONTAL_BAR_IDLE, + LS_HORIZONTAL_BAR_IDLE_TURN_180, + LS_HORIZONTAL_BAR_SWING_TURN_180 + }; + + static auto HorizontalBarBounds = ObjectCollisionBounds + { + GameBoundingBox( + -640, 640, + 704, 832, + -96, 96), + std::pair( + EulerAngles(ANGLE(-10.0f), -LARA_GRAB_THRESHOLD, ANGLE(-10.0f)), + EulerAngles(ANGLE(10.0f), LARA_GRAB_THRESHOLD, ANGLE(10.0f))) + }; + + void HorizontalBarCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) + { + auto& barItem = g_Level.Items[itemNumber]; + auto& player = GetLaraInfo(*playerItem); + + if (IsHeld(In::Action) && + (playerItem->Animation.ActiveState == LS_REACH || playerItem->Animation.ActiveState == LS_JUMP_UP) && + player.Control.HandStatus == HandStatus::Free) + { + // HACK: Update interaction basis. + auto bounds = GameBoundingBox(&barItem); + HorizontalBarBounds.BoundingBox.X1 = bounds.X1; + HorizontalBarBounds.BoundingBox.X2 = bounds.X2; + + // Test interaction. + bool isFront = TestLaraPosition(HorizontalBarBounds, &barItem, playerItem); + bool isBack = false; + if (!isFront) + { + barItem.Pose.Orientation.y += ANGLE(-180.0f); + isBack = TestLaraPosition(HorizontalBarBounds, &barItem, playerItem); + barItem.Pose.Orientation.y += ANGLE(-180.0f); + } + + // Set player interaction. + if (isFront || isBack) + { + SetAnimation(playerItem, (playerItem->Animation.ActiveState == LS_REACH) ? LA_REACH_TO_HORIZONTAL_BAR : LA_JUMP_UP_TO_HORIZONTAL_BAR); + ResetPlayerFlex(playerItem); + playerItem->Animation.Velocity.y = 0.0f; + playerItem->Animation.IsAirborne = false; + player.Context.InteractedItem = itemNumber; + player.Control.HandStatus = HandStatus::Busy; + + // Calculate catch position from line (fake attractor). + auto linePoint0 = Geometry::TranslatePoint(barItem.Pose.Position.ToVector3(), barItem.Pose.Orientation.y, 0.0f, 0.0f, HorizontalBarBounds.BoundingBox.X1); + auto linePoint1 = Geometry::TranslatePoint(barItem.Pose.Position.ToVector3(), barItem.Pose.Orientation.y, 0.0f, 0.0f, HorizontalBarBounds.BoundingBox.X2); + auto catchPos = Geometry::GetClosestPointOnLinePerp(playerItem->Pose.Position.ToVector3(), linePoint0, linePoint1); + + // Update player position and orientation. + playerItem->Pose.Position = Geometry::TranslatePoint(catchPos, 0, isFront ? bounds.Z1 : bounds.Z2, coll->Setup.Height + CLICK(0.25f)); // HACK: Hardcoded offset required. + playerItem->Pose.Orientation.y = barItem.Pose.Orientation.y + (isFront ? ANGLE(0.0f) : ANGLE(-180.0f)); + } + else + { + ObjectCollision(itemNumber, playerItem, coll); + } + } + else if (!TestState(playerItem->Animation.ActiveState, HORIZONTAL_BAR_STATES)) + { + ObjectCollision(itemNumber, playerItem, coll); + } + } +} diff --git a/TombEngine/Objects/Generic/Object/HorizontalBar.h b/TombEngine/Objects/Generic/Object/HorizontalBar.h new file mode 100644 index 000000000..83392f98e --- /dev/null +++ b/TombEngine/Objects/Generic/Object/HorizontalBar.h @@ -0,0 +1,9 @@ +#pragma once + +struct ItemInfo; +struct CollisionInfo; + +namespace TEN::Entities::Generic +{ + void HorizontalBarCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll); +} diff --git a/TombEngine/Objects/Generic/Object/objects.cpp b/TombEngine/Objects/Generic/Object/objects.cpp index 2768544bb..8bab057df 100644 --- a/TombEngine/Objects/Generic/Object/objects.cpp +++ b/TombEngine/Objects/Generic/Object/objects.cpp @@ -30,17 +30,6 @@ const ObjectCollisionBounds TightRopeBounds = EulerAngles(ANGLE(10.0f), LARA_GRAB_THRESHOLD, ANGLE(10.0f))) }; -ObjectCollisionBounds HorizontalBarBounds = -{ - GameBoundingBox( - -640, 640, - 704, 832, - -96, 96), - std::pair( - EulerAngles(ANGLE(-10.0f), -LARA_GRAB_THRESHOLD, ANGLE(-10.0f)), - EulerAngles(ANGLE(10.0f), LARA_GRAB_THRESHOLD, ANGLE(10.0f))) -}; - void ControlAnimatingSlots(short itemNumber) { // TODO: TR5 has here a series of hardcoded OCB codes, this function actually is just a placeholder @@ -122,69 +111,6 @@ void TightropeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* col } } -void HorizontalBarCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) -{ - static const auto HORIZONTAL_BAR_STATES = std::vector - { - LS_HORIZONTAL_BAR_SWING, - LS_HORIZONTAL_BAR_JUMP, - LS_HORIZONTAL_BAR_IDLE, - LS_HORIZONTAL_BAR_IDLE_TURN_180, - LS_HORIZONTAL_BAR_SWING_TURN_180 - }; - - auto& barItem = g_Level.Items[itemNumber]; - auto& player = GetLaraInfo(*playerItem); - - if (IsHeld(In::Action) && - (playerItem->Animation.ActiveState == LS_REACH || playerItem->Animation.ActiveState == LS_JUMP_UP) && - player.Control.HandStatus == HandStatus::Free) - { - // HACK: Update interaction basis. - auto bounds = GameBoundingBox(&barItem); - HorizontalBarBounds.BoundingBox.X1 = bounds.X1; - HorizontalBarBounds.BoundingBox.X2 = bounds.X2; - - // Test interaction. - bool hasFront = TestLaraPosition(HorizontalBarBounds, &barItem, playerItem); - bool hasBack = false; - if (!hasFront) - { - barItem.Pose.Orientation.y += ANGLE(-180.0f); - hasBack = TestLaraPosition(HorizontalBarBounds, &barItem, playerItem); - barItem.Pose.Orientation.y += ANGLE(-180.0f); - } - - // Set player interaction. - if (hasFront || hasBack) - { - SetAnimation(playerItem, (playerItem->Animation.ActiveState == LS_REACH) ? LA_REACH_TO_HORIZONTAL_BAR : LA_JUMP_UP_TO_HORIZONTAL_BAR); - ResetPlayerFlex(playerItem); - playerItem->Animation.Velocity.y = 0.0f; - playerItem->Animation.IsAirborne = false; - player.Context.InteractedItem = itemNumber; - player.Control.HandStatus = HandStatus::Busy; - - // Calculate catch position from line. - auto linePoint0 = Geometry::TranslatePoint(barItem.Pose.Position.ToVector3(), barItem.Pose.Orientation.y, 0.0f, 0.0f, HorizontalBarBounds.BoundingBox.X1); - auto linePoint1 = Geometry::TranslatePoint(barItem.Pose.Position.ToVector3(), barItem.Pose.Orientation.y, 0.0f, 0.0f, HorizontalBarBounds.BoundingBox.X2); - auto catchPos = Geometry::GetClosestPointOnLinePerp(playerItem->Pose.Position.ToVector3(), linePoint0, linePoint1); - - // Update player pose. - playerItem->Pose.Position = Geometry::TranslatePoint(catchPos, 0, 0.0f, coll->Setup.Height + CLICK(0.25f)); - playerItem->Pose.Orientation.y = barItem.Pose.Orientation.y + (hasFront ? ANGLE(0.0f) : ANGLE(-180.0f)); - } - else - { - ObjectCollision(itemNumber, playerItem, coll); - } - } - else if (!TestState(playerItem->Animation.ActiveState, HORIZONTAL_BAR_STATES)) - { - ObjectCollision(itemNumber, playerItem, coll); - } -} - void CutsceneRopeControl(short itemNumber) { auto* ropeItem = &g_Level.Items[itemNumber]; diff --git a/TombEngine/Objects/Generic/Object/objects.h b/TombEngine/Objects/Generic/Object/objects.h index 9e45a79d7..2b53cf41a 100644 --- a/TombEngine/Objects/Generic/Object/objects.h +++ b/TombEngine/Objects/Generic/Object/objects.h @@ -9,8 +9,6 @@ void ControlAnimatingSlots(short itemNumber); void ControlTriggerTriggerer(short itemNumber); void TightropeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); -void HorizontalBarCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll); - void CutsceneRopeControl(short itemNumber); void HybridCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); void InitializeSmashObject(short itemNumber); diff --git a/TombEngine/Objects/Generic/generic_objects.cpp b/TombEngine/Objects/Generic/generic_objects.cpp index 5e09d44ba..85acb1924 100644 --- a/TombEngine/Objects/Generic/generic_objects.cpp +++ b/TombEngine/Objects/Generic/generic_objects.cpp @@ -10,9 +10,10 @@ #include "Game/Setup.h" // Objects +#include "Objects/Generic/Object/burning_torch.h" #include "Objects/Generic/Object/generic_trapdoor.h" #include "Objects/Generic/Object/generic_bridge.h" -#include "Objects/Generic/Object/burning_torch.h" +#include "Objects/Generic/Object/HorizontalBar.h" #include "Objects/Generic/Object/polerope.h" #include "Objects/Generic/Object/Pushable/PushableObject.h" #include "Objects/Generic/Object/rope.h" diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index 6ed6d9f4d..33ba14f41 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -564,6 +564,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + @@ -1091,6 +1092,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. +