Merge branch 'MontyTRC89:develop' into develop

This commit is contained in:
davidmarr 2024-10-09 19:59:14 +02:00 committed by GitHub
commit bfcd93f52c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
38 changed files with 470 additions and 317 deletions

View file

@ -1,6 +1,6 @@
# Changelog # Changelog
Here you will find the full changelog of TEN's releases from Version 1.0 and up Here you will find the full changelog of TEN's releases from Version 1.0 and up
The dates are in European standard format where date is presented as **YYYY-MM-DD** The dates are in European standard format where date is presented as **YYYY-MM-DD**
@ -10,6 +10,11 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
### Bug fixes ### Bug fixes
* Fixed original issue with classic switch off trigger incorrectly activating some trigger actions. * Fixed original issue with classic switch off trigger incorrectly activating some trigger actions.
* Fixed leveljump vehicle transfer.
* Fixed sarcophagus pick-ups.
* Fixed several binocular bugs.
* Fixed incorrect climbing out of water on bridge objects.
* Fixed faulty death sectors.
* Fixed incorrect diving animation when swandiving from a high place. * Fixed incorrect diving animation when swandiving from a high place.
* Fixed camera rotating with the player's hips when climbing out of water. * Fixed camera rotating with the player's hips when climbing out of water.
* Fixed AI for TR2 skidoo driver and worker with shotgun. * Fixed AI for TR2 skidoo driver and worker with shotgun.
@ -26,37 +31,43 @@ TombEngine releases are located in this repository (alongside with Tomb Editor):
* Fixed teeth spikes not triggering the player impale animation. * Fixed teeth spikes not triggering the player impale animation.
* Fixed TR4 mine crash with OCB 1 when triggered. * Fixed TR4 mine crash with OCB 1 when triggered.
* Fixed cases where Atlantean mutant's bombs cause the game to crash. * Fixed cases where Atlantean mutant's bombs cause the game to crash.
* Fixed young hair drawing. * Fixed young Lara hair drawing. https://tombengine.com/docs/level-settings/#young_lara
### Features/Amendments ### Features/Amendments
* Changed Rome Hammer to not hurt player whilst deactivated.
* Changed Statue with blade damage, from 20 to 200. * Added variable framerate , that allows the engine to run at an unlocked framerate for a much smoother experience. Setting can be toggled on or off in the graphical settings menu.
* Enhanced Rolling Spindle detection to avoid them going down through pits. * Added a customisable global lensflare effect. https://tombengine.com/docs/level-settings/#lensflare
* Enhanced Sentry Guns, with a new ItemFlags[3], to contain the ID of the inventory item that deactivates the sentry guns ( by default PUZZLE_ITEM5 ) * Added a customisable starry sky and meteor effect (based on TR5). https://tombengine.com/docs/level-settings/#stars
* Enhanced Dart Emitter, with a new ItemFlags[0], to contain the number of frames between shots ( by default 32 in dart emitter, and 24 in homing dar emitter ). * Added the ability to display "Lara's Home" entry in the main menu.
* Enhanced raptor behaviour and handling. * Added F12 as alternative to PrtSc for screenshots.
- OCB 0: Classic behaviour * Added option to enable or disable menu option looping.
- OCB 1: Can jump up/down up to 4 steps and jump across gaps up to 2 blocks wide. - Menu scrolling using held inputs will stop at the last option until a new input is made.
- You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Raptor.wad2 * Added TR3 seal mutant. https://tombengine.com/docs/ocb-and-setup-instructions/#sealmutant
* Added TR3 seal mutant.
- OCB 0: Normal enemy behaviour. (TR3 RX-Tech mines level)
- OCB 1: Trap like behaviour. (TR3 Antarctica level)
- You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Seal_Mutant.wad2 - You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Seal_Mutant.wad2
* Add new sound conditions: Quicksand and Underwater. * Add new sound conditions: Quicksand and Underwater.
- Quicksand - sound effect plays when a moveable is in quicksand. - Quicksand - sound effect plays when a moveable is in quicksand.
- Underwater - sound plays when the camera is submerged. - Underwater - sound plays when the camera is submerged.
* Added TR4 Enemy_Jeep https://tombengine.com/docs/ocb-and-setup-instructions/#enemy_jeep
* Changed Rome Hammer to not hurt player whilst deactivated.
* Changed Statue with blade damage, from 20 to 200.
* Changed sound effect that is triggered when using the `level.rumble` feature in a level. Sound effect now part of the default soundmap (ID 359) and additional hardcoded pitch shift has been removed.
* Changed Water sound condition to ShallowWater. * Changed Water sound condition to ShallowWater.
* Added option to enable or disable menu option looping. * Enhanced Rolling Spindle detection to avoid them going down through pits.
* Menu scrolling using held inputs will stop at the last option until a new input is made. * Enhanced Sentry Guns, with a new ItemFlags[3], to contain the ID of the inventory item that deactivates the sentry guns ( by default PUZZLE_ITEM5 )
* Added the ability to display "Lara's Home" entry in the main menu. * Enhanced Dart Emitter, with a new ItemFlags[0], to contain the number of frames between shots ( by default 32 in dart emitter, and 24 in homing-dart emitter ).
* Added F12 as alternative to PrtSc for screenshots. * Enhanced raptor behaviour and handling. https://tombengine.com/docs/ocb-and-setup-instructions/#raptor
- You must use this version: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Enemies/TEN_Raptor.wad2
### Lua API changes ### Lua API changes
* Added Flow.EnableHomeLevel() function.
* Added Flow.IsStringPresent() function.
* Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions. * Added Inventory.GetUsedItem(), Inventory.SetUsedItem() and Inventory.ClearUsedItem() functions.
* Added Input.KeyClearAll() * Added Flow.LensFlare() and Flow.Starfield() classes.
* Added Flow.EnableHomeLevel() * Added Input.KeyClearAll() function.
* Added Room:GetRoomNumber() function.
* Removed anims.monkeyAutoJump. It is now a player menu configuration. * Removed anims.monkeyAutoJump. It is now a player menu configuration.
* Fixed Volume:GetActive() method * Fixed Volume:GetActive() method.
## [Version 1.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.1) - 2024-04-21 ## [Version 1.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.7.1) - 2024-04-21

View file

@ -362,8 +362,6 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
coll->Setup.PrevFrameNumber = item->Animation.FrameNumber; coll->Setup.PrevFrameNumber = item->Animation.FrameNumber;
coll->Setup.PrevState = item->Animation.ActiveState; coll->Setup.PrevState = item->Animation.ActiveState;
UpdateLaraRoom(item, -LARA_HEIGHT / 2);
// Handle look-around. // Handle look-around.
if (((IsHeld(In::Look) && CanPlayerLookAround(*item)) || if (((IsHeld(In::Look) && CanPlayerLookAround(*item)) ||
(player.Control.Look.IsUsingBinoculars || player.Control.Look.IsUsingLasersight)) && (player.Control.Look.IsUsingBinoculars || player.Control.Look.IsUsingLasersight)) &&
@ -378,6 +376,8 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll)
} }
player.Control.Look.Mode = LookMode::None; player.Control.Look.Mode = LookMode::None;
UpdateLaraRoom(item, -LARA_HEIGHT / 2);
// Process vehicles. // Process vehicles.
if (HandleLaraVehicle(item, coll)) if (HandleLaraVehicle(item, coll))
return; return;

View file

@ -13,8 +13,12 @@
#include "Game/Lara/PlayerStateMachine.h" #include "Game/Lara/PlayerStateMachine.h"
#include "Game/Setup.h" #include "Game/Setup.h"
#include "Objects/TR2/Vehicles/skidoo.h" #include "Objects/TR2/Vehicles/skidoo.h"
#include "Objects/TR2/Vehicles/speedboat.h"
#include "Objects/TR3/Vehicles/kayak.h" #include "Objects/TR3/Vehicles/kayak.h"
#include "Objects/TR3/Vehicles/minecart.h"
#include "Objects/TR3/Vehicles/quad_bike.h" #include "Objects/TR3/Vehicles/quad_bike.h"
#include "Objects/TR3/Vehicles/rubber_boat.h"
#include "Objects/TR3/Vehicles/upv.h"
#include "Objects/TR4/Vehicles/jeep.h" #include "Objects/TR4/Vehicles/jeep.h"
#include "Objects/TR4/Vehicles/motorbike.h" #include "Objects/TR4/Vehicles/motorbike.h"
#include "Specific/level.h" #include "Specific/level.h"
@ -122,6 +126,9 @@ void InitializeLaraAnims(ItemInfo* item)
player.LeftArm.Locked = false; player.LeftArm.Locked = false;
player.RightArm.Locked = false; player.RightArm.Locked = false;
if (PlayerVehicleObjectID != GAME_OBJECT_ID::ID_NO_OBJECT)
return;
if (TestEnvironment(ENV_FLAG_WATER, item)) if (TestEnvironment(ENV_FLAG_WATER, item))
{ {
SetAnimation(item, LA_UNDERWATER_IDLE); SetAnimation(item, LA_UNDERWATER_IDLE);
@ -197,6 +204,7 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
{ {
case GAME_OBJECT_ID::ID_KAYAK: case GAME_OBJECT_ID::ID_KAYAK:
InitializeKayak(vehicle->Index); InitializeKayak(vehicle->Index);
KayakPaddleTake(GetKayakInfo(&g_Level.Items[vehicle->Index]), &playerItem);
break; break;
case GAME_OBJECT_ID::ID_MOTORBIKE: case GAME_OBJECT_ID::ID_MOTORBIKE:
@ -215,9 +223,38 @@ static void InitializePlayerVehicle(ItemInfo& playerItem)
InitializeSkidoo(vehicle->Index); InitializeSkidoo(vehicle->Index);
break; break;
case GAME_OBJECT_ID::ID_MINECART:
MinecartWrenchTake(GetMinecartInfo(&g_Level.Items[vehicle->Index]), &playerItem);
break;
case GAME_OBJECT_ID::ID_SPEEDBOAT:
InitializeSpeedboat(vehicle->Index);
DoSpeedboatMount(&g_Level.Items[vehicle->Index], &playerItem, VehicleMountType::LevelStart);
break;
case GAME_OBJECT_ID::ID_RUBBER_BOAT:
InitializeRubberBoat(vehicle->Index);
DoRubberBoatMount(&g_Level.Items[vehicle->Index], &playerItem, VehicleMountType::LevelStart);
break;
case GAME_OBJECT_ID::ID_UPV:
DoUPVMount(&g_Level.Items[vehicle->Index], &playerItem, VehicleMountType::LevelStart);
GetUPVInfo(&g_Level.Items[vehicle->Index])->Flags = UPVFlags::UPV_FLAG_CONTROL;
break;
default: default:
break; break;
} }
// HACK: Reset activity status because boats need to be on active item linked list.
if (vehicle->ObjectNumber == GAME_OBJECT_ID::ID_RUBBER_BOAT ||
vehicle->ObjectNumber == GAME_OBJECT_ID::ID_SPEEDBOAT)
{
g_Level.Items[vehicle->Index].Active = false;
AddActiveItem(vehicle->Index);
g_Level.Items[vehicle->Index].Status = ITEM_ACTIVE;
}
} }
void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup) void InitializeLaraLevelJump(ItemInfo* item, LaraInfo* playerBackup)

