This commit is contained in:
Sezz 2025-02-03 01:52:00 +11:00
parent a82adc09c3
commit 09d5b791b6
7 changed files with 111 additions and 77 deletions

View file

@ -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))
{

View file

@ -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<int>
{
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);
}
}
}

View file

@ -0,0 +1,9 @@
#pragma once
struct ItemInfo;
struct CollisionInfo;
namespace TEN::Entities::Generic
{
void HorizontalBarCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll);
}

View file

@ -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<int>
{
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];

View file

@ -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);

View file

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

View file

@ -564,6 +564,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<ClInclude Include="Objects\Generic\Object\burning_torch.h" />
<ClInclude Include="Objects\Generic\Object\generic_bridge.h" />
<ClInclude Include="Objects\Generic\Object\generic_trapdoor.h" />
<ClInclude Include="Objects\Generic\Object\HorizontalBar.h" />
<ClInclude Include="Objects\Generic\Object\objects.h" />
<ClInclude Include="Objects\Generic\Object\polerope.h" />
<ClInclude Include="Objects\Generic\Object\Pushable\PushableBridge.h" />
@ -1091,6 +1092,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings.
<ClCompile Include="Objects\Generic\Object\burning_torch.cpp" />
<ClCompile Include="Objects\Generic\Object\generic_bridge.cpp" />
<ClCompile Include="Objects\Generic\Object\generic_trapdoor.cpp" />
<ClCompile Include="Objects\Generic\Object\HorizontalBar.cpp" />
<ClCompile Include="Objects\Generic\Object\objects.cpp" />
<ClCompile Include="Objects\Generic\Object\polerope.cpp" />
<ClCompile Include="Objects\Generic\Object\Pushable\PushableBridge.cpp" />