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

@ -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,11 +6,15 @@ 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);
@ -24,6 +28,5 @@ namespace TEN::Entities::Vehicles
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,110 +13,86 @@
#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
@pragma nostrip
*/
//namespace TEN::Scripting
//{
static auto IndexError = index_error_maker(Room, ScriptReserved_Volume); static auto IndexError = index_error_maker(Room, ScriptReserved_Volume);
static auto NewIndexError = newindex_error_maker(Room, ScriptReserved_Volume); static auto NewIndexError = newindex_error_maker(Room, ScriptReserved_Volume);
Room::Room(ROOM_INFO& room) : m_room{ room } Room::Room(ROOM_INFO& room) :
{}; _room(room)
{
};
void Room::Register(sol::table& parent) void Room::Register(sol::table& parent)
{ {
parent.new_usertype<Room>(ScriptReserved_Room, // Register type.
parent.new_usertype<Room>(
ScriptReserved_Room,
sol::no_constructor, sol::no_constructor,
sol::meta_function::index, IndexError, sol::meta_function::index, IndexError,
sol::meta_function::new_index, NewIndexError, sol::meta_function::new_index, NewIndexError,
/// Determine whether the room is active or not ScriptReserved_RoomGetRoomNumber, &Room::GetRoomNumber,
// @function Room:GetActive ScriptReserved_RoomGetName, &Room::GetName,
// @treturn bool true if the room is active ScriptReserved_RoomGetColor, &Room::GetColor,
ScriptReserved_GetActive, &Room::GetActive, 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);
}
/// Get the room's ambient light color. /// Get the room's number.
// @function Room:GetColor // @function Room:GetRoomNumber()
// @treturn Color ambient light color of the room // @treturn int Room number.
ScriptReserved_GetColor, & Room::GetColor, int Room::GetRoomNumber() const
{
/// Get the room's reverb type. return _room.RoomNumber;
// @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. /// Get the room's unique string identifier.
// @function Room:GetName // @function Room:GetName()
// @treturn string the room's name // @treturn string Room 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 std::string Room::GetName() const
{ {
return m_room.Name; return _room.Name;
} }
/// Get the room's ambient light color.
// @function Room:GetColor()
// @treturn Color Ambient light color.
ScriptColor Room::GetColor() const
{
return ScriptColor(_room.ambient);
}
/// Get the room's reverb type.
// @function Room:GetReverbType()
// @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) void Room::SetName(const std::string& name)
{ {
if (!ScriptAssert(!name.empty(), "Unable to set name. Name cannot be blank.")) if (!ScriptAssert(!name.empty(), "Unable to set name. Name cannot be blank."))
return; return;
// Remove old name if it already exists. // Remove previous name if it already exists.
if (s_callbackSetName(name, m_room)) if (s_callbackSetName(name, _room))
{ {
s_callbackRemoveName(m_room.Name); s_callbackRemoveName(_room.Name);
m_room.Name = name; _room.Name = name;
} }
else else
{ {
@ -125,29 +101,60 @@ void Room::SetName(const std::string& name)
} }
} }
bool Room::GetFlag(RoomEnvFlags flag) const /// Set the room's reverb type.
// @function Room:SetReverbType()
// @tparam Objects.RoomReverb Reverb type.
void Room::SetReverbType(ReverbType reverb)
{ {
return ((m_room.flags & flag) == flag); _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) void Room::SetFlag(RoomEnvFlags flag, bool value)
{ {
if (value) if (value)
{ {
m_room.flags |= flag; _room.flags |= flag;
} }
else else
{ {
m_room.flags &= ~flag; _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 bool Room::IsTagPresent(const std::string& tag) const
{ {
if (m_room.Tags.empty()) if (_room.Tags.empty())
return false; return false;
return std::any_of( return std::any_of(
m_room.Tags.begin(), m_room.Tags.end(), _room.Tags.begin(), _room.Tags.end(),
[&tag](const std::string& value) { return (value == tag); }); [&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;
//namespace TEN::Scripting
//{
class Room : public NamedBase<Room, ROOM_INFO&> class Room : public NamedBase<Room, ROOM_INFO&>
{ {
private:
// Members
ROOM_INFO& _room;
public: public:
using IdentifierType = std::reference_wrapper<ROOM_INFO>; using IdentifierType = std::reference_wrapper<ROOM_INFO>;
Room(ROOM_INFO& room);
~Room() = default;
Room& operator =(const Room& other) = delete;
Room(const Room& other) = delete;
static void Register(sol::table& parent); static void Register(sol::table& parent);
[[nodiscard]] bool GetActive() const; // Constructors
[[nodiscard]] ScriptColor GetColor() const;
Room(ROOM_INFO& room);
Room(const Room& room) = delete;
// Destructors
~Room() = default;
// Getters
int GetRoomNumber() const;
std::string GetName() const;
ScriptColor GetColor() const;
ReverbType GetReverbType() const;
// Setters
[[nodiscard]] std::string GetName() const;
void SetName(const std::string& name); void SetName(const std::string& name);
void SetReverbType(ReverbType reverbType);
[[nodiscard]] bool GetFlag(RoomEnvFlags flag) const;
void SetFlag(RoomEnvFlags flag, bool value); void SetFlag(RoomEnvFlags flag, bool value);
[[nodiscard]] ReverbType GetReverbType() const; // Inquirers
void SetReverbType(ReverbType reverbType);
[[nodiscard]] bool IsTagPresent(const std::string& tag) const; bool IsTagPresent(const std::string& tag) const;
bool GetActive() const; // TODO: Rename to IsActive().
bool GetFlag(RoomEnvFlags flag) const; // TODO: Rename to HasFlag().
private: // Operators
ROOM_INFO& m_room;
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)
{ {