View file

@ -935,11 +935,11 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
// Extra bridge check. // Extra bridge check.
if (coll->Front.Bridge != NO_VALUE) if (coll->Front.Bridge != NO_VALUE)
{ {
int bridgeBorder = GetBridgeBorder(g_Level.Items[coll->Front.Bridge], false) - item->Pose.Position.y; frontFloor = GetBridgeBorder(g_Level.Items[coll->Front.Bridge], false) - item->Pose.Position.y;
frontFloor = bridgeBorder - CLICK(0.5f); int bridgeBorder = frontFloor - CLICK(0.5f);
if (frontFloor <= -CLICK(2) || if (bridgeBorder <= -CLICK(2) ||
frontFloor > CLICK(1.25f) - 4) bridgeBorder > CLICK(1.25f) - 4)
{ {
return false; return false;
} }

View file

@ -952,9 +952,19 @@ void BinocularCamera(ItemInfo* item)
player.Inventory.IsBusy = false; player.Inventory.IsBusy = false;
Camera.type = BinocularOldCamera; Camera.type = BinocularOldCamera;
Camera.target = LastTarget;
AlterFOV(LastFOV); AlterFOV(LastFOV);
return; return;
} }
if (IsHeld(In::Action))
{
ClearAction(In::Action);
auto origin = Camera.pos.ToVector3i();
auto target = Camera.target.ToVector3i();
LaraTorch(&origin, &target, player.ExtraHeadRot.y, 192);
}
} }
AlterFOV(7 * (ANGLE(11.5f) - player.Control.Look.OpticRange), false); AlterFOV(7 * (ANGLE(11.5f) - player.Control.Look.OpticRange), false);
@ -1022,13 +1032,6 @@ void BinocularCamera(ItemInfo* item)
Camera.oldType = Camera.type; Camera.oldType = Camera.type;
GetTargetOnLOS(&Camera.pos, &Camera.target, false, false); GetTargetOnLOS(&Camera.pos, &Camera.target, false, false);
if (IsHeld(In::Action))
{
auto origin = Camera.pos.ToVector3i();
auto target = Camera.target.ToVector3i();
LaraTorch(&origin, &target, player.ExtraHeadRot.y, 192);
}
} }
void ConfirmCameraTargetPos() void ConfirmCameraTargetPos()
@ -1518,6 +1521,21 @@ void ItemsCollideCamera()
staticList.clear(); staticList.clear();
} }
void UpdateCamera()
{
if (UseSpotCam)
{
// Draw flyby cameras.
CalculateSpotCameras();
}
else
{
// Do the standard camera.
TrackCameraInit = false;
CalculateCamera(LaraCollision);
}
}
void UpdateMikePos(const ItemInfo& item) void UpdateMikePos(const ItemInfo& item)
{ {
if (Camera.mikeAtLara) if (Camera.mikeAtLara)
@ -1545,7 +1563,8 @@ void UpdateMikePos(const ItemInfo& item)
void RumbleScreen() void RumbleScreen()
{ {
if (!(GlobalCounter & 0x1FF)) if (!(GlobalCounter & 0x1FF))
SoundEffect(SFX_TR5_KLAXON, nullptr, SoundEnvironment::Land, 0.25f); // SFX Enum Changed from TR5 and pitch shift removed. User can set this in their sound XML. Stranger1992 31st August 2024
SoundEffect(SFX_TR4_ENVIORONMENT_RUMBLE, nullptr, SoundEnvironment::Land);
if (RumbleTimer >= 0) if (RumbleTimer >= 0)
RumbleTimer++; RumbleTimer++;

View file

@ -103,16 +103,18 @@ void RumbleScreen();
bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius); bool TestBoundsCollideCamera(const GameBoundingBox& bounds, const Pose& pose, short radius);
void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius); void ItemPushCamera(GameBoundingBox* bounds, Pose* pos, short radius);
void ItemsCollideCamera(); void ItemsCollideCamera();
void RefreshFixedCamera(short camNumber);
void ObjCamera(ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID, bool cond); void ObjCamera(ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID, bool cond);
void MoveObjCamera(GameVector* ideal, ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID); void MoveObjCamera(GameVector* ideal, ItemInfo* camSlotId, int camMeshID, ItemInfo* targetItem, int targetMeshID);
void RefreshFixedCamera(short camNumber); void ClearObjCamera();
void SetScreenFadeOut(float speed, bool force = false); void SetScreenFadeOut(float speed, bool force = false);
void SetScreenFadeIn(float speed, bool force = false); void SetScreenFadeIn(float speed, bool force = false);
void SetCinematicBars(float height, float speed); void SetCinematicBars(float height, float speed);
void ClearCinematicBars(); void ClearCinematicBars();
void UpdateCamera();
void UpdateFadeScreenAndCinematicBars(); void UpdateFadeScreenAndCinematicBars();
void UpdateMikePos(const ItemInfo& item); void UpdateMikePos(const ItemInfo& item);
void ClearObjCamera();
float GetParticleDistanceFade(const Vector3i& pos); float GetParticleDistanceFade(const Vector3i& pos);

View file

@ -89,7 +89,6 @@ using namespace TEN::Renderer;
int GameTimer = 0; int GameTimer = 0;
int GlobalCounter = 0; int GlobalCounter = 0;
int Wibble = 0;
bool InitializeGame; bool InitializeGame;
bool DoTheGame; bool DoTheGame;
@ -185,27 +184,13 @@ GameStatus ControlPhase(int numFrames)
ApplyActionQueue(); ApplyActionQueue();
ClearActionQueue(); ClearActionQueue();
UpdateCamera();
UpdateAllItems(); UpdateAllItems();
UpdateAllEffects(); UpdateAllEffects();
UpdateLara(LaraItem, isTitle); UpdateLara(LaraItem, isTitle);
g_GameScriptEntities->TestCollidingObjects(); g_GameScriptEntities->TestCollidingObjects();
if (UseSpotCam)
{
// Draw flyby cameras.
CalculateSpotCameras();
}
else
{
// Do the standard camera.
TrackCameraInit = false;
CalculateCamera(LaraCollision);
}
// Update oscillator seed.
Wibble = (Wibble + WIBBLE_SPEED) & WIBBLE_MAX;
// Smash shatters and clear stopper flags under them. // Smash shatters and clear stopper flags under them.
UpdateShatters(); UpdateShatters();
@ -213,6 +198,7 @@ GameStatus ControlPhase(int numFrames)
Weather.Update(); Weather.Update();
// Update effects. // Update effects.
UpdateWibble();
StreamerEffect.Update(); StreamerEffect.Update();
UpdateSparks(); UpdateSparks();
UpdateFireSparks(); UpdateFireSparks();

View file

@ -50,15 +50,11 @@ enum FadeStatus
constexpr int MAX_ROOMS = 1024; constexpr int MAX_ROOMS = 1024;
constexpr int WIBBLE_SPEED = 4;
constexpr int WIBBLE_MAX = UCHAR_MAX - WIBBLE_SPEED + 1;
constexpr int LOOP_FRAME_COUNT = 2; constexpr int LOOP_FRAME_COUNT = 2;
extern int GameTimer; extern int GameTimer;
extern int RumbleTimer; extern int RumbleTimer;
extern int GlobalCounter; extern int GlobalCounter;
extern int Wibble;
extern bool InitializeGame; extern bool InitializeGame;
extern bool DoTheGame; extern bool DoTheGame;

View file

@ -40,6 +40,9 @@ using namespace TEN::Math::Random;
using TEN::Renderer::g_Renderer; using TEN::Renderer::g_Renderer;
constexpr int WIBBLE_SPEED = 4;
constexpr int WIBBLE_MAX = UCHAR_MAX - WIBBLE_SPEED + 1;
// New particle class // New particle class
Particle Particles[MAX_PARTICLES]; Particle Particles[MAX_PARTICLES];
ParticleDynamic ParticleDynamics[MAX_PARTICLE_DYNAMICS]; ParticleDynamic ParticleDynamics[MAX_PARTICLE_DYNAMICS];
@ -49,7 +52,9 @@ FX_INFO EffectList[NUM_EFFECTS];
GameBoundingBox DeadlyBounds; GameBoundingBox DeadlyBounds;
SPLASH_SETUP SplashSetup; SPLASH_SETUP SplashSetup;
SPLASH_STRUCT Splashes[MAX_SPLASHES]; SPLASH_STRUCT Splashes[MAX_SPLASHES];
int SplashCount = 0; int SplashCount = 0;
int Wibble = 0;
Vector3i NodeVectors[ParticleNodeOffsetIDs::NodeMax]; Vector3i NodeVectors[ParticleNodeOffsetIDs::NodeMax];
NODEOFFSET_INFO NodeOffsets[ParticleNodeOffsetIDs::NodeMax] = NODEOFFSET_INFO NodeOffsets[ParticleNodeOffsetIDs::NodeMax] =
@ -180,6 +185,13 @@ void SetSpriteSequence(Particle& particle, GAME_OBJECT_ID objectID)
particle.spriteIndex = Objects[objectID].meshIndex + (int)round(Lerp(0.0f, numSprites, normalizedAge)); particle.spriteIndex = Objects[objectID].meshIndex + (int)round(Lerp(0.0f, numSprites, normalizedAge));
} }
void UpdateWibble()
{
// Update oscillator seed.
Wibble = (Wibble + WIBBLE_SPEED) & WIBBLE_MAX;
}
void UpdateSparks() void UpdateSparks()
{ {
auto bounds = GameBoundingBox(LaraItem); auto bounds = GameBoundingBox(LaraItem);

View file

@ -18,6 +18,8 @@ constexpr auto NUM_EFFECTS = 256;
constexpr auto MAX_PARTICLES = 1024; constexpr auto MAX_PARTICLES = 1024;
constexpr auto MAX_PARTICLE_DYNAMICS = 8; constexpr auto MAX_PARTICLE_DYNAMICS = 8;
extern int Wibble;
enum SpriteEnumFlag enum SpriteEnumFlag
{ {
SP_NONE = 0, SP_NONE = 0,
@ -279,5 +281,6 @@ void TriggerRocketFire(int x, int y, int z);
void TriggerExplosionBubbles(int x, int y, int z, short roomNumber); void TriggerExplosionBubbles(int x, int y, int z, short roomNumber);
void Ricochet(Pose& pos); void Ricochet(Pose& pos);
void ProcessEffects(ItemInfo* item); void ProcessEffects(ItemInfo* item);
void UpdateWibble();
void TriggerDynamicLight(const Vector3& pos, const Color& color, float falloff); void TriggerDynamicLight(const Vector3& pos, const Color& color, float falloff);

View file

@ -321,7 +321,7 @@ namespace TEN::Effects::Hair
{ {
auto& unit = Units[i]; auto& unit = Units[i];
auto objectID = (i == 0) ? ID_SINGLE_BRAID_HAIR : ID_DUAL_PIGTAIL_HAIR; auto objectID = (i == 0) ? ID_HAIR_PRIMARY : ID_HAIR_SECONDARY;
const auto& object = Objects[objectID]; const auto& object = Objects[objectID];
unit.IsEnabled = (object.loaded && (i == 0 || (i == 1 && isYoung))); unit.IsEnabled = (object.loaded && (i == 0 || (i == 1 && isYoung)));

View file

@ -33,9 +33,9 @@ namespace TEN::Entities::Vehicles
constexpr int KAYAK_VELOCITY_LR_ACCEL = 16 * VEHICLE_VELOCITY_SCALE; constexpr int KAYAK_VELOCITY_LR_ACCEL = 16 * VEHICLE_VELOCITY_SCALE;
constexpr int KAYAK_VELOCITY_HOLD_TURN_DECEL = 0.5f * VEHICLE_VELOCITY_SCALE; constexpr int KAYAK_VELOCITY_HOLD_TURN_DECEL = 0.5f * VEHICLE_VELOCITY_SCALE;
constexpr int KAYAK_VELOCITY_FRICTION_DECEL = 0.5f * VEHICLE_VELOCITY_SCALE; constexpr int KAYAK_VELOCITY_FRICTION_DECEL = 0.5f * VEHICLE_VELOCITY_SCALE;
constexpr int KAYAK_VELOCITY_MAX = 56 * VEHICLE_VELOCITY_SCALE; constexpr int KAYAK_VELOCITY_MAX = 56 * VEHICLE_VELOCITY_SCALE;
constexpr auto KAYAK_FLAG_PADDLE_MESH = 0x80;
constexpr auto KAYAK_WAKE_OFFSET = Vector3(BLOCK(0.1f), 0.0f, BLOCK(0.25f)); constexpr auto KAYAK_WAKE_OFFSET = Vector3(BLOCK(0.1f), 0.0f, BLOCK(0.25f));
// TODO: Very confusing. // TODO: Very confusing.
@ -221,6 +221,20 @@ namespace TEN::Entities::Vehicles
// SetupRipple(x, kayakItem->Pose.Position.y, z, -2 - (GetRandomControl() & 1), 0, Objects[ID_KAYAK_PADDLE_TRAIL_SPRITE].meshIndex,TO_RAD(kayakItem->Pose.Orientation.y)); // SetupRipple(x, kayakItem->Pose.Position.y, z, -2 - (GetRandomControl() & 1), 0, Objects[ID_KAYAK_PADDLE_TRAIL_SPRITE].meshIndex,TO_RAD(kayakItem->Pose.Orientation.y));
} }
void KayakPaddleTake(KayakInfo* kayak, ItemInfo* laraItem)
{
kayak->Flags |= KAYAK_FLAG_PADDLE_MESH;
laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND;
laraItem->MeshBits.Clear(KayakLaraLegJoints);
}
void KayakPaddlePut(KayakInfo* kayak, ItemInfo* laraItem)
{
kayak->Flags &= ~KAYAK_FLAG_PADDLE_MESH;
laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
laraItem->MeshBits.Set(KayakLaraLegJoints);
}
int KayakGetCollisionAnim(ItemInfo* kayakItem, int xDiff, int zDiff) int KayakGetCollisionAnim(ItemInfo* kayakItem, int xDiff, int zDiff)
{ {
xDiff = kayakItem->Pose.Position.x - xDiff; xDiff = kayakItem->Pose.Position.x - xDiff;
@ -897,28 +911,14 @@ namespace TEN::Entities::Vehicles
break; break;
case KAYAK_STATE_MOUNT_LEFT: case KAYAK_STATE_MOUNT_LEFT:
if (TestAnimNumber(*laraItem, KAYAK_ANIM_GET_PADDLE) && if (TestAnimNumber(*laraItem, KAYAK_ANIM_GET_PADDLE) && frame == 24 && !(kayak->Flags & KAYAK_FLAG_PADDLE_MESH))
frame == 24 && KayakPaddleTake(kayak, laraItem);
!(kayak->Flags & 0x80))
{
kayak->Flags |= 0x80;
laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND;
laraItem->MeshBits.Clear(KayakLaraLegJoints);
}
break; break;
case KAYAK_STATE_DISMOUNT: case KAYAK_STATE_DISMOUNT:
if (TestAnimNumber(*laraItem, KAYAK_ANIM_DISMOUNT_START) &&
frame == 27 &&
kayak->Flags & 0x80)
{
kayak->Flags &= ~0x80;
laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
laraItem->MeshBits.Set(KayakLaraLegJoints);
}
laraItem->Animation.TargetState = laraItem->Animation.RequiredState; laraItem->Animation.TargetState = laraItem->Animation.RequiredState;
if (TestAnimNumber(*laraItem, KAYAK_ANIM_DISMOUNT_START) && frame == 27 && kayak->Flags & KAYAK_FLAG_PADDLE_MESH)
KayakPaddlePut(kayak, laraItem);
break; break;
case KAYAK_STATE_DISMOUNT_LEFT: case KAYAK_STATE_DISMOUNT_LEFT:

View file

@ -6,24 +6,27 @@ struct ItemInfo;
namespace TEN::Entities::Vehicles namespace TEN::Entities::Vehicles
{ {
KayakInfo* GetKayakInfo(ItemInfo* kayakItem);
void InitializeKayak(short itemNumber); void InitializeKayak(short itemNumber);
void KayakPlayerCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); void KayakPlayerCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void DoKayakMount(ItemInfo* kayakItem, ItemInfo* laraItem, VehicleMountType mountType); void DoKayakMount(ItemInfo* kayakItem, ItemInfo* laraItem, VehicleMountType mountType);
void KayakPaddleTake(KayakInfo* kayak, ItemInfo* laraItem);
void KayakPaddlePut(KayakInfo* kayak, ItemInfo* laraItem);
void KayakDraw(ItemInfo* kayakItem); void KayakDraw(ItemInfo* kayakItem);
void KayakDoRipple(ItemInfo* kayakItem, int xOffset, int zOffset); void KayakDoRipple(ItemInfo* kayakItem, int xOffset, int zOffset);
int KayakGetCollisionAnim(ItemInfo* kayakItem, int xDiff, int zDiff); int KayakGetCollisionAnim(ItemInfo* kayakItem, int xDiff, int zDiff);
int KayakDoDynamics(int height, int verticalVelocity, int* y); int KayakDoDynamics(int height, int verticalVelocity, int* y);
void KayakDoCurrent(ItemInfo* kayakItem, ItemInfo* laraItem); void KayakDoCurrent(ItemInfo* kayakItem, ItemInfo* laraItem);
bool KayakCanGetOut(ItemInfo* kayakItem, int dir); bool KayakCanGetOut(ItemInfo* kayakItem, int dir);
int KayakDoShift(ItemInfo* kayakItem, Vector3i* pos, Vector3i* old); int KayakDoShift(ItemInfo* kayakItem, Vector3i* pos, Vector3i* old);
void KayakToBackground(ItemInfo* kayakItem, ItemInfo* laraItem); void KayakToBackground(ItemInfo* kayakItem, ItemInfo* laraItem);
void KayakUserInput(ItemInfo* kayakItem, ItemInfo* laraItem); void KayakUserInput(ItemInfo* kayakItem, ItemInfo* laraItem);
void KayakToItemCollision(ItemInfo* kayakItem, ItemInfo* laraItem); void KayakToItemCollision(ItemInfo* kayakItem, ItemInfo* laraItem);
void KayakLaraRapidsDrown(ItemInfo* laraItem); void KayakLaraRapidsDrown(ItemInfo* laraItem);
void PreDrawWakeFx(ItemInfo* kayakItem);
bool KayakControl(ItemInfo* laraItem); bool KayakControl(ItemInfo* laraItem);
} }

View file

@ -241,6 +241,18 @@ namespace TEN::Entities::Vehicles
} }
} }
void MinecartWrenchTake(MinecartInfo* minecart, ItemInfo* laraItem)
{
laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
minecart->Flags |= MINECART_FLAG_WRENCH_MESH;
}
void MinecartWrenchPut(MinecartInfo* minecart, ItemInfo* laraItem)
{
laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
minecart->Flags &= ~MINECART_FLAG_WRENCH_MESH;
}
static int GetMinecartCollision(ItemInfo* minecartItem, short angle, int distance) static int GetMinecartCollision(ItemInfo* minecartItem, short angle, int distance)
{ {
auto probe = GetPointCollision(*minecartItem, angle, distance, -LARA_HEIGHT); auto probe = GetPointCollision(*minecartItem, angle, distance, -LARA_HEIGHT);
@ -755,8 +767,7 @@ namespace TEN::Entities::Vehicles
if (laraItem->Animation.FrameNumber == GetFrameIndex(minecartItem, MINECART_WRENCH_MESH_TOGGLE_FRAME) && if (laraItem->Animation.FrameNumber == GetFrameIndex(minecartItem, MINECART_WRENCH_MESH_TOGGLE_FRAME) &&
minecart->Flags & MINECART_FLAG_WRENCH_MESH) minecart->Flags & MINECART_FLAG_WRENCH_MESH)
{ {
laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND; MinecartWrenchPut(minecart, laraItem);
minecart->Flags &= ~MINECART_FLAG_WRENCH_MESH;
} }
if (minecart->Flags & MINECART_FLAG_DISMOUNT_RIGHT) if (minecart->Flags & MINECART_FLAG_DISMOUNT_RIGHT)
@ -804,8 +815,7 @@ namespace TEN::Entities::Vehicles
if (!(minecart->Flags & MINECART_FLAG_WRENCH_MESH) && if (!(minecart->Flags & MINECART_FLAG_WRENCH_MESH) &&
laraItem->Animation.FrameNumber == GetFrameIndex(minecartItem, MINECART_WRENCH_MESH_TOGGLE_FRAME)) laraItem->Animation.FrameNumber == GetFrameIndex(minecartItem, MINECART_WRENCH_MESH_TOGGLE_FRAME))
{ {
laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND; MinecartWrenchTake(minecart, laraItem);
minecart->Flags |= MINECART_FLAG_WRENCH_MESH;
} }
} }

View file

@ -7,9 +7,13 @@ struct ItemInfo;
namespace TEN::Entities::Vehicles namespace TEN::Entities::Vehicles
{ {
void InitializeMinecart(short itemNumber); void InitializeMinecart(short itemNumber);
MinecartInfo* GetMinecartInfo(ItemInfo* minecartItem);
void MinecartPlayerCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); void MinecartPlayerCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void DoMinecartMount(ItemInfo* minecartItem, ItemInfo* laraItem, VehicleMountType mountType); void DoMinecartMount(ItemInfo* minecartItem, ItemInfo* laraItem, VehicleMountType mountType);
bool MinecartControl(ItemInfo* laraItem); bool MinecartControl(ItemInfo* laraItem);
void MinecartWrenchTake(MinecartInfo* minecart, ItemInfo* laraItem);
void MinecartWrenchPut(MinecartInfo* minecart, ItemInfo* laraItem);
} }

