Minor refactors to moving laser

This commit is contained in:
Sezz 2025-03-19 16:20:26 +11:00
parent b07ee8eed7
commit e0927a9415

View file

@ -12,99 +12,111 @@
#include "Game/items.h" #include "Game/items.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
#include "Sound/sound.h" #include "Sound/sound.h"
#include "Math/Utils.h"
#include "Specific/level.h" #include "Specific/level.h"
using namespace TEN::Collision::Sphere; using namespace TEN::Collision::Sphere;
namespace TEN::Entities::Traps namespace TEN::Entities::Traps
{ {
enum MovingLaserFlags constexpr auto MOVING_LASER_DAMAGE = 100;
{ constexpr auto MOVING_LASER_VELOCITY_MIN = 1.0f;
Speed, constexpr auto MOVING_LASER_ACCEL = 1.0f;
PauseCounter, constexpr auto MOVING_LASER_PAUSE_FRAME_COUNT = 30;
Direction,
DistanceTravelled,
SpeedCalc
};
constexpr auto MOVING_LASER_DAMAGE = 100; enum class MovingLaserProperty
constexpr int PAUSE_FRAMES = 30; {
constexpr float MAX_SPEED_THRESHOLD = 0.9f; Velocity,
constexpr float MIN_SPEED = 1.0f; PauseTimer,
constexpr float ACCELERATION = 1.0f; DirectionSign,
DistanceTraveled,
VelocityCalc
};
void InitializeMovingLaser(short itemNumber) void InitializeMovingLaser(short itemNumber)
{ {
auto& item = g_Level.Items[itemNumber]; auto& item = g_Level.Items[itemNumber];
item.ItemFlags[MovingLaserFlags::Direction] = 1; item.ItemFlags[(int)MovingLaserProperty::DirectionSign] = 1;
item.ItemFlags[MovingLaserFlags::Speed] = 10; item.ItemFlags[(int)MovingLaserProperty::Velocity] = 10;
item.Pose.Translate(item.Pose.Orientation, -CLICK(1)); // Offset by one click to make it dangerous at the edges of the block.
// Offset by 1/4 block to make it dangerous at sector edges.
item.Pose.Translate(item.Pose.Orientation, -BLOCK(0.25f));
} }
void ControlMovingLaser(short itemNumber) void ControlMovingLaser(short itemNumber)
{ {
auto& item = g_Level.Items[itemNumber]; auto& item = g_Level.Items[itemNumber];
if (!TriggerActive(&item)) if (!TriggerActive(&item))
return; return;
float moveDistance = (BLOCK(1) * item.TriggerFlags) + CLICK(2); // Use OCB to calculate the distance and add 2 clicks. // Calculate distances.
float moveDist = BLOCK(item.TriggerFlags) + BLOCK(0.5f);
float distPerFrame = (BLOCK(item.ItemFlags[(int)MovingLaserProperty::Velocity]) * 0.25f) / (float)FPS;
float distancePerFrame = ((float)(CLICK(1)) * item.ItemFlags[MovingLaserFlags::Speed]) / FPS; // Calculate distance per frame item.Animation.ActiveState = 0;
item.Animation.ActiveState = 0; // TODO: Use SpawnDynamicPointLight().
SpawnDynamicLight(item.Pose.Position.x, item.Pose.Position.y - 64, item.Pose.Position.z, (Random::GenerateInt() % 2) + 8, (Random::GenerateInt() % 4) + 24, Random::GenerateInt() % 4, Random::GenerateInt() % 2); SpawnDynamicLight(
item.MeshBits = -1 - (GetRandomControl() & 0x14); // To make lasers flicker item.Pose.Position.x, item.Pose.Position.y - 64, item.Pose.Position.z, (Random::GenerateInt() % 2) + 8,
(Random::GenerateInt() % 4) + 24, Random::GenerateInt() % 4, Random::GenerateInt() % 2);
/*auto lightPos = item.Pose.Position.ToVector3() + Vector3(0.0f, -64, 0.0f);
auto lightColor = Color(Random::GenerateFloat(0.1f, 0.2f), Random::GenerateFloat(0.0f, 0.01f), Random::GenerateFloat(Random::GenerateFloat(0.0f, 0.01f)));
float lightFalloff = ??
SpawnDynamicPointLight(lightPos, lightPos, lightFalloff);*/
if (item.TriggerFlags == 0) // TODO: Demagic.
{ // Used for flicker.
AnimateItem(&item); item.MeshBits = -1 - (GetRandomControl() & 20);
return;
}
if (item.ItemFlags[MovingLaserFlags::PauseCounter] > 0) if (item.TriggerFlags == 0)
{ {
item.ItemFlags[MovingLaserFlags::PauseCounter]--; AnimateItem(&item);
return;
}
if (item.ItemFlags[MovingLaserFlags::PauseCounter] == 0) if (item.ItemFlags[(int)MovingLaserProperty::PauseTimer] > 0)
{ {
item.ItemFlags[MovingLaserFlags::Direction] *= -1; item.ItemFlags[(int)MovingLaserProperty::PauseTimer]--;
item.ItemFlags[MovingLaserFlags::DistanceTravelled] = 0; if (item.ItemFlags[(int)MovingLaserProperty::PauseTimer] == 0)
} {
item.ItemFlags[(int)MovingLaserProperty::DirectionSign] *= -1;
item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] = 0;
}
AnimateItem(&item); AnimateItem(&item);
return; return;
} }
item.Pose.Translate(item.Pose.Orientation, (item.ItemFlags[MovingLaserFlags::Direction] * item.ItemFlags[MovingLaserFlags::SpeedCalc])); item.Pose.Translate(item.Pose.Orientation, (item.ItemFlags[(int)MovingLaserProperty::DirectionSign] * item.ItemFlags[(int)MovingLaserProperty::VelocityCalc]));
item.ItemFlags[MovingLaserFlags::DistanceTravelled] += item.ItemFlags[MovingLaserFlags::SpeedCalc]; item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] += item.ItemFlags[(int)MovingLaserProperty::VelocityCalc];
if (item.ItemFlags[DistanceTravelled] < (moveDistance -BLOCK(0.5f))) if (item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] < (moveDist - BLOCK(0.5f)))
item.ItemFlags[SpeedCalc] = std::min(distancePerFrame, item.ItemFlags[MovingLaserFlags::SpeedCalc] + ACCELERATION); {
else item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] = std::min(distPerFrame, item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] + MOVING_LASER_ACCEL);
item.ItemFlags[SpeedCalc] = std::max(MIN_SPEED, item.ItemFlags[MovingLaserFlags::SpeedCalc] - ACCELERATION); }
else
{
item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] = std::max(MOVING_LASER_VELOCITY_MIN, item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] - MOVING_LASER_ACCEL);
}
if (item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] >= moveDist)
{
item.ItemFlags[(int)MovingLaserProperty::PauseTimer] = MOVING_LASER_PAUSE_FRAME_COUNT;
}
if (item.ItemFlags[MovingLaserFlags::DistanceTravelled] >= moveDistance) if (item.ItemFlags[(int)MovingLaserProperty::PauseTimer] == 0)
{ {
item.ItemFlags[MovingLaserFlags::PauseCounter] = PAUSE_FRAMES; SoundEffect(SFX_TR5_MOVING_LASER_LOOP, &item.Pose, SoundEnvironment::Always);
} }
if (item.ItemFlags[MovingLaserFlags::PauseCounter] == 0) // Update room if necessary.
{ int roomNumber = GetPointCollision(item).GetRoomNumber();
SoundEffect(SFX_TR5_MOVING_LASER_LOOP, &item.Pose, SoundEnvironment::Always); if (roomNumber != item.RoomNumber)
} ItemNewRoom(itemNumber, roomNumber);
// Update room if necessary. AnimateItem(&item);
short new_room = item.RoomNumber; }
GetPointCollision(item).GetRoomNumber();
if (new_room != item.RoomNumber)
ItemNewRoom(itemNumber, new_room);
AnimateItem(&item);
}
void CollideMovingLaser(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) void CollideMovingLaser(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll)
{ {
@ -123,7 +135,7 @@ namespace TEN::Entities::Traps
ObjectCollision(itemNumber, playerItem, coll); ObjectCollision(itemNumber, playerItem, coll);
} }
// Damage entity. // Damage player.
if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius))
{ {
DoDamage(playerItem, MOVING_LASER_DAMAGE); DoDamage(playerItem, MOVING_LASER_DAMAGE);