View file

@ -151,21 +151,13 @@ namespace TEN::Entities::Vehicles
UPV_BITE_RIGHT_RUDDER_RIGHT = 4, UPV_BITE_RIGHT_RUDDER_RIGHT = 4,
UPV_BITE_RIGHT_RUDDER_LEFT = 5 // Unused. UPV_BITE_RIGHT_RUDDER_LEFT = 5 // Unused.
}; };
enum UPVFlags
{
UPV_FLAG_CONTROL = (1 << 0),
UPV_FLAG_SURFACE = (1 << 1),
UPV_FLAG_DIVE = (1 << 2),
UPV_FLAG_DEAD = (1 << 3)
};
UPVInfo* GetUPVInfo(ItemInfo* UPVItem) UPVInfo* GetUPVInfo(ItemInfo* UPVItem)
{ {
return (UPVInfo*)UPVItem->Data; return (UPVInfo*)UPVItem->Data;
} }
void UPVInitialize(short itemNumber) void InitializeUPV(short itemNumber)
{ {
auto* UPVItem = &g_Level.Items[itemNumber]; auto* UPVItem = &g_Level.Items[itemNumber];
UPVItem->Data = UPVInfo(); UPVItem->Data = UPVInfo();

View file

@ -6,7 +6,16 @@ struct ItemInfo;
namespace TEN::Entities::Vehicles namespace TEN::Entities::Vehicles
{ {
void UPVInitialize(short itemNumber); enum UPVFlags
{
UPV_FLAG_CONTROL = (1 << 0),
UPV_FLAG_SURFACE = (1 << 1),
UPV_FLAG_DIVE = (1 << 2),
UPV_FLAG_DEAD = (1 << 3)
};
void InitializeUPV(short itemNumber);
UPVInfo* GetUPVInfo(ItemInfo* UPVItem);
void UPVPlayerCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); void UPVPlayerCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
void DoUPVMount(ItemInfo* UPVItem, ItemInfo* laraItem, VehicleMountType mountType); void DoUPVMount(ItemInfo* UPVItem, ItemInfo* laraItem, VehicleMountType mountType);

View file

@ -583,7 +583,7 @@ static void StartVehicles(ObjectInfo* obj)
obj = &Objects[ID_UPV]; obj = &Objects[ID_UPV];
if (obj->loaded) if (obj->loaded)
{ {
obj->Initialize = UPVInitialize; obj->Initialize = InitializeUPV;
obj->control = UPVEffects; obj->control = UPVEffects;
obj->collision = UPVPlayerCollision; obj->collision = UPVPlayerCollision;
obj->shadowType = ShadowMode::Lara; obj->shadowType = ShadowMode::Lara;

View file

@ -3,6 +3,7 @@
#include "Game/collision/collide_room.h" #include "Game/collision/collide_room.h"
#include "Game/control/flipeffect.h" #include "Game/control/flipeffect.h"
#include "Game/effects/effects.h"
#include "Game/items.h" #include "Game/items.h"
#include "Game/Lara/lara.h" #include "Game/Lara/lara.h"
#include "Game/Setup.h" #include "Game/Setup.h"

View file

@ -73,6 +73,6 @@ void SarcophagusCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* c
} }
else else
{ {
CollectMultiplePickups(sarcItem->Index); CollectCarriedItems(sarcItem);
} }
} }

View file

@ -40,8 +40,8 @@ enum GAME_OBJECT_ID : short
ID_LARA_DIRT_MESH, ID_LARA_DIRT_MESH,
ID_LARA_CROWBAR_ANIM, ID_LARA_CROWBAR_ANIM,
ID_LARA_TORCH_ANIM, ID_LARA_TORCH_ANIM,
ID_SINGLE_BRAID_HAIR, ID_HAIR_PRIMARY,
ID_DUAL_PIGTAIL_HAIR, ID_HAIR_SECONDARY,
ID_SNOWMOBILE_LARA_ANIMS = 50, ID_SNOWMOBILE_LARA_ANIMS = 50,
ID_SNOWMOBILE, ID_SNOWMOBILE,

View file

@ -516,7 +516,7 @@ namespace TEN::Renderer
&moveable, &moveable,
&g_Level.Meshes[obj->meshIndex + j], &g_Level.Meshes[obj->meshIndex + j],
j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS, j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS,
MoveablesIds[i] == ID_SINGLE_BRAID_HAIR || MoveablesIds[i] == ID_DUAL_PIGTAIL_HAIR, &lastVertex, &lastIndex); MoveablesIds[i] == ID_HAIR_PRIMARY || MoveablesIds[i] == ID_HAIR_SECONDARY, &lastVertex, &lastIndex);
moveable.ObjectMeshes.push_back(mesh); moveable.ObjectMeshes.push_back(mesh);
_meshes.push_back(mesh); _meshes.push_back(mesh);
@ -687,7 +687,7 @@ namespace TEN::Renderer
} }
} }
} }
else if (MoveablesIds[i] == ID_SINGLE_BRAID_HAIR && isSkinPresent) else if (MoveablesIds[i] == ID_HAIR_PRIMARY && isSkinPresent)
{ {
for (int j = 0; j < obj->nmeshes; j++) for (int j = 0; j < obj->nmeshes; j++)
{ {
@ -776,7 +776,7 @@ namespace TEN::Renderer
} }
} }
} }
else if (MoveablesIds[i] == ID_DUAL_PIGTAIL_HAIR && isSkinPresent) else if (MoveablesIds[i] == ID_HAIR_SECONDARY && isSkinPresent)
{ {
for (int j = 0; j < obj->nmeshes; j++) for (int j = 0; j < obj->nmeshes; j++)
{ {

View file

@ -1260,8 +1260,8 @@ namespace TEN::Renderer
case RendererDebugPage::PlayerStats: case RendererDebugPage::PlayerStats:
PrintDebugMessage("PLAYER STATS"); PrintDebugMessage("PLAYER STATS");
PrintDebugMessage("AnimObjectID: %d", LaraItem->Animation.AnimObjectID); PrintDebugMessage("AnimObjectID: %d", LaraItem->Animation.AnimObjectID);
PrintDebugMessage("AnimNumber: %d", LaraItem->Animation.AnimNumber); PrintDebugMessage("AnimNumber: %d", LaraItem->Animation.AnimNumber - Objects[LaraItem->Animation.AnimObjectID].animIndex);
PrintDebugMessage("FrameNumber: %d", LaraItem->Animation.FrameNumber); PrintDebugMessage("FrameNumber: %d", LaraItem->Animation.FrameNumber - GetAnimData(LaraItem).frameBase);
PrintDebugMessage("ActiveState: %d", LaraItem->Animation.ActiveState); PrintDebugMessage("ActiveState: %d", LaraItem->Animation.ActiveState);
PrintDebugMessage("TargetState: %d", LaraItem->Animation.TargetState); PrintDebugMessage("TargetState: %d", LaraItem->Animation.TargetState);
PrintDebugMessage("Velocity: %.3f, %.3f, %.3f", LaraItem->Animation.Velocity.z, LaraItem->Animation.Velocity.y, LaraItem->Animation.Velocity.x); PrintDebugMessage("Velocity: %.3f, %.3f, %.3f", LaraItem->Animation.Velocity.z, LaraItem->Animation.Velocity.y, LaraItem->Animation.Velocity.x);

View file

@ -85,6 +85,9 @@ void Renderer::UpdateLaraAnimations(bool force)
if (!force && rItem.DoneAnimations) if (!force && rItem.DoneAnimations)
return; return;
if (_moveableObjects.empty())
return;
auto& playerObject = *_moveableObjects[ID_LARA]; auto& playerObject = *_moveableObjects[ID_LARA];
// Clear extra rotations. // Clear extra rotations.

View file

@ -22,10 +22,8 @@ static constexpr char ScriptReserved_Sink[] = "Sink";
static constexpr char ScriptReserved_SoundSource[] = "SoundSource"; static constexpr char ScriptReserved_SoundSource[] = "SoundSource";
static constexpr char ScriptReserved_AIObject[] = "AIObject"; static constexpr char ScriptReserved_AIObject[] = "AIObject";
static constexpr char ScriptReserved_Volume[] = "Volume"; static constexpr char ScriptReserved_Volume[] = "Volume";
static constexpr char ScriptReserved_Room[] = "Room";
static constexpr char ScriptReserved_Color[] = "Color"; static constexpr char ScriptReserved_Color[] = "Color";
static constexpr char ScriptReserved_DisplayString[] = "DisplayString"; static constexpr char ScriptReserved_DisplayString[] = "DisplayString";
static constexpr char ScriptReserved_Vec2[] = "Vec2";
static constexpr char ScriptReserved_Rotation[] = "Rotation"; static constexpr char ScriptReserved_Rotation[] = "Rotation";
static constexpr char ScriptReserved_LevelFunc[] = "LevelFunc"; static constexpr char ScriptReserved_LevelFunc[] = "LevelFunc";
@ -198,7 +196,6 @@ static constexpr char ScriptReserved_IsMoveableInside[] = "IsMoveableInside";
static constexpr char ScriptReserved_GetFlag[] = "GetFlag"; static constexpr char ScriptReserved_GetFlag[] = "GetFlag";
static constexpr char ScriptReserved_SetFlag[] = "SetFlag"; static constexpr char ScriptReserved_SetFlag[] = "SetFlag";
static constexpr char ScriptReserved_IsTagPresent[] = "IsTagPresent"; static constexpr char ScriptReserved_IsTagPresent[] = "IsTagPresent";
static constexpr char ScriptReserved_SetReverbType[] = "SetReverbType";
// Flow Functions // Flow Functions
static constexpr char ScriptReserved_AddLevel[] = "AddLevel"; static constexpr char ScriptReserved_AddLevel[] = "AddLevel";
@ -230,6 +227,7 @@ static constexpr char ScriptReserved_EnablePointFilter[] = "EnablePointFilter";
// Flow Functions // Flow Functions
static constexpr char ScriptReserved_SetStrings[] = "SetStrings"; static constexpr char ScriptReserved_SetStrings[] = "SetStrings";
static constexpr char ScriptReserved_GetString[] = "GetString"; static constexpr char ScriptReserved_GetString[] = "GetString";
static constexpr char ScriptReserved_IsStringPresent[] = "IsStringPresent";
static constexpr char ScriptReserved_SetLanguageNames[] = "SetLanguageNames"; static constexpr char ScriptReserved_SetLanguageNames[] = "SetLanguageNames";
// Flow Tables // Flow Tables
@ -371,22 +369,39 @@ static constexpr char ScriptReserved_LogLevelError[] = "ERROR";
// Internal // Internal
static constexpr char ScriptReserved_LaraObject[] = "LaraObject"; static constexpr char ScriptReserved_LaraObject[] = "LaraObject";
// Room
constexpr char ScriptReserved_Room[] = "Room";
constexpr char ScriptReserved_RoomGetActive[] = "GetActive";
constexpr char ScriptReserved_RoomGetColor[] = "GetColor";
constexpr char ScriptReserved_RoomGetFlag[] = "GetFlag";
constexpr char ScriptReserved_RoomGetName[] = "GetName";
constexpr char ScriptReserved_RoomGetReverbType[] = "GetReverbType";
constexpr char ScriptReserved_RoomGetRoomNumber[] = "GetRoomNumber";
constexpr char ScriptReserved_RoomIsTagPresent[] = "IsTagPresent";
constexpr char ScriptReserved_RoomSetFlag[] = "SetFlag";
constexpr char ScriptReserved_RoomSetName[] = "SetName";
constexpr char ScriptReserved_RoomSetReverbType[] = "SetReverbType";
// Vec2 // Vec2
constexpr char ScriptReserved_Vec2[] = "Vec2";
constexpr char ScriptReserved_Vec2Cross[] = "Cross";
constexpr char ScriptReserved_Vec2Distance[] = "Distance";
constexpr char ScriptReserved_Vec2Dot[] = "Dot";
constexpr char ScriptReserved_Vec2Length[] = "Length";
constexpr char ScriptReserved_Vec2Lerp[] = "Lerp";
constexpr char ScriptReserved_Vec2SetLength[] = "ToLength"; constexpr char ScriptReserved_Vec2SetLength[] = "ToLength";
constexpr char ScriptReserved_Vec2Normalize[] = "Normalize"; constexpr char ScriptReserved_Vec2Normalize[] = "Normalize";
constexpr char ScriptReserved_Vec2Rotate[] = "Rotate"; constexpr char ScriptReserved_Vec2Rotate[] = "Rotate";
constexpr char ScriptReserved_Vec2Lerp[] = "Lerp";
constexpr char ScriptReserved_Vec2Cross[] = "Cross";
constexpr char ScriptReserved_Vec2Dot[] = "Dot";
constexpr char ScriptReserved_Vec2Distance[] = "Distance";
constexpr char ScriptReserved_Vec2Length[] = "Length";
// Vec3 // Vec3
constexpr char ScriptReserved_Vec3[] = "Vec3"; constexpr char ScriptReserved_Vec3[] = "Vec3";
constexpr char ScriptReserved_Vec3Cross[] = "Cross";
constexpr char ScriptReserved_Vec3Distance[] = "Distance";
constexpr char ScriptReserved_Vec3Dot[] = "Dot";
constexpr char ScriptReserved_Vec3Length[] = "Length";
constexpr char ScriptReserved_Vec3Lerp[] = "Lerp";
constexpr char ScriptReserved_Vec3Normalize[] = "Normalize"; constexpr char ScriptReserved_Vec3Normalize[] = "Normalize";
constexpr char ScriptReserved_Vec3Rotate[] = "Rotate"; constexpr char ScriptReserved_Vec3Rotate[] = "Rotate";
constexpr char ScriptReserved_Vec3Lerp[] = "Lerp";
constexpr char ScriptReserved_Vec3Cross[] = "Cross";
constexpr char ScriptReserved_Vec3Dot[] = "Dot";
constexpr char ScriptReserved_Vec3Distance[] = "Distance";
constexpr char ScriptReserved_Vec3Length[] = "Length";

View file

@ -248,6 +248,12 @@ You will not need to call them manually.
*/ */
tableFlow.set_function(ScriptReserved_GetString, &FlowHandler::GetString, this); tableFlow.set_function(ScriptReserved_GetString, &FlowHandler::GetString, this);
/*** Check if translated string is present.
@function IsStringPresent
@tparam key string key for translated string
*/
tableFlow.set_function(ScriptReserved_IsStringPresent, &FlowHandler::IsStringPresent, this);
/*** Set language names for translations. /*** Set language names for translations.
Specify which translations in the strings table correspond to which languages. Specify which translations in the strings table correspond to which languages.
@function SetLanguageNames @function SetLanguageNames
@ -371,6 +377,11 @@ char const * FlowHandler::GetString(const char* id) const
} }
} }
bool FlowHandler::IsStringPresent(const char* id) const
{
return _translationMap.find(id) != _translationMap.end();
}
Settings* FlowHandler::GetSettings() Settings* FlowHandler::GetSettings()
{ {
return &_settings; return &_settings;

View file

@ -51,6 +51,7 @@ public:
void AddLevel(Level const& level); void AddLevel(Level const& level);
void LoadFlowScript(); void LoadFlowScript();
char const* GetString(const char* id) const; char const* GetString(const char* id) const;
bool IsStringPresent(const char* id) const;
void SetStrings(sol::nested<std::unordered_map<std::string, std::vector<std::string>>>&& src); void SetStrings(sol::nested<std::unordered_map<std::string, std::vector<std::string>>>&& src);
void SetLanguageNames(sol::as_table_t<std::vector<std::string>>&& src); void SetLanguageNames(sol::as_table_t<std::vector<std::string>>&& src);
void SetAnimations(const Animations& src); void SetAnimations(const Animations& src);

View file

@ -79,7 +79,7 @@ most can just be ignored (see usage).
@tparam string name Lua name of the item @tparam string name Lua name of the item
@tparam Vec3 position position in level @tparam Vec3 position position in level
@tparam Rotation rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0)) @tparam Rotation rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
@tparam int roomID room ID item is in (default: calculated automatically) @tparam int roomNumber the room number the moveable is in (default: calculated automatically).
@tparam int animNumber animation number @tparam int animNumber animation number
@tparam int frameNumber frame number @tparam int frameNumber frame number
@tparam int hp HP of item @tparam int hp HP of item

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "Scripting/Internal/ScriptUtil.h" #include "Scripting/Internal/ScriptUtil.h"
#include "Scripting/Internal/TEN/Objects/NamedBase.h" #include "Scripting/Internal/TEN/Objects/NamedBase.h"
#include "Scripting/Internal/TEN/Objects/Room/RoomObject.h" #include "Scripting/Internal/TEN/Objects/Room/RoomObject.h"

View file

@ -53,8 +53,8 @@ The following constants are inside ObjID.
LARA_DIRT_MESH LARA_DIRT_MESH
LARA_CROWBAR_ANIM LARA_CROWBAR_ANIM
LARA_TORCH_ANIM LARA_TORCH_ANIM
SINGLE_BRAID_HAIR HAIR_PRIMARY
DUAL_PIGTAIL_HAIR HAIR_SECONDARY
SNOWMOBILE_LARA_ANIMS SNOWMOBILE_LARA_ANIMS
SNOWMOBILE SNOWMOBILE
QUAD_LARA_ANIMS QUAD_LARA_ANIMS
@ -1231,8 +1231,8 @@ static const std::unordered_map<std::string, GAME_OBJECT_ID> kObjIDs {
{ "LARA_DIRT_MESH", ID_LARA_DIRT_MESH }, { "LARA_DIRT_MESH", ID_LARA_DIRT_MESH },
{ "LARA_CROWBAR_ANIM", ID_LARA_CROWBAR_ANIM }, { "LARA_CROWBAR_ANIM", ID_LARA_CROWBAR_ANIM },
{ "LARA_TORCH_ANIM", ID_LARA_TORCH_ANIM }, { "LARA_TORCH_ANIM", ID_LARA_TORCH_ANIM },
{ "SINGLE_BRAID_HAIR", ID_SINGLE_BRAID_HAIR }, { "HAIR_PRIMARY", ID_HAIR_PRIMARY },
{ "DUAL_PIGTAIL_HAIR", ID_DUAL_PIGTAIL_HAIR }, { "HAIR_SECONDARY", ID_HAIR_SECONDARY },
{ "SNOWMOBILE_LARA_ANIMS", ID_SNOWMOBILE_LARA_ANIMS }, { "SNOWMOBILE_LARA_ANIMS", ID_SNOWMOBILE_LARA_ANIMS },
{ "SNOWMOBILE", ID_SNOWMOBILE }, { "SNOWMOBILE", ID_SNOWMOBILE },
{ "QUAD_LARA_ANIMS", ID_QUAD_LARA_ANIMS }, { "QUAD_LARA_ANIMS", ID_QUAD_LARA_ANIMS },

View file

@ -13,141 +13,148 @@
#include "Specific/level.h" #include "Specific/level.h"
#include "Specific/trutils.h" #include "Specific/trutils.h"
/*** /// Room object.
Rooms // @tenclass Objects.Room
// @pragma nostrip
@tenclass Objects.Room //namespace TEN::Scripting
@pragma nostrip //{
*/ static auto IndexError = index_error_maker(Room, ScriptReserved_Volume);
static auto NewIndexError = newindex_error_maker(Room, ScriptReserved_Volume);
static auto IndexError = index_error_maker(Room, ScriptReserved_Volume); Room::Room(ROOM_INFO& room) :
static auto NewIndexError = newindex_error_maker(Room, ScriptReserved_Volume); _room(room)
Room::Room(ROOM_INFO& room) : m_room{ room }
{};
void Room::Register(sol::table& parent)
{
parent.new_usertype<Room>(ScriptReserved_Room,
sol::no_constructor,
sol::meta_function::index, IndexError,
sol::meta_function::new_index, NewIndexError,
/// Determine whether the room is active or not
// @function Room:GetActive
// @treturn bool true if the room is active
ScriptReserved_GetActive, &Room::GetActive,
/// Get the room's ambient light color.
// @function Room:GetColor
// @treturn Color ambient light color of the room
ScriptReserved_GetColor, & Room::GetColor,
/// Get the room's reverb type.
// @function Room:GetReverbType
// @treturn Objects.RoomReverb room's reverb type
ScriptReserved_GetPosition, &Room::GetReverbType,
/// Set the room's reverb type.
// @function Room:SetReverbType
// @tparam Objects.RoomReverb new reverb type of the room
ScriptReserved_SetReverbType, &Room::SetReverbType,
/// Get the room's unique string identifier.
// @function Room:GetName
// @treturn string the room's name
ScriptReserved_GetName, &Room::GetName,
/// Set the room's name (its unique string identifier).
// @function Room:SetName
// @tparam string name The room's new name
ScriptReserved_SetName, &Room::SetName,
/// Get the room's specified flag value (true or false).
// @function Room:GetFlag
// @tparam Objects.RoomFlagID flagID The room's flag ID
// @treturn bool the room's specified flag value
ScriptReserved_GetFlag, &Room::GetFlag,
/// Set the room's specified flag value.
// @function Room:SetFlag
// @tparam Objects.RoomFlagID flagID The room's flag ID
// @tparam bool the room's new flag value
ScriptReserved_SetFlag, &Room::SetFlag,
/// Checks if specified tag is set for this room.
// @function Room:IsTagPresent
// @tparam string tag A text tag to check (case sensitive)
// @treturn bool true if tag is present, false if not
ScriptReserved_IsTagPresent, &Room::IsTagPresent);
}
bool Room::GetActive() const
{
return m_room.Active();
}
ScriptColor Room::GetColor() const
{
return ScriptColor{ m_room.ambient };
}
ReverbType Room::GetReverbType() const
{
return m_room.reverbType;
}
void Room::SetReverbType(ReverbType reverb)
{
m_room.reverbType = reverb;
}
std::string Room::GetName() const
{
return m_room.Name;
}
void Room::SetName(const std::string& name)
{
if (!ScriptAssert(!name.empty(), "Unable to set name. Name cannot be blank."))
return;
// Remove old name if it already exists.
if (s_callbackSetName(name, m_room))
{ {
s_callbackRemoveName(m_room.Name); };
m_room.Name = name;
} void Room::Register(sol::table& parent)
else
{ {
ScriptAssertF(false, "Could not add name {} - does an object with this name already exist?", name); // Register type.
TENLog("Name will not be set", LogLevel::Warning, LogConfig::All); parent.new_usertype<Room>(
ScriptReserved_Room,
sol::no_constructor,
sol::meta_function::index, IndexError,
sol::meta_function::new_index, NewIndexError,
ScriptReserved_RoomGetRoomNumber, &Room::GetRoomNumber,
ScriptReserved_RoomGetName, &Room::GetName,
ScriptReserved_RoomGetColor, &Room::GetColor,
ScriptReserved_RoomGetReverbType, &Room::GetReverbType,
ScriptReserved_RoomSetName, &Room::SetName,
ScriptReserved_RoomSetReverbType, &Room::SetReverbType,
ScriptReserved_RoomSetFlag, &Room::SetFlag,
ScriptReserved_RoomIsTagPresent, &Room::IsTagPresent,
ScriptReserved_RoomGetActive, &Room::GetActive,
ScriptReserved_RoomGetFlag, &Room::GetFlag);
} }
}
bool Room::GetFlag(RoomEnvFlags flag) const /// Get the room's number.
{ // @function Room:GetRoomNumber()
return ((m_room.flags & flag) == flag); // @treturn int Room number.
} int Room::GetRoomNumber() const
void Room::SetFlag(RoomEnvFlags flag, bool value)
{
if (value)
{ {
m_room.flags |= flag; return _room.RoomNumber;
} }
else
/// Get the room's unique string identifier.
// @function Room:GetName()
// @treturn string Room name.
std::string Room::GetName() const
{ {
m_room.flags &= ~flag; return _room.Name;
} }
}
bool Room::IsTagPresent(const std::string& tag) const /// Get the room's ambient light color.
{ // @function Room:GetColor()
if (m_room.Tags.empty()) // @treturn Color Ambient light color.
return false; ScriptColor Room::GetColor() const
{
return ScriptColor(_room.ambient);
}
return std::any_of( /// Get the room's reverb type.
m_room.Tags.begin(), m_room.Tags.end(), // @function Room:GetReverbType()
[&tag](const std::string& value) { return (value == tag); }); // @treturn Objects.RoomReverb Reverb type.
} ReverbType Room::GetReverbType() const
{
return _room.reverbType;
}
/// Set the room's unique string identifier.
// @function Room:SetName()
// @tparam string name New name.
void Room::SetName(const std::string& name)
{
if (!ScriptAssert(!name.empty(), "Unable to set name. Name cannot be blank."))
return;
// Remove previous name if it already exists.
if (s_callbackSetName(name, _room))
{
s_callbackRemoveName(_room.Name);
_room.Name = name;
}
else
{
ScriptAssertF(false, "Could not add name {} - does an object with this name already exist?", name);
TENLog("Name will not be set", LogLevel::Warning, LogConfig::All);
}
}
/// Set the room's reverb type.
// @function Room:SetReverbType()
// @tparam Objects.RoomReverb Reverb type.
void Room::SetReverbType(ReverbType reverb)
{
_room.reverbType = reverb;
}
/// Set the room's specified flag.
// @function Room:SetFlag()
// @tparam Objects.RoomFlagID flagID Room flag ID.
// @tparam bool Boolean to set the flag to.
void Room::SetFlag(RoomEnvFlags flag, bool value)
{
if (value)
{
_room.flags |= flag;
}
else
{
_room.flags &= ~flag;
}
}
/// Get the room's specified flag value (true or false).
// @function Room:GetFlag()
// @tparam Objects.RoomFlagID flagID Room flag ID.
bool Room::IsTagPresent(const std::string& tag) const
{
if (_room.Tags.empty())
return false;
return std::any_of(
_room.Tags.begin(), _room.Tags.end(),
[&tag](const std::string& value)
{
return (value == tag);
});
}
/// Check if the specified tag is set for the room.
// @function Room:IsTagPresent()
// @tparam string tag Text tag to check (case sensitive).
// @treturn bool Boolean of the tag's presence.
bool Room::GetActive() const
{
return _room.Active();
}
/// Check if the room is active.
// @function Room:GetActive()
// @treturn bool Boolean of the room's active status.
bool Room::GetFlag(RoomEnvFlags flag) const
{
return ((_room.flags & flag) == flag);
}
//}

View file

@ -1,4 +1,5 @@
#pragma once #pragma once
#include "Game/room.h" #include "Game/room.h"
#include "Scripting/Internal/TEN/Objects/NamedBase.h" #include "Scripting/Internal/TEN/Objects/NamedBase.h"
@ -7,32 +8,50 @@ enum class ReverbType;
class ScriptColor; class ScriptColor;
class Vec3; class Vec3;
class Room : public NamedBase<Room, ROOM_INFO&> //namespace TEN::Scripting
{ //{
public: class Room : public NamedBase<Room, ROOM_INFO&>
using IdentifierType = std::reference_wrapper<ROOM_INFO>; {
Room(ROOM_INFO& room); private:
~Room() = default; // Members
Room& operator =(const Room& other) = delete; ROOM_INFO& _room;
Room(const Room& other) = delete;
static void Register(sol::table& parent); public:
using IdentifierType = std::reference_wrapper<ROOM_INFO>;
[[nodiscard]] bool GetActive() const; static void Register(sol::table& parent);
[[nodiscard]] ScriptColor GetColor() const;
[[nodiscard]] std::string GetName() const; // Constructors
void SetName(const std::string& name);
[[nodiscard]] bool GetFlag(RoomEnvFlags flag) const; Room(ROOM_INFO& room);
void SetFlag(RoomEnvFlags flag, bool value); Room(const Room& room) = delete;
[[nodiscard]] ReverbType GetReverbType() const; // Destructors
void SetReverbType(ReverbType reverbType);
[[nodiscard]] bool IsTagPresent(const std::string& tag) const; ~Room() = default;
private: // Getters
ROOM_INFO& m_room;
}; int GetRoomNumber() const;
std::string GetName() const;
ScriptColor GetColor() const;
ReverbType GetReverbType() const;
// Setters
void SetName(const std::string& name);
void SetReverbType(ReverbType reverbType);
void SetFlag(RoomEnvFlags flag, bool value);
// Inquirers
bool IsTagPresent(const std::string& tag) const;
bool GetActive() const; // TODO: Rename to IsActive().
bool GetFlag(RoomEnvFlags flag) const; // TODO: Rename to HasFlag().
// Operators
Room& operator =(const Room& room) = delete;
};
//}

View file

@ -9,10 +9,12 @@ public:
static void Register(sol::table& parent); static void Register(sol::table& parent);
// Members // Members
float x = 0; float x = 0;
float y = 0; float y = 0;
// Constructors // Constructors
Vec2(float x, float y); Vec2(float x, float y);
Vec2(float value); Vec2(float value);
Vec2(const Vector2& vector); Vec2(const Vector2& vector);
@ -28,6 +30,7 @@ public:
float Length() const; float Length() const;
// Meta functions // Meta functions
std::string ToString() const; std::string ToString() const;
static Vec2 Add(const Vec2& vector0, const Vec2& vector1); static Vec2 Add(const Vec2& vector0, const Vec2& vector1);
static Vec2 Subtract(const Vec2& vector0, const Vec2& vector1); static Vec2 Subtract(const Vec2& vector0, const Vec2& vector1);
@ -38,9 +41,11 @@ public:
static bool IsEqualTo(const Vec2& vector0, const Vec2& vector1); static bool IsEqualTo(const Vec2& vector0, const Vec2& vector1);
// Converters // Converters
Vector2 ToVector2() const; Vector2 ToVector2() const;
//Vector2i ToVector2i() const; //Vector2i ToVector2i() const;
// Operators // Operators
operator Vector2() const; operator Vector2() const;
}; };

View file

@ -1,10 +1,10 @@
#pragma once #pragma once
namespace sol { class state; }
class GameVector; class GameVector;
class Pose; class Pose;
class Rotation; class Rotation;
class Vector3i; class Vector3i;
namespace sol { class state; }
class Vec3 class Vec3
{ {
@ -12,11 +12,13 @@ public:
static void Register(sol::table& parent); static void Register(sol::table& parent);
// Members // Members
float x = 0; float x = 0;
float y = 0; float y = 0;
float z = 0; float z = 0;
// Constructors // Constructors
Vec3() {}; Vec3() {};
Vec3(float x, float y, float z); Vec3(float x, float y, float z);
Vec3(float value); Vec3(float value);
@ -24,6 +26,7 @@ public:
Vec3(const Vector3i& vector); Vec3(const Vector3i& vector);
// Utilities // Utilities
Vec3 Normalize() const; Vec3 Normalize() const;
Vec3 Rotate(const Rotation& rot) const; Vec3 Rotate(const Rotation& rot) const;
Vec3 Lerp(const Vec3& vector, float alpha) const; Vec3 Lerp(const Vec3& vector, float alpha) const;
@ -33,6 +36,7 @@ public:
float Length() const; float Length() const;
// Meta functions // Meta functions
std::string ToString() const; std::string ToString() const;
static Vec3 Add(const Vec3& vector0, const Vec3& vector1); static Vec3 Add(const Vec3& vector0, const Vec3& vector1);
static Vec3 Subtract(const Vec3& vector0, const Vec3& vector1); static Vec3 Subtract(const Vec3& vector0, const Vec3& vector1);
@ -43,10 +47,12 @@ public:
static bool IsEqualTo(const Vec3& vector0, const Vec3& vector1); static bool IsEqualTo(const Vec3& vector0, const Vec3& vector1);
// Converters // Converters
Vector3 ToVector3() const; Vector3 ToVector3() const;
Vector3i ToVector3i() const; Vector3i ToVector3i() const;
GameVector ToGameVector() const; GameVector ToGameVector() const;
// Operators // Operators
operator Vector3() const; operator Vector3() const;
}; };

View file

@ -361,7 +361,7 @@ enum SOUND_EFFECTS
SFX_TR4_LIGHT_BEAM_LOOP = 356, SFX_TR4_LIGHT_BEAM_LOOP = 356,
SFX_TR4_GUIDE_FIRE_LIGHT = 357, SFX_TR4_GUIDE_FIRE_LIGHT = 357,
SFX_TR4_AUTOGUNS = 358, SFX_TR4_AUTOGUNS = 358,
SFX_TR4_EMPTY8 = 359, SFX_TR4_ENVIORONMENT_RUMBLE = 359,
SFX_TR4_STEAM = 360, SFX_TR4_STEAM = 360,
SFX_TR4_GARAGE_DOOR = 361, SFX_TR4_GARAGE_DOOR = 361,
SFX_TR4_WIND = 362, SFX_TR4_WIND = 362,

View file

@ -3,43 +3,42 @@
#include "Specific/clock.h" #include "Specific/clock.h"
namespace TEN::Input namespace TEN::Input
{ {
InputAction::InputAction(ActionID actionID) InputAction::InputAction(ActionID actionID)
{ {
ID = actionID; _id = actionID;
} }
ActionID InputAction::GetID() const ActionID InputAction::GetID() const
{ {
return ID; return _id;
} }
float InputAction::GetValue() const float InputAction::GetValue() const
{ {
return Value; return _value;
} }
float InputAction::GetTimeActive() const float InputAction::GetTimeActive() const
{ {
return TimeActive; return _timeActive;
} }
float InputAction::GetTimeInactive() const float InputAction::GetTimeInactive() const
{ {
return TimeInactive; return _timeInactive;
} }
bool InputAction::IsClicked() const bool InputAction::IsClicked() const
{ {
return ((Value != 0.0f) && (PrevValue == 0.0f)); return ((_value != 0.0f) && (_prevValue == 0.0f));
} }
bool InputAction::IsHeld(float delayInSec) const bool InputAction::IsHeld(float delayInSec) const
{ {
float delayInFrameTime = (delayInSec == 0.0f) ? 0.0f : round(delayInSec / DELTA_TIME); float delayInFrameTime = (delayInSec == 0.0f) ? 0.0f : round(delayInSec / DELTA_TIME);
return ((Value != 0.0f) && (TimeActive >= delayInFrameTime)); return ((_value != 0.0f) && (_timeActive >= delayInFrameTime));
} }
// NOTE: To avoid stutter on second pulse, ensure initialDelayInSec is multiple of delayInSec. // NOTE: To avoid stutter on second pulse, ensure initialDelayInSec is multiple of delayInSec.
@ -48,12 +47,12 @@ namespace TEN::Input
if (IsClicked()) if (IsClicked())
return true; return true;
if (!IsHeld() || PrevTimeActive == 0.0f || TimeActive == PrevTimeActive) if (!IsHeld() || _prevTimeActive == 0.0f || _timeActive == _prevTimeActive)
return false; return false;
float activeDelayInFrameTime = (TimeActive > round(initialDelayInSec / DELTA_TIME)) ? round(delayInSec / DELTA_TIME) : round(initialDelayInSec / DELTA_TIME); float activeDelayInFrameTime = (_timeActive > round(initialDelayInSec / DELTA_TIME)) ? round(delayInSec / DELTA_TIME) : round(initialDelayInSec / DELTA_TIME);
float delayInFrameTime = std::floor(TimeActive / activeDelayInFrameTime) * activeDelayInFrameTime; float delayInFrameTime = std::floor(_timeActive / activeDelayInFrameTime) * activeDelayInFrameTime;
if (delayInFrameTime > (std::floor(PrevTimeActive / activeDelayInFrameTime) * activeDelayInFrameTime)) if (delayInFrameTime > (std::floor(_prevTimeActive / activeDelayInFrameTime) * activeDelayInFrameTime))
return true; return true;
// Keeping version counting real time for future reference. -- Sezz 2022.10.01 // Keeping version counting real time for future reference. -- Sezz 2022.10.01
@ -70,7 +69,7 @@ namespace TEN::Input
bool InputAction::IsReleased(float maxDelayInSec) const bool InputAction::IsReleased(float maxDelayInSec) const
{ {
float maxDelayInFrameTime = (maxDelayInSec == INFINITY) ? INFINITY : round(maxDelayInSec / DELTA_TIME); float maxDelayInFrameTime = (maxDelayInSec == INFINITY) ? INFINITY : round(maxDelayInSec / DELTA_TIME);
return ((Value == 0.0f) && (PrevValue != 0.0f) && (TimeActive <= maxDelayInFrameTime)); return ((_value == 0.0f) && (_prevValue != 0.0f) && (_timeActive <= maxDelayInFrameTime));
} }
void InputAction::Update(bool value) void InputAction::Update(bool value)
@ -89,57 +88,57 @@ namespace TEN::Input
if (IsClicked()) if (IsClicked())
{ {
PrevTimeActive = 0.0f; _prevTimeActive = 0.0f;
TimeActive = 0.0f; _timeActive = 0.0f;
TimeInactive += FRAME_TIME;// DELTA_TIME; _timeInactive += FRAME_TIME;// DELTA_TIME;
} }
else if (IsReleased()) else if (IsReleased())
{ {
PrevTimeActive = TimeActive; _prevTimeActive = _timeActive;
TimeActive += FRAME_TIME;// DELTA_TIME; _timeActive += FRAME_TIME;// DELTA_TIME;
TimeInactive = 0.0f; _timeInactive = 0.0f;
} }
else if (IsHeld()) else if (IsHeld())
{ {
PrevTimeActive = TimeActive; _prevTimeActive = _timeActive;
TimeActive += FRAME_TIME;// DELTA_TIME; _timeActive += FRAME_TIME;// DELTA_TIME;
TimeInactive = 0.0f; _timeInactive = 0.0f;
} }
else else
{ {
PrevTimeActive = 0.0f; _prevTimeActive = 0.0f;
TimeActive = 0.0f; _timeActive = 0.0f;
TimeInactive += FRAME_TIME;// DELTA_TIME; _timeInactive += FRAME_TIME;// DELTA_TIME;
} }
} }
void InputAction::Clear() void InputAction::Clear()
{ {
Value = 0.0f; _value = 0.0f;
PrevValue = 0.0f; _prevValue = 0.0f;
TimeActive = 0.0f; _timeActive = 0.0f;
PrevTimeActive = 0.0f; _prevTimeActive = 0.0f;
TimeInactive = 0.0f; _timeInactive = 0.0f;
} }
void InputAction::DrawDebug() const void InputAction::DrawDebug() const
{ {
PrintDebugMessage("ID: %d", (int)ID); PrintDebugMessage("ID: %d", (int)_id);
PrintDebugMessage("IsClicked: %d", IsClicked()); PrintDebugMessage("IsClicked: %d", IsClicked());
PrintDebugMessage("IsHeld: %d", IsHeld()); PrintDebugMessage("IsHeld: %d", IsHeld());
PrintDebugMessage("IsPulsed (.2s, .6s): %d", IsPulsed(0.2f, 0.6f)); PrintDebugMessage("IsPulsed (.2s, .6s): %d", IsPulsed(0.2f, 0.6f));
PrintDebugMessage("IsReleased: %d", IsReleased()); PrintDebugMessage("IsReleased: %d", IsReleased());
PrintDebugMessage(""); PrintDebugMessage("");
PrintDebugMessage("Value: %.3f", Value); PrintDebugMessage("Value: %.3f", _value);
PrintDebugMessage("PrevValue: %.3f", PrevValue); PrintDebugMessage("PrevValue: %.3f", _prevValue);
PrintDebugMessage("TimeActive: %.3f", TimeActive); PrintDebugMessage("TimeActive: %.3f", _timeActive);
PrintDebugMessage("PrevTimeActive: %.3f", PrevTimeActive); PrintDebugMessage("PrevTimeActive: %.3f", _prevTimeActive);
PrintDebugMessage("TimeInactive: %.3f", TimeInactive); PrintDebugMessage("TimeInactive: %.3f", _timeInactive);
} }
void InputAction::UpdateValue(float value) void InputAction::UpdateValue(float value)
{ {
PrevValue = Value; _prevValue = _value;
Value = value; _value = value;
} }
} }

View file

@ -65,12 +65,12 @@ namespace TEN::Input
private: private:
// Members // Members
ActionID ID = In::Forward; ActionID _id = In::Forward;
float Value = 0.0f; float _value = 0.0f;
float PrevValue = 0.0f; float _prevValue = 0.0f;
float TimeActive = 0.0f; float _timeActive = 0.0f;
float PrevTimeActive = 0.0f; float _prevTimeActive = 0.0f;
float TimeInactive = 0.0f; float _timeInactive = 0.0f;
public: public:
// Constructors // Constructors

View file

@ -1471,7 +1471,8 @@ void GetCarriedItems()
const auto& object = Objects[item.ObjectNumber]; const auto& object = Objects[item.ObjectNumber];
if (object.intelligent || if (object.intelligent ||
(item.ObjectNumber >= ID_SEARCH_OBJECT1 && item.ObjectNumber <= ID_SEARCH_OBJECT3)) (item.ObjectNumber >= ID_SEARCH_OBJECT1 && item.ObjectNumber <= ID_SEARCH_OBJECT3) ||
(item.ObjectNumber == ID_SARCOPHAGUS))
{ {
for (short linkNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem) for (short linkNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkNumber != NO_VALUE; linkNumber = g_Level.Items[linkNumber].NextItem)
{ {