From 64a2d60d2f9a9cbed525d9e30881f90bae361e3d Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 00:29:33 +0100 Subject: [PATCH 01/53] Added safeguards for problems surfaced in #1618 --- TombEngine/Game/animation.cpp | 4 ++++ TombEngine/Renderer/RendererDraw.cpp | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp index 53d0a6d46..04eb59905 100644 --- a/TombEngine/Game/animation.cpp +++ b/TombEngine/Game/animation.cpp @@ -711,6 +711,10 @@ Vector3i GetJointPosition(const ItemInfo& item, const CreatureBiteInfo& bite) Vector3 GetJointOffset(GAME_OBJECT_ID objectID, int jointIndex) { const auto& object = Objects[objectID]; + int boneIndex = object.boneIndex + (jointIndex * 4); + + if (g_Level.Bones.size() <= boneIndex) + return Vector3::Zero; int* bonePtr = &g_Level.Bones[object.boneIndex + (jointIndex * 4)]; return Vector3(*(bonePtr + 1), *(bonePtr + 2), *(bonePtr + 3)); diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 98e29e66f..a79e06298 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -2571,6 +2571,12 @@ namespace TEN::Renderer if (!SetupBlendModeAndAlphaTest(bucket.BlendMode, rendererPass, p)) continue; + if (_staticTextures.size() <= bucket.Texture) + { + TENLog("Attempted to set incorrect static mesh texture atlas", LogLevel::Warning); + continue; + } + BindTexture(TextureRegister::ColorMap, &std::get<0>(_staticTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp); From c608e6dec5d76ee2453486b6405173cf14079e77 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 00:30:52 +0100 Subject: [PATCH 02/53] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index edf146d46..78bf16d1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ### Bug fixes * Fixed particles remaining in the level after reloading from the savegame. * Fixed particles being canceled by fog bulbs. +* Fixed crash in case hair object is the last object in a level. +* Fixed crash with incorrectly applied animated textures on static meshes. ### Lua API changes * Added missing constructor for `Collision.Probe` without room number. From 8c26702678cd4c167a26c87ef5e89cce9aa76365 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 08:31:05 +0100 Subject: [PATCH 03/53] Always warn about different game version --- TombEngine/Specific/level.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 3addd27f9..4935ecb0a 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -1317,7 +1317,7 @@ bool LoadLevel(const std::string& path, bool partial) auto assemblyVersion = TEN::Utils::GetProductOrFileVersion(true); for (int i = 0; i < assemblyVersion.size(); i++) { - if (assemblyVersion[i] < version[i]) + if (assemblyVersion[i] != version[i]) { TENLog("Level version is different from TEN version.", LogLevel::Warning); break; From b1ee6a190eb1a4fdf5af76406a2bb18492b5986e Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 09:42:01 +0100 Subject: [PATCH 04/53] Added ability to perform Lua commands in the console window in realtime --- CHANGELOG.md | 37 +++++++++++++++++--------------- TombEngine/Specific/winmain.cpp | 38 +++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78bf16d1c..30710e1f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.8.1](link to release) - yyyy-mm-dd +### New features +* Added ability to perform Lua commands in the console window in realtime. + ### Bug fixes * Fixed particles remaining in the level after reloading from the savegame. * Fixed particles being canceled by fog bulbs. @@ -35,7 +38,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed custom shatter sounds with custom sound IDs not playing correctly. * Fixed crashes with sound samples larger than 2 megabytes. -### New Features +### New features * Added multithreading and an option for it to flow system settings. * Added ability to use floor trapdoors, keys and puzzle items underwater. - You must update your Lara object: https://github.com/TombEngine/Resources/raw/main/Wad2%20Objects/Lara/TEN_Lara.wad2 @@ -84,7 +87,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed gravity being applied underwater when exiting the fly cheat. * Fixed gravity being applied when vaulting on the same frame as the player lands. -### New Features +### New features * Added realtime shader reloading in debug mode by pressing F9 key. * Added load, save, stopwatch and compass as a functional pick-up items with ability to add or remove them from inventory. * Increased particle limit from 1024 to 4096. @@ -134,7 +137,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed spotlight shadows. * Fixed Skeleton and Mummy not reacting to shotgun hits. -### New Features +### New features * Added classic mirror effect with ability to reflect moveables and static meshes. * Added ability to customize many hardcoded parameters, such as flare, weapon, and hair settings. * Added dynamic shadow casting on objects and static meshes. @@ -210,7 +213,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed display sprites and display strings rendering in the inventory background. * Fixed young Lara hair drawing. https://tombengine.com/docs/level-settings/#young_lara -### New Features +### New features * Added high framerate mode (also known as 60 FPS mode). * Added a customisable global lensflare effect. https://tombengine.com/docs/level-settings/#lensflare * Added a customisable starry sky and meteor effect. https://tombengine.com/docs/level-settings/#stars @@ -270,7 +273,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed bottom collision for solid static meshes. * Fixed T-Rex's head rotation. -### New Features +### New features * Auto-switch to a crawl state if player start position is in a crawlspace. * Allow directional flame emitter (negative OCBs) to be rotated at any angle. * Revise wall spikes: @@ -317,7 +320,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed incorrect light collection in some cases. * Fixed normal mapping for rooms, items, and statics.' -### New Features +### New features * Added ambient occlusion (SSAO). * Added new post-process workflow (monochrome, negative, exclusion) with tinting. * Added SMAA antialiasing instead of MSAA. @@ -376,7 +379,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fix camera snap when disengaging the look-around mode. * Fix TR4 mapper not being visible. -### New Features +### New features * Improve head-on wall collision. * Overhaul pushables: - Separate climbable and non-climbable pushable object slots. @@ -459,7 +462,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fix incorrect culling for scaled static meshes. * Fix normal mapping. -### New Features +### New features * Add ability to save screenshot in the "Screenshots" subfolder by pressing the "Print screen" key. * Implement separate audio track channel for playing voiceovers with subtitles in .srt format. * Don't stop ambience when Lara dies. @@ -507,7 +510,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fix rendering for static meshes with custom blending modes and alpha transparency. * Fix inconsistent multiline string spacing on different display modes. -### New Features +### New features * Remove search object 4 hardcoded meshswap activated with a flipmap. * Add TR1 cowboy. * Add TR3 wall mounted blade. @@ -565,7 +568,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): - Please note you must use the patched version found here: https://github.com/TombEngine/Resources/blob/main/Wad2%20Objects/tr5_Imp.wad2 * Fix and improve wraith tails. -### New Features/Amedments +### New features/Amedments * Add dedicated WRAITH_TRAP object with enhanced effects. - OCB 0: Effect disabled. - OCB 1: Effect enabled. @@ -614,7 +617,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fix TR3 big gun spawning rocket with 0 life which caused an immediate explosion. * Fix TR3 Tony and add boss effect for him. -### New Features +### New features * Add TR3 civvy. * Add TR3 electric cleaner. * Add TR3 Sophia Leigh with following OCBs: @@ -666,7 +669,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fix grenade and rocket launcher lighting. * Fix ceiling trapdoor and floor trapdoor that Lara couldn't open manually. -### New Features +### New features * Make enemies drop pickups at first available bounding box corner point, not centerpoint. * Restore original volumetric explosion effects. * Add TR3 lizard and Puna. @@ -718,7 +721,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fix bone rotations of some entities. * Fix Lara's animation for cog switch release. -### New Features +### New features * Added new OCB to cog switch object: - Use OCB 0 to have the traditional behaviour. - Use any other OCB to can use the Cog Switch without need of any door linked. @@ -732,7 +735,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.0.4](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.2) - 2022-12-16 -### New Features +### New features * Add generic assignable effects for moveables - fire, sparks, smoke and laser / electric ignite. * Add ability to burn enemies with FLAME_EMITTER_1 and death blocks. * Add wireframe mode and other visual debug information (switch by F10/F11 debug page scroll hotkeys). @@ -804,7 +807,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.0.3](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6.1) - 2022-11-18 -### New Features +### New features * Add ledge jumps (Lara object must be updated with new animations to make it work). * Allow any object slot to be used as a meshswap. * Add OCB 1 for rollingball to make it silent. @@ -872,7 +875,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.0.2](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.6) - 2022-09-16 -### New Features +### New features * Fix removing Pistols with TakeItem and SetItemCount. * Allow saving and loading of Vec3s in LevelVars and GameVars. * Support volume triggers made with node editor. @@ -927,7 +930,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.0.1](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.5.2) - 2022-08-16 -### New Features +### New features * Added antialiasing support. * Added static mesh scaling support. * Added free rotation for teeth spikes instead of using OCB codes. diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index bd7b2cefa..d120636c4 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -30,8 +30,8 @@ using std::cout; using std::endl; WINAPP App; -unsigned int ThreadID; -uintptr_t ThreadHandle; +unsigned int ThreadID, ConsoleThreadID; +uintptr_t ThreadHandle, ConsoleThreadHandle; HACCEL hAccTable; bool DebugMode = false; HWND WindowsHandle; @@ -242,6 +242,37 @@ bool GenerateDummyLevel(const std::string& levelPath) return true; } +unsigned CALLBACK ConsoleInput(void*) +{ + std::string input; + + while (!ThreadEnded) + { + if (!std::getline(std::cin, input)) + break; + + if (g_GameScript == nullptr) + { + TENLog("Scripting engine not initialized.", LogLevel::Error); + continue; + } + else + { + try + { + g_GameScript->ExecuteString(input); + } + catch (const exception& ex) + { + std::string error = ex.what(); + TENLog("Error executing " + input + ": " + error.substr(error.find(":1: ") + 4), LogLevel::Error); + } + } + } + + return true; +} + void WinProcMsg() { MSG msg; @@ -406,7 +437,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine #ifndef _DEBUG if (!DebugMode) ShowWindow(GetConsoleWindow(), 0); + else #endif + ConsoleThreadHandle = BeginThread(ConsoleInput, ConsoleThreadID); // Clear application structure. memset(&App, 0, sizeof(WINAPP)); @@ -615,6 +648,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine void WinClose() { + CloseHandle((HANDLE)ConsoleThreadHandle); WaitForSingleObject((HANDLE)ThreadHandle, 5000); DestroyAcceleratorTable(hAccTable); From 075c438b5d4c76e30c623941a61bbc55ca27114a Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 09:49:03 +0100 Subject: [PATCH 05/53] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 30710e1f3..622cb7839 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.8.1](link to release) - yyyy-mm-dd ### New features -* Added ability to perform Lua commands in the console window in realtime. +* Added live console input to perform Lua commands in realtime. ### Bug fixes * Fixed particles remaining in the level after reloading from the savegame. From d47e8d0e6989d5461be7f281005f33989b3818a1 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 09:57:25 +0100 Subject: [PATCH 06/53] Don't try to execute empty lines --- TombEngine/Specific/winmain.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index d120636c4..5a68753bc 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -251,6 +251,9 @@ unsigned CALLBACK ConsoleInput(void*) if (!std::getline(std::cin, input)) break; + if (std::regex_match(input, std::regex("^\\s*$"))) + continue; + if (g_GameScript == nullptr) { TENLog("Scripting engine not initialized.", LogLevel::Error); From f0f733519fbdc465804cc09abe32371e939908c2 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 10:01:51 +0100 Subject: [PATCH 07/53] Simplify error message --- TombEngine/Specific/winmain.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 5a68753bc..01d13bf8c 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -267,8 +267,7 @@ unsigned CALLBACK ConsoleInput(void*) } catch (const exception& ex) { - std::string error = ex.what(); - TENLog("Error executing " + input + ": " + error.substr(error.find(":1: ") + 4), LogLevel::Error); + TENLog("Error executing " + input + ": " + ex.what(), LogLevel::Error); } } } From e27ec86e853ad0f24c524e8fc8a5139e8f86f908 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 10:28:12 +0100 Subject: [PATCH 08/53] Allow to run console input in freeze modes as well --- .../Scripting/Include/ScriptInterfaceGame.h | 1 + .../Internal/TEN/Logic/LogicHandler.cpp | 26 +++++++++++++++++++ .../Internal/TEN/Logic/LogicHandler.h | 5 +++- TombEngine/Specific/winmain.cpp | 13 +--------- 4 files changed, 32 insertions(+), 13 deletions(-) diff --git a/TombEngine/Scripting/Include/ScriptInterfaceGame.h b/TombEngine/Scripting/Include/ScriptInterfaceGame.h index 73b0be0ee..121cbe2f2 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceGame.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceGame.h @@ -62,6 +62,7 @@ public: virtual void OnUseItem(GAME_OBJECT_ID objectNumber) = 0; virtual void OnFreeze() = 0; + virtual void AddConsoleInput(const std::string& input) = 0; virtual void ShortenTENCalls() = 0; virtual void FreeLevelScripts() = 0; virtual void ResetScripts(bool clearGameVars) = 0; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index e85c98ce5..e1cf4ed6b 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -620,6 +620,28 @@ int Handle(TypeFrom& var, MapType& varsMap, size_t& numVars, std::vectorsecond; } +void LogicHandler::AddConsoleInput(const std::string& input) +{ + _consoleInput = input; +} + +void LogicHandler::PerformConsoleInput() +{ + if (!_consoleInput.empty()) + { + try + { + ExecuteString(_consoleInput); + } + catch (const std::exception& ex) + { + TENLog("Error executing " + _consoleInput + ": " + ex.what(), LogLevel::Error); + } + + _consoleInput.clear(); + } +} + std::string LogicHandler::GetRequestedPath() const { auto path = std::string(); @@ -1027,6 +1049,8 @@ void LogicHandler::OnLoop(float deltaTime, bool postLoop) for (const auto& name : _callbacksPreLoop) CallLevelFuncByName(name, deltaTime); + PerformConsoleInput(); + lua_gc(_handler.GetState()->lua_state(), LUA_GCCOLLECT, 0); if (_onLoop.valid()) CallLevelFunc(_onLoop, deltaTime); @@ -1099,6 +1123,8 @@ void LogicHandler::OnFreeze() for (const auto& name : _callbacksPreFreeze) CallLevelFuncByName(name); + PerformConsoleInput(); + if (_onFreeze.valid()) CallLevelFunc(_onFreeze); diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index f4f7ff481..8ff7be4e2 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -75,11 +75,13 @@ private: sol::protected_function _onFreeze = {}; std::unordered_map*> _callbacks; - std::vector> _savedVarPath; bool _shortenedCalls = false; + std::string _consoleInput = ""; + void PerformConsoleInput(); + std::string GetRequestedPath() const; void ResetLevelTables(); @@ -132,6 +134,7 @@ public: void HandleEvent(const std::string& name, EventType type, sol::optional activator); void EnableEvent(const std::string& name, EventType type); void DisableEvent(const std::string& name, EventType type); + void AddConsoleInput(const std::string& input); void ResetScripts(bool clearGameVars) override; void ShortenTENCalls() override; diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 01d13bf8c..f4cf4d9da 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -24,10 +24,6 @@ using namespace TEN::Renderer; using namespace TEN::Input; using namespace TEN::Utils; -using std::exception; -using std::string; -using std::cout; -using std::endl; WINAPP App; unsigned int ThreadID, ConsoleThreadID; @@ -261,14 +257,7 @@ unsigned CALLBACK ConsoleInput(void*) } else { - try - { - g_GameScript->ExecuteString(input); - } - catch (const exception& ex) - { - TENLog("Error executing " + input + ": " + ex.what(), LogLevel::Error); - } + g_GameScript->AddConsoleInput(input); } } From 8427ae770621d2cd3f195378d31a4190472b7948 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 10:37:36 +0100 Subject: [PATCH 09/53] Update winmain.cpp --- TombEngine/Specific/winmain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index f4cf4d9da..3efdd8b20 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -639,7 +639,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine void WinClose() { - CloseHandle((HANDLE)ConsoleThreadHandle); + if (ConsoleThreadHandle) + CloseHandle((HANDLE)ConsoleThreadHandle); + WaitForSingleObject((HANDLE)ThreadHandle, 5000); DestroyAcceleratorTable(hAccTable); From 382b9d1ef59425fb9c43272b400f11dab9b47031 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 22 Mar 2025 10:56:17 +0100 Subject: [PATCH 10/53] Fixed incorrect debug line --- TombEngine/Renderer/RendererDrawMenu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Renderer/RendererDrawMenu.cpp b/TombEngine/Renderer/RendererDrawMenu.cpp index 87de33b5c..e38f1e440 100644 --- a/TombEngine/Renderer/RendererDrawMenu.cpp +++ b/TombEngine/Renderer/RendererDrawMenu.cpp @@ -1331,7 +1331,7 @@ namespace TEN::Renderer PrintDebugMessage("RoomNumber: %d", LaraItem->RoomNumber); PrintDebugMessage("PathfindingBoxID: %d", LaraItem->BoxNumber); PrintDebugMessage((Lara.Context.WaterSurfaceDist == -NO_HEIGHT ? "WaterSurfaceDist: N/A" : "WaterSurfaceDist: %d"), Lara.Context.WaterSurfaceDist); - PrintDebugMessage("Room Position: %d, %d, %d, %d", room.Position.z, room.Position.z, room.Position.z + BLOCK(room.XSize), room.Position.z + BLOCK(room.ZSize)); + PrintDebugMessage("Room Bounds: (%d, %d), (%d, %d)", room.Position.x, room.Position.z, room.Position.x + BLOCK(room.XSize), room.Position.z + BLOCK(room.ZSize)); PrintDebugMessage("Room.y, minFloor, maxCeiling: %d, %d, %d ", room.Position.y, room.BottomHeight, room.TopHeight); PrintDebugMessage("Camera Position: %d, %d, %d", Camera.pos.x, Camera.pos.y, Camera.pos.z); PrintDebugMessage("Camera LookAt: %d, %d, %d", Camera.target.x, Camera.target.y, Camera.target.z); From ac77c5f9ad007944fa89c1bda5b716cac4325088 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 23 Mar 2025 08:24:36 +0100 Subject: [PATCH 11/53] Rollback MovingLaserFlags rename, bump version number --- TombEngine/Objects/TR5/Trap/MovingLaser.cpp | 34 ++++++++++----------- TombEngine/version.h | 4 +-- 2 files changed, 19 insertions(+), 19 deletions(-) diff --git a/TombEngine/Objects/TR5/Trap/MovingLaser.cpp b/TombEngine/Objects/TR5/Trap/MovingLaser.cpp index bb07f8c19..830d14746 100644 --- a/TombEngine/Objects/TR5/Trap/MovingLaser.cpp +++ b/TombEngine/Objects/TR5/Trap/MovingLaser.cpp @@ -23,7 +23,7 @@ namespace TEN::Entities::Traps constexpr auto MOVING_LASER_ACCEL = 1.0f; constexpr auto MOVING_LASER_PAUSE_FRAME_COUNT = 30; - enum class MovingLaserProperty + enum class MovingLaserFlags { Velocity, PauseTimer, @@ -35,8 +35,8 @@ namespace TEN::Entities::Traps void InitializeMovingLaser(short itemNumber) { auto& item = g_Level.Items[itemNumber]; - item.ItemFlags[(int)MovingLaserProperty::DirectionSign] = 1; - item.ItemFlags[(int)MovingLaserProperty::Velocity] = 10; + item.ItemFlags[(int)MovingLaserFlags::DirectionSign] = 1; + item.ItemFlags[(int)MovingLaserFlags::Velocity] = 10; // Offset by 1/4 block to make it dangerous at sector edges. item.Pose.Translate(item.Pose.Orientation, -BLOCK(0.25f)); @@ -51,7 +51,7 @@ namespace TEN::Entities::Traps // Calculate distances. float moveDist = BLOCK(item.TriggerFlags) + BLOCK(0.5f); - float distPerFrame = (BLOCK(item.ItemFlags[(int)MovingLaserProperty::Velocity]) * 0.25f) / (float)FPS; + float distPerFrame = (BLOCK(item.ItemFlags[(int)MovingLaserFlags::Velocity]) * 0.25f) / (float)FPS; item.Animation.ActiveState = 0; @@ -74,38 +74,38 @@ namespace TEN::Entities::Traps return; } - if (item.ItemFlags[(int)MovingLaserProperty::PauseTimer] > 0) + if (item.ItemFlags[(int)MovingLaserFlags::PauseTimer] > 0) { - item.ItemFlags[(int)MovingLaserProperty::PauseTimer]--; - if (item.ItemFlags[(int)MovingLaserProperty::PauseTimer] == 0) + item.ItemFlags[(int)MovingLaserFlags::PauseTimer]--; + if (item.ItemFlags[(int)MovingLaserFlags::PauseTimer] == 0) { - item.ItemFlags[(int)MovingLaserProperty::DirectionSign] *= -1; - item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] = 0; + item.ItemFlags[(int)MovingLaserFlags::DirectionSign] *= -1; + item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] = 0; } AnimateItem(&item); return; } - item.Pose.Translate(item.Pose.Orientation, (item.ItemFlags[(int)MovingLaserProperty::DirectionSign] * item.ItemFlags[(int)MovingLaserProperty::VelocityCalc])); + item.Pose.Translate(item.Pose.Orientation, (item.ItemFlags[(int)MovingLaserFlags::DirectionSign] * item.ItemFlags[(int)MovingLaserFlags::VelocityCalc])); - item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] += item.ItemFlags[(int)MovingLaserProperty::VelocityCalc]; + item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] += item.ItemFlags[(int)MovingLaserFlags::VelocityCalc]; - if (item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] < (moveDist - BLOCK(0.5f))) + if (item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] < (moveDist - BLOCK(0.5f))) { - item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] = std::min(distPerFrame, item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] + MOVING_LASER_ACCEL); + item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] = std::min(distPerFrame, item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] + MOVING_LASER_ACCEL); } else { - item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] = std::max(MOVING_LASER_VELOCITY_MIN, item.ItemFlags[(int)MovingLaserProperty::VelocityCalc] - MOVING_LASER_ACCEL); + item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] = std::max(MOVING_LASER_VELOCITY_MIN, item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] - MOVING_LASER_ACCEL); } - if (item.ItemFlags[(int)MovingLaserProperty::DistanceTraveled] >= moveDist) + if (item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] >= moveDist) { - item.ItemFlags[(int)MovingLaserProperty::PauseTimer] = MOVING_LASER_PAUSE_FRAME_COUNT; + item.ItemFlags[(int)MovingLaserFlags::PauseTimer] = MOVING_LASER_PAUSE_FRAME_COUNT; } - if (item.ItemFlags[(int)MovingLaserProperty::PauseTimer] == 0) + if (item.ItemFlags[(int)MovingLaserFlags::PauseTimer] == 0) { SoundEffect(SFX_TR5_MOVING_LASER_LOOP, &item.Pose, SoundEnvironment::Always); } diff --git a/TombEngine/version.h b/TombEngine/version.h index 464c2b659..654ddf744 100644 --- a/TombEngine/version.h +++ b/TombEngine/version.h @@ -2,12 +2,12 @@ #define TE_MAJOR_VERSION 1 #define TE_MINOR_VERSION 8 -#define TE_BUILD_NUMBER 0 +#define TE_BUILD_NUMBER 1 #define TE_REVISION_NUMBER 0 #define TEN_MAJOR_VERSION 1 #define TEN_MINOR_VERSION 8 -#define TEN_BUILD_NUMBER 0 +#define TEN_BUILD_NUMBER 1 #define TEN_REVISION_NUMBER 0 #define TEST_BUILD 1 From 78e8d34c005f80497840cb6bc0e6dab16963ac00 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 24 Mar 2025 22:03:52 +0100 Subject: [PATCH 12/53] Fixed console on Win11 and monkey pathfinding --- CHANGELOG.md | 2 ++ TombEngine/Game/control/box.cpp | 10 +++++++--- TombEngine/Specific/winmain.cpp | 2 +- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 622cb7839..9dab845db 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,10 +9,12 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Added live console input to perform Lua commands in realtime. ### Bug fixes +* Fixed pathfinding for friendly NPCs, such as monkeys. * Fixed particles remaining in the level after reloading from the savegame. * Fixed particles being canceled by fog bulbs. * Fixed crash in case hair object is the last object in a level. * Fixed crash with incorrectly applied animated textures on static meshes. +* Fixed console window not hiding in non-debug mode on Windows 11. ### Lua API changes * Added missing constructor for `Collision.Probe` without room number. diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index b60256557..763dfec8b 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -1150,6 +1150,7 @@ bool StalkBox(ItemInfo* item, ItemInfo* enemy, int boxNumber) { if (enemy == nullptr || boxNumber == NO_VALUE) return false; + auto* box = &g_Level.PathfindingBoxes[boxNumber]; int xRange = STALK_DIST + ((box->bottom - box->top) * BLOCK(1)); @@ -1635,8 +1636,11 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent) auto* LOT = &creature->LOT; auto* enemy = creature->Enemy; - if (enemy == nullptr) - return; + + // HACK: Fallback to bored mood from attack mood if enemy was cleared. + // Replaces previous "fix" with early exit, because it was breaking friendly NPC pathfinding. -- Lwmte, 24.03.25 + if (enemy == nullptr && creature->Mood == MoodType::Attack) + creature->Mood = MoodType::Bored; int boxNumber; switch (creature->Mood) @@ -1645,7 +1649,7 @@ void CreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent) boxNumber = LOT->Node[GetRandomControl() * LOT->ZoneCount >> 15].boxNumber; if (ValidBox(item, AI->zoneNumber, boxNumber)) { - if (StalkBox(item, enemy, boxNumber) && enemy->HitPoints > 0 && creature->Enemy) + if (StalkBox(item, enemy, boxNumber) && creature->Enemy && enemy->HitPoints > 0) { TargetBox(LOT, boxNumber); creature->Mood = MoodType::Bored; diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 3efdd8b20..6384e29b4 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -427,7 +427,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // Hide console window if mode isn't debug. #ifndef _DEBUG if (!DebugMode) - ShowWindow(GetConsoleWindow(), 0); + FreeConsole(); else #endif ConsoleThreadHandle = BeginThread(ConsoleInput, ConsoleThreadID); From c2c6b5f0726eebbb0e745691e5651ece67b18dd5 Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 25 Mar 2025 15:05:07 +1100 Subject: [PATCH 13/53] Minor changes --- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h | 3 ++- TombEngine/Specific/winmain.cpp | 7 +++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 8ff7be4e2..cbc659d14 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -79,7 +79,8 @@ private: bool _shortenedCalls = false; - std::string _consoleInput = ""; + std::string _consoleInput = {}; + void PerformConsoleInput(); std::string GetRequestedPath() const; diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 6384e29b4..560073115 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -240,8 +240,7 @@ bool GenerateDummyLevel(const std::string& levelPath) unsigned CALLBACK ConsoleInput(void*) { - std::string input; - + auto input = std::string(); while (!ThreadEnded) { if (!std::getline(std::cin, input)) @@ -427,10 +426,14 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // Hide console window if mode isn't debug. #ifndef _DEBUG if (!DebugMode) + { FreeConsole(); + } else #endif + { ConsoleThreadHandle = BeginThread(ConsoleInput, ConsoleThreadID); + } // Clear application structure. memset(&App, 0, sizeof(WINAPP)); From 22195b32675b0729f4a89abf02f8d380f3bda03e Mon Sep 17 00:00:00 2001 From: Sezz Date: Wed, 26 Mar 2025 23:26:00 +1100 Subject: [PATCH 14/53] Fix key binding settings saving for current session after hitting Esc to cancel --- CHANGELOG.md | 3 ++- TombEngine/Game/gui.cpp | 19 +++++++++++++------ TombEngine/Game/gui.h | 6 +++--- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9dab845db..4e17ee3ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,12 +9,13 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Added live console input to perform Lua commands in realtime. ### Bug fixes -* Fixed pathfinding for friendly NPCs, such as monkeys. +* Fixed pathfinding for friendly NPCs such as monkeys. * Fixed particles remaining in the level after reloading from the savegame. * Fixed particles being canceled by fog bulbs. * Fixed crash in case hair object is the last object in a level. * Fixed crash with incorrectly applied animated textures on static meshes. * Fixed console window not hiding in non-debug mode on Windows 11. +* Fixed key binding settings saving for the current play session after hitting Esc to cancel. ### Lua API changes * Added missing constructor for `Collision.Probe` without room number. diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index a024419a2..46558185d 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -690,7 +690,7 @@ namespace TEN::Gui CurrentSettings.IgnoreInput = true; } - if (CurrentSettings.NewKeyWaitTimer > 0.0f) + if (CurrentSettings.NewKeyWaitTimer > 0) { ClearAllActions(); @@ -699,15 +699,15 @@ namespace TEN::Gui bool legacy30FpsDoneDraw = false; bool decreaseCounter = false; - while (CurrentSettings.NewKeyWaitTimer > 0.0f) + while (CurrentSettings.NewKeyWaitTimer > 0) { g_Synchronizer.Sync(); while (g_Synchronizer.Synced()) { - CurrentSettings.NewKeyWaitTimer -= 1.0f; - if (CurrentSettings.NewKeyWaitTimer <= 0.0f) - CurrentSettings.NewKeyWaitTimer = 0.0f; + CurrentSettings.NewKeyWaitTimer--; + if (CurrentSettings.NewKeyWaitTimer <= 0) + CurrentSettings.NewKeyWaitTimer = 0; if (!fromPauseMenu) { @@ -760,7 +760,7 @@ namespace TEN::Gui g_Bindings.SetKeyBinding(InputDeviceID::Custom, InputActionID(baseIndex + SelectedOption), selectedKeyID); DefaultConflict(); - CurrentSettings.NewKeyWaitTimer = 0.0f; + CurrentSettings.NewKeyWaitTimer = 0; CurrentSettings.IgnoreInput = true; return; } @@ -850,6 +850,7 @@ namespace TEN::Gui if (SelectedOption == (OptionCount - 2)) { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); + ApplyDefaultBindings(); return; } @@ -858,9 +859,11 @@ namespace TEN::Gui if (SelectedOption == (OptionCount - 1)) { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); + CurrentSettings.Configuration.Bindings = g_Bindings.GetBindingProfile(InputDeviceID::Custom); g_Configuration.Bindings = g_Bindings.GetBindingProfile(InputDeviceID::Custom); SaveConfiguration(); + MenuToDisplay = fromPauseMenu ? Menu::Pause : Menu::Options; SelectedOption = 2; return; @@ -870,7 +873,9 @@ namespace TEN::Gui if (SelectedOption == OptionCount) { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); + g_Bindings.SetBindingProfile(InputDeviceID::Custom, CurrentSettings.Configuration.Bindings); + MenuToDisplay = fromPauseMenu ? Menu::Pause : Menu::Options; SelectedOption = 2; return; @@ -881,6 +886,8 @@ namespace TEN::Gui { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); + g_Bindings.SetBindingProfile(InputDeviceID::Custom, CurrentSettings.Configuration.Bindings); + MenuToDisplay = Menu::Options; SelectedOption = 2; } diff --git a/TombEngine/Game/gui.h b/TombEngine/Game/gui.h index bca6f8b3a..8a04f1e9c 100644 --- a/TombEngine/Game/gui.h +++ b/TombEngine/Game/gui.h @@ -111,9 +111,9 @@ namespace TEN::Gui GameConfiguration Configuration = {}; - int SelectedScreenResolution = 0; - bool IgnoreInput = false; // Ignore input until all actions are inactive. - float NewKeyWaitTimer = 0.0f; + int SelectedScreenResolution = 0; + bool IgnoreInput = false; // Ignore input until all actions are inactive. + int NewKeyWaitTimer = 0; }; class GuiController From 539c19bdee440763adf332ab6301d057e5155824 Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 27 Mar 2025 03:43:10 +1100 Subject: [PATCH 15/53] Update README.md --- README.md | 56 +++++++++++++++++++++++++++---------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index 5ad28cfa3..557b222d6 100644 --- a/README.md +++ b/README.md @@ -1,41 +1,41 @@ -# TombEngine +# Tomb Engine ![Logo](https://github.com/MontyTRC89/TombEngine/blob/7c50d26ca898c74978336d41e16ce3ce0c8ecacd/TEN%20logo.png) -TombEngine (TEN) is an open-source, custom level engine which aims to abolish limits and fix bugs of the classic Tomb Raider games, introduce new features while refining old ones, and provide user-friendly level creation process. Current support includes: -- Lua (as the native scripting language) -- Many objects from the original series (1-5) -- Support for high framerate, antialiasing, mipmapping and SSAO -- Full diagonal geometry support -- Uncapped map size -- A streamlined player control scheme. +*Tomb Engine* (*TEN*) is an open-source custom level engine which aims to abolish limits and fix bugs of the classic Tomb Raider games. It aims to introduce new features, refine old ones, and provide a user-friendly level creation process. Current support includes: +- *Lua* as the native scripting language. +- Many objects from the original series (1-5). +- Support for high framerate, antialiasing, mipmapping, and SSAO. +- Full diagonal geometry support. +- Uncapped map size. +- A streamlined player control scheme.. -If you would like to participate in TEN discussion with other TEN devs whether it is contributing, bugs or general discussion, then join this discord server: https://discord.gg/h5tUYFmres +Contributions are welcome. If you would like to participate in development to any degree, whether that be through suggestions, bug reports, or code, join our [Discord server](https://discord.gg/h5tUYFmres). -Tomb Engine should be used in conjuction with Tomb Editor. Tomb Editor is also open source written in C#, you can find the repository here: https://github.com/MontyTRC89/Tomb-Editor +*Tomb Engine* is used in conjunction with *Tomb Editor*. The repository can be found [here](https://github.com/MontyTRC89/Tomb-Editor). -# Compiling TombEngine -To compile TEN, ensure you have installed: -- Microsoft Visual Studio -- Tomb Editor (if you would like to create and test levels) +# Compiling *Tomb Engine* +To compile *TEN*, ensure you have installed: +- *Microsoft Visual Studio* +- *Tomb Editor* (for level creation and testing) Steps: -1) Clone the repository to your GitHub Desktop -2) Open TombEngine.sln -4) Compile the solution -5) Once compiled, create a separate folder to serve as your main TEN directory (or create test TEN project using TombIDE) -6) Copy everything inside the Build folder to the main TEN directory -7) Ensure you have the necessary level data and texture files as well -8) In the case Windows warns about missing DLLs, (bass.dll, etc.) copy the missing DLL files found inside the Libs folder to your main TEN directory. +1) Clone the repository to your GitHub Desktop. +2) Open `TombEngine.sln`. +4) Compile the solution. +5) Once compiled, create a separate folder to serve as your main *TEN* directory (or create a test *TEN* project using *TombIDE*) +6) Copy everything inside the `Build` folder to the main *TEN* directory. +7) Ensure you have the necessary level data and texture files. +8) In case Windows warns about missing DLLs (bass.dll, etc.), copy the missing DLL files found inside the `Libs` folder to your main `TEN` directory. -Visual Studio may also warn about NuGet packages. To fix: -1) Delete the Packages folder -2) Go back to Microsoft Visual Studio -3) Right-click on the TombEngine solution in the Solution Explorer tab and select "Restore NuGet Packages" -4) If it doesn't help, manually install `directxtk_desktop_2019` and `Microsoft.XAudio2.Redist` packages via NuGet Package Manager +*Visual Studio* may warn about NuGet packages. To fix: +1) Delete the `Packages` folder. +2) Go back to *Microsoft Visual Studio*. +3) Right-click on the *TEN* solution in the *Solution Explorer* tab and select "Restore NuGet Packages". +4) If it doesn't help, manually install `directxtk_desktop_2019` and `Microsoft.XAudio2.Redist` packages via NuGet Package Manager. -Once done, you should be able to build a level with TombEditor and run it in TEN. +Once done, you should be able to build a level with *Tomb Editor* and run it in *TEN*. # Disclaimer -This is a community project which is not affiliated with Core Design, Eidos Interactive, or Embracer Group AB. Tomb Raider is a registered trademark of Embracer Group AB. TombEngine is not be sold. The code is open-source to encourage contributions and to be used for study purposes. We are not responsible for illegal uses of this source code. This source code is released as-is and continues to be maintained by non-paid contributors in their free time. +This community project is unaffiliated with Core Design, Eidos Interactive, or Embracer Group AB. *Tomb Raider* is a registered trademark of Embracer Group AB. *Tomb Engine* is not for sale. The code is open-source to encourage contributions and for study purposes. We are not responsible for illegal uses of this source code. This source code is released as-is and continues to be maintained by non-paid contributors in their free time. From 917a86863eb55a3561a4bc7f01f765c2f9e3d169 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 26 Mar 2025 19:41:53 +0100 Subject: [PATCH 16/53] Changed lensflare formula --- TombEngine/Shaders/PostProcess.fx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx index 79c3ebef2..0c7c232ea 100644 --- a/TombEngine/Shaders/PostProcess.fx +++ b/TombEngine/Shaders/PostProcess.fx @@ -185,7 +185,7 @@ float4 PSLensFlare(PixelShaderInput input) : SV_Target totalLensFlareColor += lensFlareColor; } - color.xyz += totalLensFlareColor; + color.xyz = lerp(color.xyz, color.xyz + totalLensFlareColor, saturate(dot(totalLensFlareColor, float3(0.5f, 0.5f, 0.5f)))); return color; } \ No newline at end of file From 8e5f045d022716d2ef3d7d6a1055bb93727d8c67 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 26 Mar 2025 22:58:32 +0100 Subject: [PATCH 17/53] Update PostProcess.fx --- TombEngine/Shaders/PostProcess.fx | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx index 0c7c232ea..10d717245 100644 --- a/TombEngine/Shaders/PostProcess.fx +++ b/TombEngine/Shaders/PostProcess.fx @@ -114,27 +114,27 @@ float3 LensFlare(float2 uv, float2 pos) f0 += f0 * (sin((ang + rotationOffset + 1.0f / 18.0f) * 8.0f) * 0.2f + dist * 0.1f + 0.2f); // Lensflare glow components - float f2 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.8f * pos), 2.0f)), 0.0f) * 0.25f; - float f22 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.85f * pos), 2.0f)), 0.0f) * 0.23f; - float f23 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.9f * pos), 2.0f)), 0.0f) * 0.21f; + float f2 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.8f * pos), 1.0f)), 0.0f) * 0.25f; + float f22 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.85f * pos), 1.0f)), 0.0f) * 0.23f; + float f23 = max(1.0f / (1.0f + 32.0f * pow(length(uvd + 0.9f * pos), 1.0f)), 0.0f) * 0.21f; // Circular lens artifacts float2 uvx = lerp(uv, uvd, -0.5f); - float f4 = max(0.01f - pow(length(uvx + 0.4f * pos), 2.4f), 0.0f) * 6.0f; - float f42 = max(0.01f - pow(length(uvx + 0.45f * pos), 2.4f), 0.0f) * 5.0f; - float f43 = max(0.01f - pow(length(uvx + 0.5f * pos), 2.4f), 0.0f) * 3.0f; + float f4 = max(0.01f - pow(length(uvx + 0.4f * pos), 2.4f), 0.0f) * 9.0f; + float f42 = max(0.01f - pow(length(uvx + 0.45f * pos), 2.4f), 0.0f) * 7.0f; + float f43 = max(0.01f - pow(length(uvx + 0.5f * pos), 2.4f), 0.0f) * 6.0f; // Smaller lens artifacts uvx = lerp(uv, uvd, -0.4f); - float f5 = max(0.01f - pow(length(uvx + 0.2f * pos), 5.5f), 0.0f) * 2.0f; + float f5 = max(0.01f - pow(length(uvx + 0.2f * pos), 5.5f), 0.0f) * 2.0f; float f52 = max(0.01f - pow(length(uvx + 0.4f * pos), 5.5f), 0.0f) * 2.0f; float f53 = max(0.01f - pow(length(uvx + 0.6f * pos), 5.5f), 0.0f) * 2.0f; // Symmetric artifacts uvx = lerp(uv, uvd, -0.5f); - float f6 = max(0.01f - pow(length(uvx - 0.3f * pos), 1.6f), 0.0f) * 6.0f; - float f62 = max(0.01f - pow(length(uvx - 0.325f * pos), 1.6f), 0.0f) * 3.0f; - float f63 = max(0.01f - pow(length(uvx - 0.35f * pos), 1.6f), 0.0f) * 5.0f; + float f6 = max(0.01f - pow(length(uvx - 0.3f * pos), 1.6f), 0.0f) * 9.0f; + float f62 = max(0.01f - pow(length(uvx - 0.325f * pos), 1.6f), 0.0f) * 6.0f; + float f63 = max(0.01f - pow(length(uvx - 0.35f * pos), 1.6f), 0.0f) * 7.0f; // Sunflare and lensflare outputs float3 sunflare = float3(f0, f0, f0); From 9469a0e63a311da5b96918dda46c33d7c0e58e48 Mon Sep 17 00:00:00 2001 From: Nemoel-Tomo Date: Fri, 28 Mar 2025 06:44:07 +0100 Subject: [PATCH 18/53] Tomo - fireflies (#1597) * tests only - nothing to see * update * update * update * update corpse * update savegame, formatting * import develop * formatting * fix broken streamer vertex * update firefly streamer spawn * update effect * Add in objects for fireflies * fixed all reviews, formatting, changing on-off cycle * formatting * reduced the emitted light to two lights per cluster * adding antitrigger * formatting * fixed corpse * fixed a bug with corpse * fixed corpse fall bug * formatting * Small refactors * Fix merge --------- Co-authored-by: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com> --- Documentation/doc/4 enums/Objects.ObjID.html | 3 + TombEngine/Game/Setup.cpp | 2 + TombEngine/Game/control/control.cpp | 3 + TombEngine/Game/control/flipeffect.cpp | 3 + TombEngine/Game/savegame.cpp | 69 ++- TombEngine/Objects/Effects/Fireflies.cpp | 445 ++++++++++++++++ TombEngine/Objects/Effects/Fireflies.h | 76 +++ TombEngine/Objects/TR3/Object/corpse.cpp | 100 +++- TombEngine/Objects/TR5/tr5_objects.cpp | 10 + TombEngine/Objects/game_object_ids.h | 5 +- TombEngine/Renderer/Renderer.h | 1 + TombEngine/Renderer/RendererDraw.cpp | 1 + TombEngine/Renderer/RendererDrawEffect.cpp | 45 ++ .../Internal/TEN/Objects/ObjectIDs.h | 7 +- .../flatbuffers/ten_savegame_generated.h | 493 ++++++++++++++++-- .../Specific/savegame/schema/ten_savegame.fbs | 26 + TombEngine/TombEngine.vcxproj | 2 + 17 files changed, 1220 insertions(+), 71 deletions(-) create mode 100644 TombEngine/Objects/Effects/Fireflies.cpp create mode 100644 TombEngine/Objects/Effects/Fireflies.h diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index 7fa0d1ba0..b10a91473 100644 --- a/Documentation/doc/4 enums/Objects.ObjID.html +++ b/Documentation/doc/4 enums/Objects.ObjID.html @@ -952,6 +952,7 @@ DOPPELGANGER_ORIGIN CORPSE WRAITH_TRAP WATERFALL_EMITTER +FIREFLY_EMITTER MESHSWAP1 MESHSWAP2 MESHSWAP3 @@ -1132,6 +1133,7 @@ AIR_BAR_TEXTURE DASH_BAR_TEXTURE SFX_BAR_TEXTURE WATERFALL_SPRITES +FIREFLY_SPRITES CROSSHAIR_GRAPHICS SPEEDOMETER_GRAPHICS CUSTOM_BAR_GRAPHICS @@ -1410,6 +1412,7 @@ AIR_BAR_TEXTURE DASH_BAR_TEXTURE SFX_BAR_TEXTURE WATERFALL_SPRITES +FIREFLY_SPRITES CROSSHAIR_GRAPHICS SPEEDOMETER_GRAPHICS CUSTOM_BAR_GRAPHICS diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp index 42bfb08df..22ab28749 100644 --- a/TombEngine/Game/Setup.cpp +++ b/TombEngine/Game/Setup.cpp @@ -27,6 +27,7 @@ #include "Objects/TR4/Entity/tr4_beetle_swarm.h" #include "Objects/Utils/object_helper.h" #include "Specific/level.h" +#include "Objects/Effects/Fireflies.h" using namespace TEN::Effects::Hair; using namespace TEN::Entities; @@ -200,6 +201,7 @@ void InitializeSpecialEffects() TEN::Entities::TR4::ClearBeetleSwarm(); TEN::Entities::Creatures::TR3::ClearFishSwarm(); + TEN::Effects::Fireflies::ClearFireflySwarm(); } void CustomObjects() diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index 412c974dd..d5171cbae 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -59,6 +59,7 @@ #include "Specific/Input/Input.h" #include "Specific/level.h" #include "Specific/winmain.h" +#include "Objects/Effects/Fireflies.h" using namespace std::chrono; using namespace TEN::Effects; @@ -89,6 +90,7 @@ using namespace TEN::Math; using namespace TEN::Renderer; using namespace TEN::Entities::Creatures::TR3; using namespace TEN::Entities::Effects; +using namespace TEN::Effects::Fireflies; constexpr auto DEATH_NO_INPUT_TIMEOUT = 10 * FPS; constexpr auto DEATH_INPUT_TIMEOUT = 3 * FPS; @@ -211,6 +213,7 @@ GameStatus GamePhase(bool insideMenu) UpdateLocusts(); UpdateUnderwaterBloodParticles(); UpdateFishSwarm(); + UpdateFireflySwarm(); UpdateGlobalLensFlare(); // Update HUD. diff --git a/TombEngine/Game/control/flipeffect.cpp b/TombEngine/Game/control/flipeffect.cpp index e1b3af5d4..c473386d0 100644 --- a/TombEngine/Game/control/flipeffect.cpp +++ b/TombEngine/Game/control/flipeffect.cpp @@ -17,6 +17,7 @@ #include "Game/Setup.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Objects/Effects/Fireflies.h" #include "Objects/Generic/puzzles_keys.h" #include "Objects/TR3/Entity/FishSwarm.h" #include "Objects/TR4/Entity/tr4_beetle_swarm.h" @@ -29,6 +30,7 @@ using namespace TEN::Effects::Environment; using namespace TEN::Effects::Footprint; using namespace TEN::Effects::Hair; using namespace TEN::Entities::Creatures::TR3; +using namespace TEN::Effects::Fireflies; int FlipEffect; @@ -90,6 +92,7 @@ void ClearSwarmEnemies(ItemInfo* item) ClearBeetleSwarm(); ClearLocusts(); ClearFishSwarm(); + ClearFireflySwarm(); } void FlashOrange(ItemInfo* item) diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index b2ae7ec0c..8f3f1394c 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -10,6 +10,7 @@ #include "Game/control/flipeffect.h" #include "Game/control/lot.h" #include "Game/control/volume.h" +#include "Objects/Effects/Fireflies.h" #include "Game/effects/item_fx.h" #include "Game/effects/effects.h" #include "Game/effects/weather.h" @@ -43,8 +44,9 @@ using namespace flatbuffers; using namespace TEN::Collision::Floordata; using namespace TEN::Control::Volumes; -using namespace TEN::Effects::Items; using namespace TEN::Effects::Environment; +using namespace TEN::Effects::Fireflies; +using namespace TEN::Effects::Items; using namespace TEN::Entities::Creatures::TR3; using namespace TEN::Entities::Generic; using namespace TEN::Entities::Switches; @@ -924,6 +926,38 @@ const std::vector SaveGame::Build() } auto fishSwarmOffset = fbb.CreateVector(fishSwarm); + std::vector> fireflySwarm; + for (const auto& firefly : FireflySwarm) + { + Save::FireflyDataBuilder fireflySave{ fbb }; + fireflySave.add_sprite_index(firefly.SpriteSeqID); + fireflySave.add_sprite_id(firefly.SpriteID); + fireflySave.add_blend_mode((int)firefly.blendMode); + fireflySave.add_scalar(firefly.scalar); + fireflySave.add_position(&FromVector3(firefly.Position)); + fireflySave.add_room_number(firefly.RoomNumber); + fireflySave.add_position_target(&FromVector3(firefly.PositionTarget)); + fireflySave.add_orientation(&FromEulerAngles(firefly.Orientation)); + fireflySave.add_velocity(firefly.Velocity); + fireflySave.add_target_item_number((firefly.TargetItemPtr == nullptr) ? -1 : firefly.TargetItemPtr->Index); + fireflySave.add_z_vel(firefly.zVel); + fireflySave.add_life(firefly.Life); + fireflySave.add_number(firefly.Number); + fireflySave.add_d_r(firefly.rB); + fireflySave.add_d_g(firefly.gB); + fireflySave.add_d_b(firefly.bB); + fireflySave.add_r(firefly.r); + fireflySave.add_g(firefly.g); + fireflySave.add_b(firefly.b); + fireflySave.add_on(firefly.on); + fireflySave.add_size(firefly.size); + fireflySave.add_rot_Ang(firefly.rotAng); + + auto fireflySaveOffset = fireflySave.Finish(); + fireflySwarm.push_back(fireflySaveOffset); + } + auto fireflySwarmOffset = fbb.CreateVector(fireflySwarm); + // TODO: In future, we should save only active FX, not whole array. // This may come together with Monty's branch merge -- Lwmte, 10.07.22 @@ -1545,6 +1579,7 @@ const std::vector SaveGame::Build() sgb.add_next_item_active(NextItemActive); sgb.add_items(serializedItemsOffset); sgb.add_fish_swarm(fishSwarmOffset); + sgb.add_firefly_swarm(fireflySwarmOffset); sgb.add_fxinfos(serializedEffectsOffset); sgb.add_next_fx_free(NextFxFree); sgb.add_next_fx_active(NextFxActive); @@ -2289,6 +2324,38 @@ static void ParseEffects(const Save::SaveGame* s) FishSwarm.push_back(fish); } + // Load firefly swarm. + for (int i = 0; i < s->firefly_swarm()->size(); i++) + { + const auto& fireflySave = s->firefly_swarm()->Get(i); + auto firefly = FireflyData{}; + + firefly.SpriteSeqID = fireflySave->sprite_index(); + firefly.SpriteID = fireflySave->sprite_id(); + firefly.blendMode = (BlendMode)fireflySave->blend_mode(); + firefly.scalar = fireflySave->scalar(); + firefly.Position = ToVector3(fireflySave->position()); + firefly.RoomNumber = fireflySave->room_number(); + firefly.PositionTarget = ToVector3(fireflySave->position_target()); + firefly.Orientation = ToEulerAngles(fireflySave->orientation()); + firefly.Velocity = fireflySave->velocity(); + firefly.TargetItemPtr = (fireflySave->target_item_number() == -1) ? nullptr : &g_Level.Items[fireflySave->target_item_number()]; + firefly.zVel = fireflySave->z_vel(); + firefly.Life = fireflySave->life(); + firefly.Number = fireflySave->number(); + firefly.rB = fireflySave->d_r(); + firefly.gB = fireflySave->d_g(); + firefly.bB = fireflySave->d_b(); + firefly.r = fireflySave->r(); + firefly.g = fireflySave->g(); + firefly.b = fireflySave->b(); + firefly.on = fireflySave->on(); + firefly.size = fireflySave->size(); + firefly.rotAng = fireflySave->rot_Ang(); + + FireflySwarm.push_back(firefly); + } + // Load particles. for (int i = 0; i < s->particles()->size(); i++) { diff --git a/TombEngine/Objects/Effects/Fireflies.cpp b/TombEngine/Objects/Effects/Fireflies.cpp new file mode 100644 index 000000000..0510283f9 --- /dev/null +++ b/TombEngine/Objects/Effects/Fireflies.cpp @@ -0,0 +1,445 @@ +#include "framework.h" +#include "Objects/Effects/Fireflies.h" + +#include "Game/collision/collide_item.h" +#include "Game/collision/collide_room.h" +#include "Game/collision/Point.h" +#include "Game/control/box.h" +#include "Game/control/flipeffect.h" +#include "Game/effects/effects.h" +#include "Game/effects/Streamer.h" +#include "Game/effects/tomb4fx.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Game/Lara/lara_helpers.h" +#include "Game/misc.h" +#include "Game/Setup.h" +#include "Math/Math.h" +#include "Renderer/Renderer.h" +#include "Specific/clock.h" +#include "Specific/level.h" + +using namespace TEN::Collision::Point; +using namespace TEN::Math; +using namespace TEN::Renderer; +using namespace TEN::Effects::Streamer; + +namespace TEN::Effects::Fireflies +{ + constexpr auto FIREFLY_COHESION_FACTOR = 600.1f; + constexpr auto FIREFLY_SPACING_FACTOR = 600.0f; + constexpr auto FIREFLY_CATCH_UP_FACTOR = 0.2f; + constexpr auto FIREFLY_TARGET_DISTANCE_MAX = SQUARE(BLOCK(1.0f)); + constexpr auto FIREFLY_BASE_SEPARATION_DISTANCE = 10.0f; + constexpr auto FIREFLY_FLEE_DISTANCE = BLOCK(0.7); + constexpr auto MAX_FIREFLIES = 92; + constexpr auto DEFAULT_FIREFLY_COUNT = 20; + constexpr auto FIREFLY_RISE_UP_FACTOR = 200; + constexpr auto MAX_AREA_RANGE = 8; + constexpr auto LIGHT_ALPHA_CYCLE_DURATION = 120.0f; + + std::vector FireflySwarm = {}; + std::unordered_map nextFireflyNumberMap; // Numbering the Fireflies for Streamer effect. + + void InitializeFireflySwarm(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + item.Animation.Velocity.z = Random::GenerateFloat(32.0f, 160.0f); + + item.HitPoints = DEFAULT_FIREFLY_COUNT; + item.ItemFlags[FirefliesItemFlags::TargetItemPtr] = item.Index; + item.ItemFlags[FirefliesItemFlags::Light] = 1; // 0 = Turn off light effect, 1 = turn on light (DEFAULT). + + item.ItemFlags[FirefliesItemFlags::TriggerFlags] = std::clamp((int)item.TriggerFlags, -MAX_AREA_RANGE, MAX_AREA_RANGE); + + item.ItemFlags[FirefliesItemFlags::Spawncounter] = 0; + item.ItemFlags[FirefliesItemFlags::RemoveFliesEffect] = 0; + + // Firefly numbers that has the light. + item.ItemFlags[FirefliesItemFlags::LightIndex1] = NO_VALUE; + item.ItemFlags[FirefliesItemFlags::LightIndex2] = NO_VALUE; + } + + void SpawnFireflySwarm(ItemInfo& item, int triggerFlags) + { + constexpr auto VEL_MAX = 34.0f; + constexpr auto VEL_MIN = 6.0f; + + // Create new firefly. + auto& firefly = GetNewEffect(FireflySwarm, MAX_FIREFLIES); + + unsigned char r = 255; + unsigned char g = 255; + unsigned char b = 255; + + if (triggerFlags >= 0) + { + float brightnessShift = Random::GenerateFloat(-0.1f, 0.1f); + r = std::clamp(item.Model.Color.x / 2.0f + brightnessShift, 0.0f, 1.0f) * UCHAR_MAX; + g = std::clamp(item.Model.Color.y / 2.0f + brightnessShift, 0.0f, 1.0f) * UCHAR_MAX; + b = std::clamp(item.Model.Color.z / 2.0f + brightnessShift, 0.0f, 1.0f) * UCHAR_MAX; + + firefly.SpriteSeqID = ID_FIREFLY_SPRITES; + firefly.SpriteID = 0; + firefly.blendMode = BlendMode::Additive; + firefly.scalar = 3.0f; + firefly.size = 1.0f; + } + else + { + firefly.SpriteSeqID = ID_FIREFLY_SPRITES; + firefly.SpriteID = 1; + firefly.blendMode = BlendMode::Subtractive; + firefly.scalar = 1.2f; + firefly.size = 1.2f; + } + + firefly.r = firefly.rB = r; + firefly.g = firefly.gB = g; + firefly.b = firefly.bB = b; + + firefly.rotAng = ANGLE(0.0f); + + if (item.TriggerFlags > 8) + firefly.rotAng = ANGLE(90.0f); + + firefly.on = true; + + firefly.Position = item.Pose.Position.ToVector3(); + firefly.RoomNumber = item.RoomNumber; + firefly.Orientation = item.Pose.Orientation; + firefly.Velocity = Random::GenerateFloat(VEL_MIN, VEL_MAX); + firefly.zVel = 0.3f; + + firefly.Life = Random::GenerateInt(1, 400); + firefly.TargetItemPtr = &g_Level.Items[item.ItemFlags[FirefliesItemFlags::TargetItemPtr]]; + + int& nextFireflyNumber = nextFireflyNumberMap[item.Index]; + firefly.Number = nextFireflyNumber++; + } + + void ControlFireflySwarm(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + if (!TriggerActive(&item)) + { + // Remove all fireflies associated with this item. + RemoveFireflies(item); + + // Reset ItemFlags. + if (item.HitPoints == NOT_TARGETABLE) + item.HitPoints = item.ItemFlags[FirefliesItemFlags::Spawncounter]; + + item.ItemFlags[FirefliesItemFlags::Spawncounter] = 0; + item.ItemFlags[FirefliesItemFlags::LightIndex1] = NO_VALUE; + item.ItemFlags[FirefliesItemFlags::LightIndex2] = NO_VALUE; + + return; + } + + constexpr auto ALPHA_PAUSE_DURATION = 2.0f; + static float frameCounter = 0.0f; + + // Increment the counter variable in each frame. + frameCounter += 1.0f; + + if (item.HitPoints != NOT_TARGETABLE) + { + int fireflyCount = item.HitPoints - item.ItemFlags[FirefliesItemFlags::Spawncounter]; + + if (fireflyCount < 0) + { + int firefliesToTurnOff = -fireflyCount; + for (auto& firefly : FireflySwarm) + { + if (firefly.TargetItemPtr == &item && firefly.Life > 0.0f) + { + firefly.Life = 0.0f; + firefly.on = false; + firefliesToTurnOff--; + + if (firefliesToTurnOff == 0) + break; + } + } + } + else if (fireflyCount > 0) + { + for (int i = 0; i < fireflyCount; i++) + { + SpawnFireflySwarm(item, item.TriggerFlags); + } + } + + item.ItemFlags[FirefliesItemFlags::Spawncounter] = item.HitPoints; + item.HitPoints = NOT_TARGETABLE; + } + + // Update color values for blinking effect. + float alphaFactor; + + for (auto& firefly : FireflySwarm) + { + auto targetItem = firefly.TargetItemPtr; + + if (targetItem == &item) + { + // Choose one of the available firefly number that has the light. + if (targetItem->ItemFlags[FirefliesItemFlags::LightIndex1] == NO_VALUE && targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] >= 0) + { + targetItem->ItemFlags[FirefliesItemFlags::LightIndex1] = Random::GenerateInt(0, targetItem->TriggerFlags); + } + // Two lights max for each cluster. + if (targetItem->ItemFlags[FirefliesItemFlags::LightIndex2] == NO_VALUE && targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] >= 0) + { + targetItem->ItemFlags[FirefliesItemFlags::LightIndex2] = Random::GenerateInt(0, targetItem->TriggerFlags); + } + + auto posBase = firefly.Position; + auto rotMatrix = firefly.Orientation.ToRotationMatrix(); + auto pos = posBase + Vector3::Transform(Vector3(0, 0, 30), rotMatrix); + auto direction0 = Geometry::RotatePoint(posBase, EulerAngles::Identity); + short orient2D = firefly.Orientation.z; + + if (targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] >= 0) + { + StreamerEffect.Spawn(targetItem->Index, firefly.Number, pos, direction0, orient2D, + Vector4(firefly.r / (float)UCHAR_MAX, firefly.g / (float)UCHAR_MAX, firefly.b / (float)UCHAR_MAX, 1.0f), + Vector4::Zero, + 6.3f - (firefly.zVel / 12), ((firefly.Velocity / 8) + firefly.zVel * 3) / (float)UCHAR_MAX, 0.0f, -0.1f, 90.0f, StreamerFeatherMode::None, BlendMode::Additive); + } + else if (targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] < 0) + { + StreamerEffect.Spawn(targetItem->Index, firefly.Number, pos, direction0, orient2D, + Vector4((firefly.r / 2) / (float)UCHAR_MAX, (firefly.g / 2) / (float)UCHAR_MAX, (firefly.b / 2) / (float)UCHAR_MAX, 0.2f), + Vector4((firefly.r / 3) / (float)UCHAR_MAX, (firefly.g / 3) / (float)UCHAR_MAX, (firefly.b / 3) / (float)UCHAR_MAX, 0.2f), + 0.0f, 0.4f, 0.0f, 0.2f, 0.0f, StreamerFeatherMode::None, BlendMode::Subtractive); + } + + if ((targetItem->ItemFlags[FirefliesItemFlags::LightIndex1] == firefly.Number || targetItem->ItemFlags[FirefliesItemFlags::LightIndex2] == firefly.Number) && + targetItem->ItemFlags[FirefliesItemFlags::Light] == 1) + { + float totalCycleDuration = 2 * (LIGHT_ALPHA_CYCLE_DURATION + ALPHA_PAUSE_DURATION); + float alphaTime = fmod(frameCounter, totalCycleDuration); + + if (alphaTime < ALPHA_PAUSE_DURATION) + { + alphaFactor = 1.0f; // Pause on Alpha 1. + } + else if (alphaTime < ALPHA_PAUSE_DURATION + LIGHT_ALPHA_CYCLE_DURATION) + { + alphaFactor = 1.0f - ((alphaTime - ALPHA_PAUSE_DURATION) / LIGHT_ALPHA_CYCLE_DURATION); + } + else if (alphaTime < 2 * ALPHA_PAUSE_DURATION + LIGHT_ALPHA_CYCLE_DURATION) + { + alphaFactor = 0.0f; // Pause on Alpha 0. + targetItem->ItemFlags[FirefliesItemFlags::LightIndex1] = NO_VALUE; + targetItem->ItemFlags[FirefliesItemFlags::LightIndex2] = NO_VALUE; + } + else + { + alphaFactor = (alphaTime - 2 * ALPHA_PAUSE_DURATION - LIGHT_ALPHA_CYCLE_DURATION) / LIGHT_ALPHA_CYCLE_DURATION; + } + + SpawnDynamicLight(firefly.Position.x, firefly.Position.y, firefly.Position.z, 3, + static_cast(std::clamp(firefly.r * alphaFactor, 0.0f, (float)firefly.r)), + static_cast(std::clamp(firefly.g * alphaFactor, 0.0f, (float)firefly.g)), + static_cast(std::clamp(firefly.b * alphaFactor, 0.0f, (float)firefly.b))); + } + } + } + } + + void UpdateFireflySwarm() + { + constexpr auto FLEE_VEL = 1.5f; + constexpr auto ALPHA_PAUSE_DURATION = 100.0f; + + static const auto SPHERE = BoundingSphere(Vector3::Zero, BLOCK(1 / 8.0f)); + + if (FireflySwarm.empty()) + return; + + const auto& playerItem = *LaraItem; + static float frameCounter = 0.0f; + + // Increment the counter variable in each frame. + frameCounter += 1.0f; + + for (auto& firefly : FireflySwarm) + { + if (firefly.Life <= 0.0f || !firefly.on) + continue; + + auto targetItem = firefly.TargetItemPtr; + + if (targetItem->ItemFlags[FirefliesItemFlags::RemoveFliesEffect]) + { + firefly.r = 0; + firefly.g = 0; + firefly.b = 0; + continue; + } + + firefly.StoreInterpolationData(); + + firefly.PositionTarget = Random::GeneratePointInSphere(SPHERE); + + int multiplierX = CLICK(targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] * 2); + int multiplierY = CLICK(targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] * 4); + int multiplierZ = CLICK(targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] * 2); + + auto spheroidAxis = Vector3(multiplierX, multiplierY, multiplierZ); + auto itemPos = Vector3i(targetItem->Pose.Position.x, targetItem->Pose.Position.y - FIREFLY_RISE_UP_FACTOR, targetItem->Pose.Position.z); + + // Calculate desired position based on target object and random offsets. + auto desiredPos = itemPos + Random::GeneratePointInSpheroid(firefly.PositionTarget, EulerAngles::Identity, spheroidAxis); + auto dir = desiredPos - firefly.Position; + + auto dirs = dir.ToVector3(); + dirs.Normalize(); + auto dirNorm = dirs; + + // Define cohesion factor to keep fireflies close together. + float distToTarget = dirs.Length(); + + float targetVel = (distToTarget * FIREFLY_COHESION_FACTOR) + Random::GenerateFloat(3.0f, 5.0f); + firefly.Velocity = std::min(targetVel, targetItem->Animation.Velocity.z - 21.0f); + + // If firefly is too far from target, increase velocity to catch up. + if (distToTarget > FIREFLY_TARGET_DISTANCE_MAX) + firefly.Velocity += FIREFLY_CATCH_UP_FACTOR; + + // Translate. + auto moveDir = firefly.Orientation.ToDirection(); + moveDir.Normalize(); + firefly.Position += (moveDir * firefly.Velocity) / 26.0f; + firefly.Position += (moveDir * FIREFLY_SPACING_FACTOR) / 26.0f; + + auto orientTo = Geometry::GetOrientToPoint(firefly.Position, desiredPos.ToVector3()); + firefly.Orientation.Lerp(orientTo, 0.1f); + + // Update color values for blinking effect. + float totalCycleDuration = 2 * (LIGHT_ALPHA_CYCLE_DURATION + ALPHA_PAUSE_DURATION); + float alphaTime = fmod(frameCounter + firefly.Life, totalCycleDuration); + float alphaFactor; + + if (alphaTime < ALPHA_PAUSE_DURATION) + { + alphaFactor = 1.0f; + } + else if (alphaTime < ALPHA_PAUSE_DURATION + LIGHT_ALPHA_CYCLE_DURATION) + { + alphaFactor = 1.0f - ((alphaTime - ALPHA_PAUSE_DURATION) / LIGHT_ALPHA_CYCLE_DURATION); + } + else if (alphaTime < 2 * ALPHA_PAUSE_DURATION + LIGHT_ALPHA_CYCLE_DURATION) + { + alphaFactor = 0.0f; + } + else + { + alphaFactor = (alphaTime - 2 * ALPHA_PAUSE_DURATION - LIGHT_ALPHA_CYCLE_DURATION) / LIGHT_ALPHA_CYCLE_DURATION; + } + + firefly.r = static_cast(firefly.rB * alphaFactor); + firefly.g = static_cast(firefly.gB * alphaFactor); + firefly.b = static_cast(firefly.bB * alphaFactor); + + for (const auto& otherFirefly : FireflySwarm) + { + if (&firefly == &otherFirefly) + continue; + + float distToOtherFirefly = Vector3i::Distance(firefly.Position, otherFirefly.Position); + float distToPlayer = Vector3i::Distance(firefly.Position, playerItem.Pose.Position); + + // If player is too close, flee. + if (distToPlayer < FIREFLY_FLEE_DISTANCE && playerItem.Animation.ActiveState != 2) + { + auto separationDir = firefly.Position - playerItem.Pose.Position.ToVector3(); + separationDir.Normalize(); + + // Reduce the Y component of the escape direction. + separationDir.y *= Random::GenerateFloat(0.0f, 0.4f); + + // Normalize the direction again to get the length of the vector. + separationDir.Normalize(); + + firefly.Position += separationDir * FLEE_VEL; + + auto orientTo = Geometry::GetOrientToPoint(firefly.Position, separationDir); + firefly.Orientation.Lerp(orientTo, 0.05f); + + firefly.Velocity -= std::min(FLEE_VEL, firefly.TargetItemPtr->Animation.Velocity.z - 1.0f); + + if (Random::TestProbability(1.0f / 700.0f) && + targetItem->ItemFlags[FirefliesItemFlags::Light] == 1 && + targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] >= 0) + { + if (firefly.zVel == 0.3f) + { + firefly.zVel = 50.0f; + } + } + + if (firefly.zVel > 50.0f) + firefly.zVel = 0.3f; + } + + if (distToOtherFirefly < FIREFLY_BASE_SEPARATION_DISTANCE) + { + auto separationDir = firefly.Position - otherFirefly.Position; + separationDir.Normalize(); + + firefly.Position += separationDir * (FIREFLY_BASE_SEPARATION_DISTANCE - distToOtherFirefly); + } + } + + auto pointColl = GetPointCollision(firefly.Position, firefly.RoomNumber); + + // Update firefly room number. + if (pointColl.GetRoomNumber() != firefly.RoomNumber && + pointColl.GetRoomNumber() != NO_VALUE) + { + firefly.RoomNumber = pointColl.GetRoomNumber(); + } + + if (targetItem->ItemFlags[FirefliesItemFlags::Light] == 1 && targetItem->ItemFlags[FirefliesItemFlags::TriggerFlags] >= 0) + { + if (Random::TestProbability(1.0f / (700.0f - (float)(targetItem->ItemFlags[FirefliesItemFlags::Spawncounter] * 2)))) + firefly.zVel = 100.0f; + + if (firefly.zVel > 1.0f) + firefly.zVel -= 2.0f; + if (firefly.zVel <= 1.0f) + firefly.zVel = 0.3f; + } + } + } + + void RemoveFireflies(ItemInfo& item) + { + FireflySwarm.erase(std::remove_if(FireflySwarm.begin(), FireflySwarm.end(), + [&item](FireflyData& firefly) + { + if (firefly.TargetItemPtr == &item) + { + firefly.Life = 0.0f; + firefly.on = false; + return true; + } + return false; + }), FireflySwarm.end()); + nextFireflyNumberMap.erase(item.Index); + } + + void ClearFireflySwarm() + { + FireflySwarm.clear(); + nextFireflyNumberMap.clear(); + } +} + + diff --git a/TombEngine/Objects/Effects/Fireflies.h b/TombEngine/Objects/Effects/Fireflies.h new file mode 100644 index 000000000..807869b81 --- /dev/null +++ b/TombEngine/Objects/Effects/Fireflies.h @@ -0,0 +1,76 @@ +#pragma once +#include "Game/items.h" +#include "Math/Math.h" + +using namespace TEN::Math; + +namespace TEN::Effects::Fireflies +{ + enum FirefliesItemFlags + { + TargetItemPtr, + Light, + TriggerFlags, + Spawncounter, + RemoveFliesEffect, + LightIndex1, + LightIndex2 + }; + + struct FireflyData + { + int SpriteSeqID = ID_DEFAULT_SPRITES; + int SpriteID = SPR_UNDERWATERDUST; + BlendMode blendMode; + unsigned int scalar; + + Vector3 Position = Vector3::Zero; + int RoomNumber = 0; + Vector3 PositionTarget = Vector3::Zero; + EulerAngles Orientation = EulerAngles::Identity; + float Velocity = 0.0f; + + ItemInfo* TargetItemPtr = nullptr; + + float zVel; + float Life = 0.0f; + int Number = 0; + + unsigned char rB; + unsigned char gB; + unsigned char bB; + unsigned char r; + unsigned char g; + unsigned char b; + + bool on; + float size; + short rotAng; + + int PrevX; + int PrevY; + int PrevZ; + byte PrevR; + byte PrevG; + byte PrevB; + + void StoreInterpolationData() + { + PrevX = Position.x; + PrevY = Position.y; + PrevZ = Position.z; + PrevR = r; + PrevG = g; + PrevB = b; + } + }; + + extern std::vector FireflySwarm; + + void InitializeFireflySwarm(short itemNumber); + void ControlFireflySwarm(short itemNumber); + void UpdateFireflySwarm(); + void ClearFireflySwarm(); + void SpawnFireflySwarm(ItemInfo& item, int triggerFlags); + void RemoveFireflies(ItemInfo& item); +} diff --git a/TombEngine/Objects/TR3/Object/corpse.cpp b/TombEngine/Objects/TR3/Object/corpse.cpp index 527f12f1c..3b3da8a3b 100644 --- a/TombEngine/Objects/TR3/Object/corpse.cpp +++ b/TombEngine/Objects/TR3/Object/corpse.cpp @@ -17,6 +17,7 @@ #include "Game/Lara/lara_helpers.h" #include "Game/Setup.h" #include "Math/Math.h" +#include "Objects/Effects/Fireflies.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Sound/sound.h" #include "Specific/level.h" @@ -25,9 +26,13 @@ using namespace TEN::Collision::Point; using namespace TEN::Effects::Ripple; using namespace TEN::Effects::Splash; using namespace TEN::Math; +using namespace TEN::Effects::Fireflies; namespace TEN::Entities::TR3 { + constexpr auto FLY_EFFECT_MAX_WIDTH = -1; + constexpr auto FLY_AMOUNT = 16; + enum CorpseState { CORPSE_STATE_GROUNDED = 0, @@ -51,19 +56,25 @@ namespace TEN::Entities::TR3 if (item.TriggerFlags == 1) { - item.ItemFlags[1] = (int)CorpseFlag::Hang; + item.ItemFlags[7] = (int)CorpseFlag::Hang; item.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_HANG; item.Animation.ActiveState = CORPSE_STATE_HANG; } else { - item.ItemFlags[1] = (int)CorpseFlag::Grounded; + item.ItemFlags[7] = (int)CorpseFlag::Grounded; item.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_GROUNDED; item.Animation.ActiveState = CORPSE_STATE_GROUNDED; } + item.ItemFlags[FirefliesItemFlags::RemoveFliesEffect] = 0; + AddActiveItem(itemNumber); item.Status = ITEM_ACTIVE; + + item.ItemFlags[FirefliesItemFlags::TargetItemPtr] = item.Index; + item.ItemFlags[FirefliesItemFlags::TriggerFlags] = -1; + item.HitPoints = FLY_AMOUNT; } void ControlCorpse(short itemNumber) @@ -71,9 +82,11 @@ namespace TEN::Entities::TR3 auto& item = g_Level.Items[itemNumber]; const auto& object = Objects[item.ObjectNumber]; - if (item.ItemFlags[1] == (int)CorpseFlag::Fall) + if (item.ItemFlags[7] == (int)CorpseFlag::Fall) { bool isWater = TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item.RoomNumber); + bool isSwamp = TestEnvironment(RoomEnvFlags::ENV_FLAG_SWAMP, item.RoomNumber); + float verticalVelCoeff = isWater ? 81.0f : 1.0f; auto pointColl = GetPointCollision(item); @@ -94,31 +107,37 @@ namespace TEN::Entities::TR3 ItemNewRoom(itemNumber, pointColl.GetRoomNumber()); } - pointColl = GetPointCollision(item); + // Remove fly effect when in water. + if (isWater || isSwamp) + { + item.ItemFlags[FirefliesItemFlags::RemoveFliesEffect] = 1; + } + + auto bounds = GameBoundingBox(&item); + item.Animation.IsAirborne = true; - if (pointColl.GetFloorHeight() < item.Pose.Position.y) + if (pointColl.GetFloorHeight() <= item.Pose.Position.y - bounds.Y2) { if (!isWater) { - item.Pose.Position.y = item.Pose.Position.y - item.Animation.Velocity.y; + item.Pose.Position.y = pointColl.GetFloorHeight(); SoundEffect(SFX_TR4_CROCGOD_LAND, &item.Pose); } - else + else { - item.Pose.Position.y = item.Pose.Position.y; + item.Pose.Position.y = pointColl.GetFloorHeight(); } item.Animation.IsAirborne = false; item.Animation.Velocity = Vector3::Zero; item.Animation.TargetState = CORPSE_STATE_LAND; item.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_LAND; - AlignEntityToSurface(&item, Vector2(object.radius)); - item.ItemFlags[1] = (int)CorpseFlag::Grounded; + item.ItemFlags[7] = (int)CorpseFlag::Grounded; return; } - else + else if (item.Animation.ActiveState == CORPSE_STATE_FALL) { if (isWater) { @@ -133,17 +152,56 @@ namespace TEN::Entities::TR3 AnimateItem(&item); - if (!TriggerActive(&item)) - return; - - int meshCount = object.nmeshes; - for (int i = 0; i < meshCount; i++) + if (!TriggerActive(&item) || item.ItemFlags[FirefliesItemFlags::RemoveFliesEffect] == 1) { - if (Random::TestProbability(1 / 72.0f)) + // Remove all fireflies associated with this item. + RemoveFireflies(item); + + // Reset ItemFlags. + if (item.HitPoints == NOT_TARGETABLE) + item.HitPoints = FLY_AMOUNT; + + item.ItemFlags[FirefliesItemFlags::Spawncounter] = 0; + + return; + } + else + { + AddActiveItem(itemNumber); + item.Status = ITEM_ACTIVE; + } + + // Spawn fly effect. + if (item.HitPoints != NOT_TARGETABLE) + { + int fireflyCount = item.HitPoints - item.ItemFlags[FirefliesItemFlags::Spawncounter]; + + if (fireflyCount < 0) { - auto pos = GetJointPosition(&item, i).ToVector3(); - SpawnCorpseEffect(pos); + int firefliesToTurnOff = -fireflyCount; + for (auto& firefly : FireflySwarm) + { + if (firefly.TargetItemPtr == &item && firefly.Life > 0.0f) + { + firefly.Life = 0.0f; + firefly.on = false; + firefliesToTurnOff--; + + if (firefliesToTurnOff == 0) + break; + } + } } + else if (fireflyCount > 0) + { + for (int i = 0; i < fireflyCount; i++) + { + SpawnFireflySwarm(item, FLY_EFFECT_MAX_WIDTH); + } + } + + item.ItemFlags[FirefliesItemFlags::Spawncounter] = item.HitPoints; + item.HitPoints = NOT_TARGETABLE; } } @@ -160,9 +218,9 @@ namespace TEN::Entities::TR3 { DoBloodSplat(pos->x, pos->y, pos->z, Random::GenerateInt(4, 8), source.Pose.Orientation.y, pos->RoomNumber); - if (target.ItemFlags[1] == (int)CorpseFlag::Hang) + if (target.ItemFlags[7] == (int)CorpseFlag::Hang) { - target.ItemFlags[1] = (int)CorpseFlag::Fall; + target.ItemFlags[7] = (int)CorpseFlag::Fall; target.Animation.AnimNumber = object.animIndex + CORPSE_ANIM_FALL; target.Animation.ActiveState = CORPSE_STATE_FALL; } diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp index 9b5b878b6..130d7405f 100644 --- a/TombEngine/Objects/TR5/tr5_objects.cpp +++ b/TombEngine/Objects/TR5/tr5_objects.cpp @@ -42,6 +42,7 @@ #include "Objects/TR5/Emitter/tr5_spider_emitter.h" #include "Objects/TR5/Emitter/tr5_smoke_emitter.h" #include "Objects/TR5/Emitter/Waterfall.h" +#include "Objects/Effects/Fireflies.h" // Objects #include "Objects/TR5/Light/tr5_light.h" @@ -81,6 +82,7 @@ using namespace TEN::Effects::WaterfallEmitter; using namespace TEN::Entities::Creatures::TR5; using namespace TEN::Entities::Switches; using namespace TEN::Entities::Traps; +using namespace TEN::Effects::Fireflies; static void StartEntity(ObjectInfo *obj) { @@ -796,6 +798,14 @@ static void StartObject(ObjectInfo *obj) obj->control = ControlEmberEmitter; } + obj = &Objects[ID_FIREFLY_EMITTER]; + if (obj->loaded) + { + obj->Initialize = InitializeFireflySwarm; + obj->control = ControlFireflySwarm; + obj->drawRoutine = NULL; + } + obj = &Objects[ID_GEN_SLOT1]; if (obj->loaded) { diff --git a/TombEngine/Objects/game_object_ids.h b/TombEngine/Objects/game_object_ids.h index 26138ce91..18c64a25b 100644 --- a/TombEngine/Objects/game_object_ids.h +++ b/TombEngine/Objects/game_object_ids.h @@ -817,6 +817,7 @@ enum GAME_OBJECT_ID : short ID_CORPSE, ID_WRAITH_TRAP, ID_WATERFALL_EMITTER, + ID_FIREFLY_EMITTER, ID_MESHSWAP1 = 1100, ID_MESHSWAP2, @@ -1006,8 +1007,8 @@ enum GAME_OBJECT_ID : short ID_DASH_BAR_TEXTURE, ID_SFX_BAR_TEXTURE, ID_WATERFALL_SPRITES, - // 1379 - ID_CROSSHAIR_GRAPHICS = 1380, + ID_FIREFLY_SPRITES, + ID_CROSSHAIR_GRAPHICS, ID_SPEEDOMETER_GRAPHICS, ID_CUSTOM_BAR_GRAPHICS, ID_CUSTOM_AMMO_GRAPHICS, diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index cfe315b4c..4e643388d 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -409,6 +409,7 @@ namespace TEN::Renderer void PrepareFires(RenderView& view); void PrepareParticles(RenderView& view); void PrepareSmokes(RenderView& view); + void PrepareFireflies(RenderView& view); void PrepareElectricity(RenderView& view); void PrepareHelicalLasers(RenderView& view); void PrepareBlood(RenderView& view); diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index a79e06298..1c63b24d8 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -1759,6 +1759,7 @@ namespace TEN::Renderer PrepareStreamers(view); PrepareLaserBarriers(view); PrepareSingleLaserBeam(view); + PrepareFireflies(view); // Sprites grouped in buckets for instancing. Non-commutative sprites are collected at a later stage. SortAndPrepareSprites(view); diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp index 3b00f6c5f..e647f86b1 100644 --- a/TombEngine/Renderer/RendererDrawEffect.cpp +++ b/TombEngine/Renderer/RendererDrawEffect.cpp @@ -35,6 +35,7 @@ #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Specific/level.h" #include "Structures/RendererSpriteBucket.h" +#include "Objects/Effects/Fireflies.h" using namespace TEN::Effects::Blood; using namespace TEN::Effects::Bubble; @@ -48,6 +49,7 @@ using namespace TEN::Effects::Streamer; using namespace TEN::Entities::Creatures::TR5; using namespace TEN::Entities::Traps; using namespace TEN::Math; +using namespace TEN::Effects::Fireflies; extern BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD]; extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; @@ -330,6 +332,49 @@ namespace TEN::Renderer } } + void Renderer::PrepareFireflies(RenderView& view) + { + if (!Objects[ID_FIREFLY_EMITTER].loaded) + return; + + for (auto& firefly : FireflySwarm) + { + if (!firefly.on) + continue; + + + if (!CheckIfSlotExists(ID_SPARK_SPRITE, "Particle rendering")) + continue; + + auto axis = Vector3(0,0,0); + axis.Normalize(); + + + firefly.scalar = 3; + firefly.size = 3; + + auto pos = Vector3::Lerp( + Vector3(firefly.PrevX, firefly.PrevY, firefly.PrevZ), + Vector3(firefly.Position.x, firefly.Position.y, firefly.Position.z), + GetInterpolationFactor()); + + pos = Vector3(firefly.Position.x, firefly.Position.y, firefly.Position.z); + + // Disallow sprites out of bounds. + int spriteIndex = Objects[firefly.SpriteSeqID].meshIndex + firefly.SpriteID; + spriteIndex = std::clamp(spriteIndex, 0, (int)_sprites.size()); + + AddSpriteBillboard( + &_sprites[spriteIndex], + pos, + Color(firefly.r / (float)UCHAR_MAX, firefly.g / (float)UCHAR_MAX, firefly.b / (float)UCHAR_MAX, 1.0f), + TO_RAD(firefly.rotAng << 4), firefly.scalar, + Vector2(firefly.size, firefly.size), + firefly.blendMode, true, view); + + } + } + void Renderer::PrepareSmokes(RenderView& view) { for (const auto& smoke : SmokeSparks) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h index 41dba67cb..04e5732a8 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h @@ -1,7 +1,7 @@ #pragma once // This file is generated automatically, do not edit it. -// Last generated on 13/03/2025. +// Last generated on 17/03/2025. #include #include @@ -815,6 +815,7 @@ The following constants are inside ObjID. CORPSE WRAITH_TRAP WATERFALL_EMITTER + FIREFLY_EMITTER MESHSWAP1 MESHSWAP2 MESHSWAP3 @@ -995,6 +996,7 @@ The following constants are inside ObjID. DASH_BAR_TEXTURE SFX_BAR_TEXTURE WATERFALL_SPRITES + FIREFLY_SPRITES CROSSHAIR_GRAPHICS SPEEDOMETER_GRAPHICS CUSTOM_BAR_GRAPHICS @@ -1245,6 +1247,7 @@ The following ObjID members refer to sprites. DASH_BAR_TEXTURE SFX_BAR_TEXTURE WATERFALL_SPRITES + FIREFLY_SPRITES CROSSHAIR_GRAPHICS SPEEDOMETER_GRAPHICS CUSTOM_BAR_GRAPHICS @@ -2052,6 +2055,7 @@ static const std::unordered_map GAME_OBJECT_IDS { { "CORPSE", ID_CORPSE }, { "WRAITH_TRAP", ID_WRAITH_TRAP }, { "WATERFALL_EMITTER", ID_WATERFALL_EMITTER }, + { "FIREFLY_EMITTER", ID_FIREFLY_EMITTER }, { "MESHSWAP1", ID_MESHSWAP1 }, { "MESHSWAP2", ID_MESHSWAP2 }, { "MESHSWAP3", ID_MESHSWAP3 }, @@ -2232,6 +2236,7 @@ static const std::unordered_map GAME_OBJECT_IDS { { "DASH_BAR_TEXTURE", ID_DASH_BAR_TEXTURE }, { "SFX_BAR_TEXTURE", ID_SFX_BAR_TEXTURE }, { "WATERFALL_SPRITES", ID_WATERFALL_SPRITES }, + { "FIREFLY_SPRITES", ID_FIREFLY_SPRITES }, { "CROSSHAIR_GRAPHICS", ID_CROSSHAIR_GRAPHICS }, { "SPEEDOMETER_GRAPHICS", ID_SPEEDOMETER_GRAPHICS }, { "CUSTOM_BAR_GRAPHICS", ID_CUSTOM_BAR_GRAPHICS }, diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index 5c8333d07..a99d79882 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h @@ -169,6 +169,10 @@ struct FishData; struct FishDataBuilder; struct FishDataT; +struct FireflyData; +struct FireflyDataBuilder; +struct FireflyDataT; + struct KeyValPair; struct ScriptTable; @@ -6861,6 +6865,295 @@ struct FishData::Traits { flatbuffers::Offset CreateFishData(flatbuffers::FlatBufferBuilder &_fbb, const FishDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct FireflyDataT : public flatbuffers::NativeTable { + typedef FireflyData TableType; + int32_t sprite_index = 0; + int32_t sprite_id = 0; + int32_t blend_mode = 0; + int32_t scalar = 0; + std::unique_ptr position{}; + int32_t room_number = 0; + std::unique_ptr position_target{}; + std::unique_ptr orientation{}; + float velocity = 0.0f; + int32_t target_item_number = 0; + float z_vel = 0.0f; + float life = 0.0f; + int32_t number = 0; + int32_t d_r = 0; + int32_t d_g = 0; + int32_t d_b = 0; + int32_t r = 0; + int32_t g = 0; + int32_t b = 0; + bool on = false; + float size = 0.0f; + int32_t rot_Ang = 0; +}; + +struct FireflyData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef FireflyDataT NativeTableType; + typedef FireflyDataBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_SPRITE_INDEX = 4, + VT_SPRITE_ID = 6, + VT_BLEND_MODE = 8, + VT_SCALAR = 10, + VT_POSITION = 12, + VT_ROOM_NUMBER = 14, + VT_POSITION_TARGET = 16, + VT_ORIENTATION = 18, + VT_VELOCITY = 20, + VT_TARGET_ITEM_NUMBER = 22, + VT_Z_VEL = 24, + VT_LIFE = 26, + VT_NUMBER = 28, + VT_D_R = 30, + VT_D_G = 32, + VT_D_B = 34, + VT_R = 36, + VT_G = 38, + VT_B = 40, + VT_ON = 42, + VT_SIZE = 44, + VT_ROT_ANG = 46 + }; + int32_t sprite_index() const { + return GetField(VT_SPRITE_INDEX, 0); + } + int32_t sprite_id() const { + return GetField(VT_SPRITE_ID, 0); + } + int32_t blend_mode() const { + return GetField(VT_BLEND_MODE, 0); + } + int32_t scalar() const { + return GetField(VT_SCALAR, 0); + } + const TEN::Save::Vector3 *position() const { + return GetStruct(VT_POSITION); + } + int32_t room_number() const { + return GetField(VT_ROOM_NUMBER, 0); + } + const TEN::Save::Vector3 *position_target() const { + return GetStruct(VT_POSITION_TARGET); + } + const TEN::Save::EulerAngles *orientation() const { + return GetStruct(VT_ORIENTATION); + } + float velocity() const { + return GetField(VT_VELOCITY, 0.0f); + } + int32_t target_item_number() const { + return GetField(VT_TARGET_ITEM_NUMBER, 0); + } + float z_vel() const { + return GetField(VT_Z_VEL, 0.0f); + } + float life() const { + return GetField(VT_LIFE, 0.0f); + } + int32_t number() const { + return GetField(VT_NUMBER, 0); + } + int32_t d_r() const { + return GetField(VT_D_R, 0); + } + int32_t d_g() const { + return GetField(VT_D_G, 0); + } + int32_t d_b() const { + return GetField(VT_D_B, 0); + } + int32_t r() const { + return GetField(VT_R, 0); + } + int32_t g() const { + return GetField(VT_G, 0); + } + int32_t b() const { + return GetField(VT_B, 0); + } + bool on() const { + return GetField(VT_ON, 0) != 0; + } + float size() const { + return GetField(VT_SIZE, 0.0f); + } + int32_t rot_Ang() const { + return GetField(VT_ROT_ANG, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_SPRITE_INDEX) && + VerifyField(verifier, VT_SPRITE_ID) && + VerifyField(verifier, VT_BLEND_MODE) && + VerifyField(verifier, VT_SCALAR) && + VerifyField(verifier, VT_POSITION) && + VerifyField(verifier, VT_ROOM_NUMBER) && + VerifyField(verifier, VT_POSITION_TARGET) && + VerifyField(verifier, VT_ORIENTATION) && + VerifyField(verifier, VT_VELOCITY) && + VerifyField(verifier, VT_TARGET_ITEM_NUMBER) && + VerifyField(verifier, VT_Z_VEL) && + VerifyField(verifier, VT_LIFE) && + VerifyField(verifier, VT_NUMBER) && + VerifyField(verifier, VT_D_R) && + VerifyField(verifier, VT_D_G) && + VerifyField(verifier, VT_D_B) && + VerifyField(verifier, VT_R) && + VerifyField(verifier, VT_G) && + VerifyField(verifier, VT_B) && + VerifyField(verifier, VT_ON) && + VerifyField(verifier, VT_SIZE) && + VerifyField(verifier, VT_ROT_ANG) && + verifier.EndTable(); + } + FireflyDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(FireflyDataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const FireflyDataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct FireflyDataBuilder { + typedef FireflyData Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_sprite_index(int32_t sprite_index) { + fbb_.AddElement(FireflyData::VT_SPRITE_INDEX, sprite_index, 0); + } + void add_sprite_id(int32_t sprite_id) { + fbb_.AddElement(FireflyData::VT_SPRITE_ID, sprite_id, 0); + } + void add_blend_mode(int32_t blend_mode) { + fbb_.AddElement(FireflyData::VT_BLEND_MODE, blend_mode, 0); + } + void add_scalar(int32_t scalar) { + fbb_.AddElement(FireflyData::VT_SCALAR, scalar, 0); + } + void add_position(const TEN::Save::Vector3 *position) { + fbb_.AddStruct(FireflyData::VT_POSITION, position); + } + void add_room_number(int32_t room_number) { + fbb_.AddElement(FireflyData::VT_ROOM_NUMBER, room_number, 0); + } + void add_position_target(const TEN::Save::Vector3 *position_target) { + fbb_.AddStruct(FireflyData::VT_POSITION_TARGET, position_target); + } + void add_orientation(const TEN::Save::EulerAngles *orientation) { + fbb_.AddStruct(FireflyData::VT_ORIENTATION, orientation); + } + void add_velocity(float velocity) { + fbb_.AddElement(FireflyData::VT_VELOCITY, velocity, 0.0f); + } + void add_target_item_number(int32_t target_item_number) { + fbb_.AddElement(FireflyData::VT_TARGET_ITEM_NUMBER, target_item_number, 0); + } + void add_z_vel(float z_vel) { + fbb_.AddElement(FireflyData::VT_Z_VEL, z_vel, 0.0f); + } + void add_life(float life) { + fbb_.AddElement(FireflyData::VT_LIFE, life, 0.0f); + } + void add_number(int32_t number) { + fbb_.AddElement(FireflyData::VT_NUMBER, number, 0); + } + void add_d_r(int32_t d_r) { + fbb_.AddElement(FireflyData::VT_D_R, d_r, 0); + } + void add_d_g(int32_t d_g) { + fbb_.AddElement(FireflyData::VT_D_G, d_g, 0); + } + void add_d_b(int32_t d_b) { + fbb_.AddElement(FireflyData::VT_D_B, d_b, 0); + } + void add_r(int32_t r) { + fbb_.AddElement(FireflyData::VT_R, r, 0); + } + void add_g(int32_t g) { + fbb_.AddElement(FireflyData::VT_G, g, 0); + } + void add_b(int32_t b) { + fbb_.AddElement(FireflyData::VT_B, b, 0); + } + void add_on(bool on) { + fbb_.AddElement(FireflyData::VT_ON, static_cast(on), 0); + } + void add_size(float size) { + fbb_.AddElement(FireflyData::VT_SIZE, size, 0.0f); + } + void add_rot_Ang(int32_t rot_Ang) { + fbb_.AddElement(FireflyData::VT_ROT_ANG, rot_Ang, 0); + } + explicit FireflyDataBuilder(flatbuffers::FlatBufferBuilder &_fbb) + : fbb_(_fbb) { + start_ = fbb_.StartTable(); + } + flatbuffers::Offset Finish() { + const auto end = fbb_.EndTable(start_); + auto o = flatbuffers::Offset(end); + return o; + } +}; + +inline flatbuffers::Offset CreateFireflyData( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t sprite_index = 0, + int32_t sprite_id = 0, + int32_t blend_mode = 0, + int32_t scalar = 0, + const TEN::Save::Vector3 *position = 0, + int32_t room_number = 0, + const TEN::Save::Vector3 *position_target = 0, + const TEN::Save::EulerAngles *orientation = 0, + float velocity = 0.0f, + int32_t target_item_number = 0, + float z_vel = 0.0f, + float life = 0.0f, + int32_t number = 0, + int32_t d_r = 0, + int32_t d_g = 0, + int32_t d_b = 0, + int32_t r = 0, + int32_t g = 0, + int32_t b = 0, + bool on = false, + float size = 0.0f, + int32_t rot_Ang = 0) { + FireflyDataBuilder builder_(_fbb); + builder_.add_rot_Ang(rot_Ang); + builder_.add_size(size); + builder_.add_b(b); + builder_.add_g(g); + builder_.add_r(r); + builder_.add_d_b(d_b); + builder_.add_d_g(d_g); + builder_.add_d_r(d_r); + builder_.add_number(number); + builder_.add_life(life); + builder_.add_z_vel(z_vel); + builder_.add_target_item_number(target_item_number); + builder_.add_velocity(velocity); + builder_.add_orientation(orientation); + builder_.add_position_target(position_target); + builder_.add_room_number(room_number); + builder_.add_position(position); + builder_.add_scalar(scalar); + builder_.add_blend_mode(blend_mode); + builder_.add_sprite_id(sprite_id); + builder_.add_sprite_index(sprite_index); + builder_.add_on(on); + return builder_.Finish(); +} + +struct FireflyData::Traits { + using type = FireflyData; + static auto constexpr Create = CreateFireflyData; +}; + +flatbuffers::Offset CreateFireflyData(flatbuffers::FlatBufferBuilder &_fbb, const FireflyDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct ScriptTableT : public flatbuffers::NativeTable { typedef ScriptTable TableType; std::vector keys_vals{}; @@ -8000,6 +8293,7 @@ struct SaveGameT : public flatbuffers::NativeTable { int32_t next_item_active = 0; std::vector room_items{}; std::vector> fish_swarm{}; + std::vector> firefly_swarm{}; std::vector> fxinfos{}; int32_t next_fx_free = 0; int32_t next_fx_active = 0; @@ -8066,52 +8360,53 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_NEXT_ITEM_ACTIVE = 24, VT_ROOM_ITEMS = 26, VT_FISH_SWARM = 28, - VT_FXINFOS = 30, - VT_NEXT_FX_FREE = 32, - VT_NEXT_FX_ACTIVE = 34, - VT_FIXED_CAMERAS = 36, - VT_SINKS = 38, - VT_STATIC_MESHES = 40, - VT_FLYBY_CAMERAS = 42, - VT_PARTICLES = 44, - VT_RATS = 46, - VT_SPIDERS = 48, - VT_SCARABS = 50, - VT_BATS = 52, - VT_FLIP_MAPS = 54, - VT_FLIP_STATS = 56, - VT_FLIP_EFFECT = 58, - VT_FLIP_TIMER = 60, - VT_FLIP_STATUS = 62, - VT_CURRENT_FOV = 64, - VT_LAST_INV_ITEM = 66, - VT_ACTION_QUEUE = 68, - VT_SOUNDTRACKS = 70, - VT_CD_FLAGS = 72, - VT_POSTPROCESS_MODE = 74, - VT_POSTPROCESS_STRENGTH = 76, - VT_POSTPROCESS_TINT = 78, - VT_ROPE = 80, - VT_PENDULUM = 82, - VT_ALTERNATE_PENDULUM = 84, - VT_VOLUMES = 86, - VT_GLOBAL_EVENT_SETS = 88, - VT_VOLUME_EVENT_SETS = 90, - VT_SCRIPT_VARS = 92, - VT_CALLBACKS_PRE_START = 94, - VT_CALLBACKS_POST_START = 96, - VT_CALLBACKS_PRE_END = 98, - VT_CALLBACKS_POST_END = 100, - VT_CALLBACKS_PRE_SAVE = 102, - VT_CALLBACKS_POST_SAVE = 104, - VT_CALLBACKS_PRE_LOAD = 106, - VT_CALLBACKS_POST_LOAD = 108, - VT_CALLBACKS_PRE_LOOP = 110, - VT_CALLBACKS_POST_LOOP = 112, - VT_CALLBACKS_PRE_USEITEM = 114, - VT_CALLBACKS_POST_USEITEM = 116, - VT_CALLBACKS_PRE_FREEZE = 118, - VT_CALLBACKS_POST_FREEZE = 120 + VT_FIREFLY_SWARM = 30, + VT_FXINFOS = 32, + VT_NEXT_FX_FREE = 34, + VT_NEXT_FX_ACTIVE = 36, + VT_FIXED_CAMERAS = 38, + VT_SINKS = 40, + VT_STATIC_MESHES = 42, + VT_FLYBY_CAMERAS = 44, + VT_PARTICLES = 46, + VT_RATS = 48, + VT_SPIDERS = 50, + VT_SCARABS = 52, + VT_BATS = 54, + VT_FLIP_MAPS = 56, + VT_FLIP_STATS = 58, + VT_FLIP_EFFECT = 60, + VT_FLIP_TIMER = 62, + VT_FLIP_STATUS = 64, + VT_CURRENT_FOV = 66, + VT_LAST_INV_ITEM = 68, + VT_ACTION_QUEUE = 70, + VT_SOUNDTRACKS = 72, + VT_CD_FLAGS = 74, + VT_POSTPROCESS_MODE = 76, + VT_POSTPROCESS_STRENGTH = 78, + VT_POSTPROCESS_TINT = 80, + VT_ROPE = 82, + VT_PENDULUM = 84, + VT_ALTERNATE_PENDULUM = 86, + VT_VOLUMES = 88, + VT_GLOBAL_EVENT_SETS = 90, + VT_VOLUME_EVENT_SETS = 92, + VT_SCRIPT_VARS = 94, + VT_CALLBACKS_PRE_START = 96, + VT_CALLBACKS_POST_START = 98, + VT_CALLBACKS_PRE_END = 100, + VT_CALLBACKS_POST_END = 102, + VT_CALLBACKS_PRE_SAVE = 104, + VT_CALLBACKS_POST_SAVE = 106, + VT_CALLBACKS_PRE_LOAD = 108, + VT_CALLBACKS_POST_LOAD = 110, + VT_CALLBACKS_PRE_LOOP = 112, + VT_CALLBACKS_POST_LOOP = 114, + VT_CALLBACKS_PRE_USEITEM = 116, + VT_CALLBACKS_POST_USEITEM = 118, + VT_CALLBACKS_PRE_FREEZE = 120, + VT_CALLBACKS_POST_FREEZE = 122 }; const TEN::Save::SaveGameHeader *header() const { return GetPointer(VT_HEADER); @@ -8152,6 +8447,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector> *fish_swarm() const { return GetPointer> *>(VT_FISH_SWARM); } + const flatbuffers::Vector> *firefly_swarm() const { + return GetPointer> *>(VT_FIREFLY_SWARM); + } const flatbuffers::Vector> *fxinfos() const { return GetPointer> *>(VT_FXINFOS); } @@ -8318,6 +8616,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyOffset(verifier, VT_FISH_SWARM) && verifier.VerifyVector(fish_swarm()) && verifier.VerifyVectorOfTables(fish_swarm()) && + VerifyOffset(verifier, VT_FIREFLY_SWARM) && + verifier.VerifyVector(firefly_swarm()) && + verifier.VerifyVectorOfTables(firefly_swarm()) && VerifyOffset(verifier, VT_FXINFOS) && verifier.VerifyVector(fxinfos()) && verifier.VerifyVectorOfTables(fxinfos()) && @@ -8478,6 +8779,9 @@ struct SaveGameBuilder { void add_fish_swarm(flatbuffers::Offset>> fish_swarm) { fbb_.AddOffset(SaveGame::VT_FISH_SWARM, fish_swarm); } + void add_firefly_swarm(flatbuffers::Offset>> firefly_swarm) { + fbb_.AddOffset(SaveGame::VT_FIREFLY_SWARM, firefly_swarm); + } void add_fxinfos(flatbuffers::Offset>> fxinfos) { fbb_.AddOffset(SaveGame::VT_FXINFOS, fxinfos); } @@ -8642,6 +8946,7 @@ inline flatbuffers::Offset CreateSaveGame( int32_t next_item_active = 0, flatbuffers::Offset> room_items = 0, flatbuffers::Offset>> fish_swarm = 0, + flatbuffers::Offset>> firefly_swarm = 0, flatbuffers::Offset>> fxinfos = 0, int32_t next_fx_free = 0, int32_t next_fx_active = 0, @@ -8734,6 +9039,7 @@ inline flatbuffers::Offset CreateSaveGame( builder_.add_next_fx_active(next_fx_active); builder_.add_next_fx_free(next_fx_free); builder_.add_fxinfos(fxinfos); + builder_.add_firefly_swarm(firefly_swarm); builder_.add_fish_swarm(fish_swarm); builder_.add_room_items(room_items); builder_.add_next_item_active(next_item_active); @@ -8771,6 +9077,7 @@ inline flatbuffers::Offset CreateSaveGameDirect( int32_t next_item_active = 0, const std::vector *room_items = nullptr, const std::vector> *fish_swarm = nullptr, + const std::vector> *firefly_swarm = nullptr, const std::vector> *fxinfos = nullptr, int32_t next_fx_free = 0, int32_t next_fx_active = 0, @@ -8821,6 +9128,7 @@ inline flatbuffers::Offset CreateSaveGameDirect( auto items__ = items ? _fbb.CreateVector>(*items) : 0; auto room_items__ = room_items ? _fbb.CreateVector(*room_items) : 0; auto fish_swarm__ = fish_swarm ? _fbb.CreateVector>(*fish_swarm) : 0; + auto firefly_swarm__ = firefly_swarm ? _fbb.CreateVector>(*firefly_swarm) : 0; auto fxinfos__ = fxinfos ? _fbb.CreateVector>(*fxinfos) : 0; auto fixed_cameras__ = fixed_cameras ? _fbb.CreateVector>(*fixed_cameras) : 0; auto sinks__ = sinks ? _fbb.CreateVector>(*sinks) : 0; @@ -8868,6 +9176,7 @@ inline flatbuffers::Offset CreateSaveGameDirect( next_item_active, room_items__, fish_swarm__, + firefly_swarm__, fxinfos__, next_fx_free, next_fx_active, @@ -10889,6 +11198,95 @@ inline flatbuffers::Offset CreateFishData(flatbuffers::FlatBufferBuild _velocity); } +inline FireflyDataT *FireflyData::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::make_unique(); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void FireflyData::UnPackTo(FireflyDataT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = sprite_index(); _o->sprite_index = _e; } + { auto _e = sprite_id(); _o->sprite_id = _e; } + { auto _e = blend_mode(); _o->blend_mode = _e; } + { auto _e = scalar(); _o->scalar = _e; } + { auto _e = position(); if (_e) _o->position = std::unique_ptr(new TEN::Save::Vector3(*_e)); } + { auto _e = room_number(); _o->room_number = _e; } + { auto _e = position_target(); if (_e) _o->position_target = std::unique_ptr(new TEN::Save::Vector3(*_e)); } + { auto _e = orientation(); if (_e) _o->orientation = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } + { auto _e = velocity(); _o->velocity = _e; } + { auto _e = target_item_number(); _o->target_item_number = _e; } + { auto _e = z_vel(); _o->z_vel = _e; } + { auto _e = life(); _o->life = _e; } + { auto _e = number(); _o->number = _e; } + { auto _e = d_r(); _o->d_r = _e; } + { auto _e = d_g(); _o->d_g = _e; } + { auto _e = d_b(); _o->d_b = _e; } + { auto _e = r(); _o->r = _e; } + { auto _e = g(); _o->g = _e; } + { auto _e = b(); _o->b = _e; } + { auto _e = on(); _o->on = _e; } + { auto _e = size(); _o->size = _e; } + { auto _e = rot_Ang(); _o->rot_Ang = _e; } +} + +inline flatbuffers::Offset FireflyData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const FireflyDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateFireflyData(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateFireflyData(flatbuffers::FlatBufferBuilder &_fbb, const FireflyDataT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const FireflyDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _sprite_index = _o->sprite_index; + auto _sprite_id = _o->sprite_id; + auto _blend_mode = _o->blend_mode; + auto _scalar = _o->scalar; + auto _position = _o->position ? _o->position.get() : 0; + auto _room_number = _o->room_number; + auto _position_target = _o->position_target ? _o->position_target.get() : 0; + auto _orientation = _o->orientation ? _o->orientation.get() : 0; + auto _velocity = _o->velocity; + auto _target_item_number = _o->target_item_number; + auto _z_vel = _o->z_vel; + auto _life = _o->life; + auto _number = _o->number; + auto _d_r = _o->d_r; + auto _d_g = _o->d_g; + auto _d_b = _o->d_b; + auto _r = _o->r; + auto _g = _o->g; + auto _b = _o->b; + auto _on = _o->on; + auto _size = _o->size; + auto _rot_Ang = _o->rot_Ang; + return TEN::Save::CreateFireflyData( + _fbb, + _sprite_index, + _sprite_id, + _blend_mode, + _scalar, + _position, + _room_number, + _position_target, + _orientation, + _velocity, + _target_item_number, + _z_vel, + _life, + _number, + _d_r, + _d_g, + _d_b, + _r, + _g, + _b, + _on, + _size, + _rot_Ang); +} + inline ScriptTableT *ScriptTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = std::make_unique(); UnPackTo(_o.get(), _resolver); @@ -11323,6 +11721,7 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi { auto _e = next_item_active(); _o->next_item_active = _e; } { auto _e = room_items(); if (_e) { _o->room_items.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->room_items[_i] = _e->Get(_i); } } } { auto _e = fish_swarm(); if (_e) { _o->fish_swarm.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fish_swarm[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } + { auto _e = firefly_swarm(); if (_e) { _o->firefly_swarm.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->firefly_swarm[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = fxinfos(); if (_e) { _o->fxinfos.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->fxinfos[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = next_fx_free(); _o->next_fx_free = _e; } { auto _e = next_fx_active(); _o->next_fx_active = _e; } @@ -11392,6 +11791,7 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild auto _next_item_active = _o->next_item_active; auto _room_items = _fbb.CreateVector(_o->room_items); auto _fish_swarm = _fbb.CreateVector> (_o->fish_swarm.size(), [](size_t i, _VectorArgs *__va) { return CreateFishData(*__va->__fbb, __va->__o->fish_swarm[i].get(), __va->__rehasher); }, &_va ); + auto _firefly_swarm = _fbb.CreateVector> (_o->firefly_swarm.size(), [](size_t i, _VectorArgs *__va) { return CreateFireflyData(*__va->__fbb, __va->__o->firefly_swarm[i].get(), __va->__rehasher); }, &_va ); auto _fxinfos = _fbb.CreateVector> (_o->fxinfos.size(), [](size_t i, _VectorArgs *__va) { return CreateFXInfo(*__va->__fbb, __va->__o->fxinfos[i].get(), __va->__rehasher); }, &_va ); auto _next_fx_free = _o->next_fx_free; auto _next_fx_active = _o->next_fx_active; @@ -11453,6 +11853,7 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild _next_item_active, _room_items, _fish_swarm, + _firefly_swarm, _fxinfos, _next_fx_free, _next_fx_active, diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs index b4e852148..bc41d27be 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -499,6 +499,31 @@ table FishData { velocity: float; } +table FireflyData { + sprite_index: int32; + sprite_id: int32; + blend_mode: int32; + scalar: int32; + position: Vector3; + room_number: int32; + position_target: Vector3; + orientation: EulerAngles; + velocity: float; + target_item_number: int32; + z_vel: float; + life: float; + number: int32; + d_r: int32; + d_g: int32; + d_b: int32; + r: int32; + g: int32; + b: int32; + on: bool; + size: float; + rot_Ang: int32; +} + struct KeyValPair { key: uint32; val: uint32; @@ -602,6 +627,7 @@ table SaveGame { next_item_active: int32; room_items: [int32]; fish_swarm: [FishData]; + firefly_swarm: [FireflyData]; fxinfos: [FXInfo]; next_fx_free: int32; next_fx_active: int32; diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index 19ff7ecfb..64841e2e1 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -506,6 +506,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + @@ -1044,6 +1045,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. + From 7ba93702818ebb86abd94271326b499de7a79075 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 28 Mar 2025 07:11:04 +0100 Subject: [PATCH 19/53] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4e17ee3ae..7f1ceec64 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.8.1](link to release) - yyyy-mm-dd ### New features +* Added Firefly Emitter object (ID 1099) with corresponding sprite slot (ID 1379). * Added live console input to perform Lua commands in realtime. ### Bug fixes From 9fc370833bf3c43127fa250bb86413853123b715 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 28 Mar 2025 21:36:37 +0100 Subject: [PATCH 20/53] Implement flyby spline looping in lua API --- CHANGELOG.md | 1 + Documentation/doc/1 modules/View.html | 18 ++++++-- TombEngine/Game/spotcam.cpp | 44 +++++++++++++++---- TombEngine/Game/spotcam.h | 2 +- .../Internal/TEN/View/ViewHandler.cpp | 10 +++-- 5 files changed, 58 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7f1ceec64..3d47c249b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ### Lua API changes * Added missing constructor for `Collision.Probe` without room number. +* Added optional looping argument for `View.GetFlybyPosition` and `View.GetFlybyRotation` functions. ## [Version 1.8](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8) - 2025-03-16 diff --git a/Documentation/doc/1 modules/View.html b/Documentation/doc/1 modules/View.html index f1725ceb1..40f491a7b 100644 --- a/Documentation/doc/1 modules/View.html +++ b/Documentation/doc/1 modules/View.html @@ -176,11 +176,11 @@ Play a flyby sequence. - GetFlybyPosition(seqID, progress) + GetFlybyPosition(seqID, progress[, loop]) Get a flyby sequence's position at a specified progress point in percent. - GetFlybyRotation(seqID, progress) + GetFlybyRotation(seqID, progress[, loop]) Get a flyby sequence's rotation at a specified progress point in percent. @@ -499,7 +499,7 @@
- GetFlybyPosition(seqID, progress) + GetFlybyPosition(seqID, progress[, loop])
Get a flyby sequence's position at a specified progress point in percent. @@ -516,6 +516,11 @@ float Progress point in percent. Clamped to [0, 100]. +
  • loop + bool + Smooth the position near start and end points, as if the sequence is looped. + (optional) +
  • Returns:

    @@ -531,7 +536,7 @@
    - GetFlybyRotation(seqID, progress) + GetFlybyRotation(seqID, progress[, loop])
    Get a flyby sequence's rotation at a specified progress point in percent. @@ -548,6 +553,11 @@ float Progress point in percent. Clamped to [0, 100]. +
  • loop + bool + Smooth the position near start and end points, as if the sequence is looped. + (optional) +
  • Returns:

    diff --git a/TombEngine/Game/spotcam.cpp b/TombEngine/Game/spotcam.cpp index ffa8be942..2b6ea8d10 100644 --- a/TombEngine/Game/spotcam.cpp +++ b/TombEngine/Game/spotcam.cpp @@ -839,7 +839,7 @@ int Spline(int x, int* knots, int nk) return ((__int64)x * (((__int64)x * (((__int64)x * c1 >> 16) + c2) >> 16) + (k[2] >> 1) + ((-k[0] - 1) >> 1)) >> 16) + k[1]; } -Pose GetCameraTransform(int sequence, float alpha) +Pose GetCameraTransform(int sequence, float alpha, bool loop) { alpha = std::clamp(alpha, 0.0f, 1.0f); @@ -873,15 +873,43 @@ Pose GetCameraTransform(int sequence, float alpha) } // Compute spline interpolation of main flyby camera parameters. - auto origin = Vector3(Spline(splineAlpha, xOrigins.data(), splinePoints), - Spline(splineAlpha, yOrigins.data(), splinePoints), - Spline(splineAlpha, zOrigins.data(), splinePoints)); + auto getInterpolatedPoint = [&](float t, std::vector& x, std::vector& y, std::vector& z) + { + int tAlpha = int(t * (float)USHRT_MAX); + return Vector3(Spline(tAlpha, x.data(), splinePoints), + Spline(tAlpha, y.data(), splinePoints), + Spline(tAlpha, z.data(), splinePoints)); + }; - auto target = Vector3(Spline(splineAlpha, xTargets.data(), splinePoints), - Spline(splineAlpha, yTargets.data(), splinePoints), - Spline(splineAlpha, zTargets.data(), splinePoints)); + auto getInterpolatedRoll = [&](float t) + { + int tAlpha = int(t * (float)USHRT_MAX); + return Spline(tAlpha, rolls.data(), splinePoints); + }; - short orientZ = Spline(splineAlpha, rolls.data(), splinePoints); + Vector3 origin = {}; + Vector3 target = {}; + short orientZ = 0; + + constexpr float BLEND_RANGE = 0.1f; + constexpr float BLEND_START = BLEND_RANGE; + constexpr float BLEND_END = 1.0f - BLEND_RANGE; + + // If loop is enabled and we are at the start or end of the sequence, blend between the last and first cameras. + if (loop && (alpha < BLEND_START || alpha >= BLEND_END)) + { + float blendFactor = (alpha < BLEND_START) ? 0.5f + (alpha / BLEND_RANGE) * 0.5f : (alpha - BLEND_END) / BLEND_START * 0.5f; + + origin = Vector3::Lerp(getInterpolatedPoint(BLEND_END, xOrigins, yOrigins, zOrigins), getInterpolatedPoint(BLEND_START, xOrigins, yOrigins, zOrigins), blendFactor); + target = Vector3::Lerp(getInterpolatedPoint(BLEND_END, xTargets, yTargets, zTargets), getInterpolatedPoint(BLEND_START, xTargets, yTargets, zTargets), blendFactor); + orientZ = Lerp(getInterpolatedRoll(BLEND_END), getInterpolatedRoll(BLEND_START), blendFactor); + } + else + { + origin = getInterpolatedPoint(alpha, xOrigins, yOrigins, zOrigins); + target = getInterpolatedPoint(alpha, xTargets, yTargets, zTargets); + orientZ = getInterpolatedRoll(alpha); + } auto pose = Pose(origin, EulerAngles(target - origin)); pose.Orientation.z = orientZ; diff --git a/TombEngine/Game/spotcam.h b/TombEngine/Game/spotcam.h index 035929e93..07917c26d 100644 --- a/TombEngine/Game/spotcam.h +++ b/TombEngine/Game/spotcam.h @@ -64,4 +64,4 @@ void InitializeSpotCam(short sequence); void CalculateSpotCameras(); int Spline(int x, int* knots, int nk); -Pose GetCameraTransform(int sequence, float alpha); +Pose GetCameraTransform(int sequence, float alpha, bool loop); diff --git a/TombEngine/Scripting/Internal/TEN/View/ViewHandler.cpp b/TombEngine/Scripting/Internal/TEN/View/ViewHandler.cpp index 501784af1..8076215b2 100644 --- a/TombEngine/Scripting/Internal/TEN/View/ViewHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/View/ViewHandler.cpp @@ -111,18 +111,18 @@ namespace TEN::Scripting::View InitializeSpotCam(seqID); } - static Vec3 GetFlybyPosition(int seqID, float progress) + static Vec3 GetFlybyPosition(int seqID, float progress, TypeOrNil loop) { constexpr auto PROGRESS_MAX = 100.0f; - return Vec3(GetCameraTransform(seqID, progress / PROGRESS_MAX).Position); + return Vec3(GetCameraTransform(seqID, progress / PROGRESS_MAX, ValueOr(loop, false)).Position); } - static Rotation GetFlybyRotation(int seqID, float progress) + static Rotation GetFlybyRotation(int seqID, float progress, TypeOrNil loop) { constexpr auto PROGRESS_MAX = 100.0f; - return Rotation(GetCameraTransform(seqID, progress / PROGRESS_MAX).Orientation); + return Rotation(GetCameraTransform(seqID, progress / PROGRESS_MAX, ValueOr(loop, false)).Orientation); } static void FlashScreen(TypeOrNil col, TypeOrNil speed) @@ -244,6 +244,7 @@ namespace TEN::Scripting::View // @function GetFlybyPosition // @tparam int seqID Flyby sequence ID. // @tparam float progress Progress point in percent. Clamped to [0, 100]. + // @tparam[opt] bool loop Smooth the position near start and end points, as if the sequence is looped. // @treturn Vec3 Position at the given progress point. tableView.set_function(ScriptReserved_GetFlybyPosition, &GetFlybyPosition); @@ -251,6 +252,7 @@ namespace TEN::Scripting::View // @function GetFlybyRotation // @tparam int seqID Flyby sequence ID. // @tparam float progress Progress point in percent. Clamped to [0, 100]. + // @tparam[opt] bool loop Smooth the position near start and end points, as if the sequence is looped. // @treturn Rotation Rotation at the given progress point. tableView.set_function(ScriptReserved_GetFlybyRotation, &GetFlybyRotation); From d4c8b72bbe0a31bbe6dd238fedfc7fd5ecfa88a5 Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Fri, 28 Mar 2025 21:37:07 +0000 Subject: [PATCH 21/53] Test commit for Discord --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d47c249b..0a92d6d75 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.8.1](link to release) - yyyy-mm-dd ### New features -* Added Firefly Emitter object (ID 1099) with corresponding sprite slot (ID 1379). +* Added Firefly Emitter object (ID 1099) with corresponding sprite slots (ID 1379). * Added live console input to perform Lua commands in realtime. ### Bug fixes From 83f71eaf3bb471d3b7f733b211c5d99a5a1f0159 Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Fri, 28 Mar 2025 21:39:40 +0000 Subject: [PATCH 22/53] Revert "Test commit for Discord" This reverts commit d4c8b72bbe0a31bbe6dd238fedfc7fd5ecfa88a5. --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a92d6d75..3d47c249b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ## [Version 1.8.1](link to release) - yyyy-mm-dd ### New features -* Added Firefly Emitter object (ID 1099) with corresponding sprite slots (ID 1379). +* Added Firefly Emitter object (ID 1099) with corresponding sprite slot (ID 1379). * Added live console input to perform Lua commands in realtime. ### Bug fixes From 74b7688c7b777bb742c7c21b78aa804a3b0647e2 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:23:43 +0100 Subject: [PATCH 23/53] Update Settings.lua --- Scripts/Settings.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Scripts/Settings.lua b/Scripts/Settings.lua index 75981eaf7..989c44f8e 100644 --- a/Scripts/Settings.lua +++ b/Scripts/Settings.lua @@ -19,7 +19,7 @@ local settings = Flow.Settings.new() settings.Flare.offset = Vec3(0, 0, 41) settings.Flare.range = 9 settings.Flare.timeout = 60 - settings.Flare.lensflareBrightness = 0.5 + settings.Flare.lensflareBrightness = 1.0 settings.Flare.sparks = true settings.Flare.smoke = true settings.Flare.flicker = true @@ -35,6 +35,7 @@ local settings = Flow.Settings.new() settings.System.errorMode = Flow.ErrorMode.WARN settings.System.fastReload = true + settings.System.multithreaded = true -- Hair[1] is normal player hair. Types [2] and [3] are for left and right young Lara hair. From 3e2a1ccf379f6ff16352d25687424ed2e13db4a4 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 28 Mar 2025 23:39:49 +0100 Subject: [PATCH 24/53] Update documentation --- Documentation/config.ld | 2 +- Documentation/doc/1 modules/Effects.html | 2 +- Documentation/doc/1 modules/Flow.html | 2 +- Documentation/doc/1 modules/Input.html | 2 +- Documentation/doc/1 modules/Inventory.html | 2 +- Documentation/doc/1 modules/Logic.html | 2 +- Documentation/doc/1 modules/Objects.html | 2 +- Documentation/doc/1 modules/Sound.html | 2 +- Documentation/doc/1 modules/Strings.html | 2 +- Documentation/doc/1 modules/Util.html | 2 +- Documentation/doc/1 modules/View.html | 2 +- Documentation/doc/2 classes/Collision.Probe.html | 2 +- Documentation/doc/2 classes/Flow.Level.html | 2 +- Documentation/doc/2 classes/Flow.Settings.html | 2 +- Documentation/doc/2 classes/Flow.Statistics.html | 2 +- Documentation/doc/2 classes/Objects.AIObject.html | 2 +- Documentation/doc/2 classes/Objects.Camera.html | 2 +- Documentation/doc/2 classes/Objects.LaraObject.html | 2 +- Documentation/doc/2 classes/Objects.Moveable.html | 2 +- Documentation/doc/2 classes/Objects.Room.html | 2 +- Documentation/doc/2 classes/Objects.Sink.html | 2 +- Documentation/doc/2 classes/Objects.SoundSource.html | 2 +- Documentation/doc/2 classes/Objects.Static.html | 2 +- Documentation/doc/2 classes/Objects.Volume.html | 2 +- Documentation/doc/2 classes/Strings.DisplayString.html | 2 +- Documentation/doc/2 classes/View.DisplaySprite.html | 2 +- Documentation/doc/3 primitive classes/Color.html | 2 +- Documentation/doc/3 primitive classes/Flow.Fog.html | 2 +- Documentation/doc/3 primitive classes/Flow.Horizon.html | 2 +- Documentation/doc/3 primitive classes/Flow.InventoryItem.html | 2 +- Documentation/doc/3 primitive classes/Flow.LensFlare.html | 2 +- Documentation/doc/3 primitive classes/Flow.SkyLayer.html | 2 +- Documentation/doc/3 primitive classes/Flow.Starfield.html | 2 +- Documentation/doc/3 primitive classes/Rotation.html | 2 +- Documentation/doc/3 primitive classes/Time.html | 2 +- Documentation/doc/3 primitive classes/Vec2.html | 2 +- Documentation/doc/3 primitive classes/Vec3.html | 2 +- Documentation/doc/4 enums/Collision.MaterialType.html | 2 +- Documentation/doc/4 enums/Effects.BlendID.html | 2 +- Documentation/doc/4 enums/Effects.EffectID.html | 2 +- Documentation/doc/4 enums/Effects.ParticleAnimationType.html | 2 +- Documentation/doc/4 enums/Effects.StreamerFeatherMode.html | 2 +- Documentation/doc/4 enums/Flow.ErrorMode.html | 2 +- Documentation/doc/4 enums/Flow.FreezeMode.html | 2 +- Documentation/doc/4 enums/Flow.GameStatus.html | 2 +- Documentation/doc/4 enums/Input.ActionID.html | 2 +- Documentation/doc/4 enums/Objects.AmmoType.html | 2 +- Documentation/doc/4 enums/Objects.HandStatus.html | 2 +- Documentation/doc/4 enums/Objects.MoveableStatus.html | 2 +- Documentation/doc/4 enums/Objects.ObjID.html | 2 +- Documentation/doc/4 enums/Objects.RoomFlagID.html | 2 +- Documentation/doc/4 enums/Objects.RoomReverb.html | 2 +- Documentation/doc/4 enums/Objects.WeaponType.html | 2 +- Documentation/doc/4 enums/Sound.SoundTrackType.html | 2 +- Documentation/doc/4 enums/Strings.DisplayStringOption.html | 2 +- Documentation/doc/4 enums/Util.LogLevel.html | 2 +- Documentation/doc/4 enums/View.AlignMode.html | 2 +- Documentation/doc/4 enums/View.CameraType.html | 2 +- Documentation/doc/4 enums/View.PostProcessMode.html | 2 +- Documentation/doc/4 enums/View.ScaleMode.html | 2 +- Documentation/doc/5 lua utility modules/CustomBar.html | 2 +- Documentation/doc/5 lua utility modules/Diary.html | 2 +- Documentation/doc/5 lua utility modules/EventSequence.html | 2 +- Documentation/doc/5 lua utility modules/Timer.html | 2 +- Documentation/doc/5 lua utility modules/Type.html | 2 +- Documentation/doc/index.html | 4 ++-- 66 files changed, 67 insertions(+), 67 deletions(-) diff --git a/Documentation/config.ld b/Documentation/config.ld index abc23eb0c..6a3876d25 100644 --- a/Documentation/config.ld +++ b/Documentation/config.ld @@ -12,7 +12,7 @@ new_type("luautil", "5 Lua utility modules", true) not_luadoc = true -local version = "1.8" +local version = "1.8.1" project = " TombEngine" title = "TombEngine " .. version .. " Lua API" description = "TombEngine " .. version .. " scripting interface" diff --git a/Documentation/doc/1 modules/Effects.html b/Documentation/doc/1 modules/Effects.html index 1ba87f3f0..d8d58667e 100644 --- a/Documentation/doc/1 modules/Effects.html +++ b/Documentation/doc/1 modules/Effects.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index 9ca9202e8..a8ae0a9b0 100644 --- a/Documentation/doc/1 modules/Flow.html +++ b/Documentation/doc/1 modules/Flow.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Input.html b/Documentation/doc/1 modules/Input.html index 789bad1c6..c3439c75c 100644 --- a/Documentation/doc/1 modules/Input.html +++ b/Documentation/doc/1 modules/Input.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index 14f4f6be5..45a377928 100644 --- a/Documentation/doc/1 modules/Inventory.html +++ b/Documentation/doc/1 modules/Inventory.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index 83b919387..dff8277a1 100644 --- a/Documentation/doc/1 modules/Logic.html +++ b/Documentation/doc/1 modules/Logic.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Objects.html b/Documentation/doc/1 modules/Objects.html index 1e77c2f79..06d84e7c1 100644 --- a/Documentation/doc/1 modules/Objects.html +++ b/Documentation/doc/1 modules/Objects.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Sound.html b/Documentation/doc/1 modules/Sound.html index d7c87bb04..6f1305b02 100644 --- a/Documentation/doc/1 modules/Sound.html +++ b/Documentation/doc/1 modules/Sound.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html index d5aaeda4a..16b10bee4 100644 --- a/Documentation/doc/1 modules/Strings.html +++ b/Documentation/doc/1 modules/Strings.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/Util.html b/Documentation/doc/1 modules/Util.html index cc0443c3d..a9b7c3972 100644 --- a/Documentation/doc/1 modules/Util.html +++ b/Documentation/doc/1 modules/Util.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/1 modules/View.html b/Documentation/doc/1 modules/View.html index 40f491a7b..557e35756 100644 --- a/Documentation/doc/1 modules/View.html +++ b/Documentation/doc/1 modules/View.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Collision.Probe.html b/Documentation/doc/2 classes/Collision.Probe.html index 4ff672202..19c7f4ec2 100644 --- a/Documentation/doc/2 classes/Collision.Probe.html +++ b/Documentation/doc/2 classes/Collision.Probe.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html index 0060d532e..c7c23ab6b 100644 --- a/Documentation/doc/2 classes/Flow.Level.html +++ b/Documentation/doc/2 classes/Flow.Level.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index 326b6b4ce..6003f5cdc 100644 --- a/Documentation/doc/2 classes/Flow.Settings.html +++ b/Documentation/doc/2 classes/Flow.Settings.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Flow.Statistics.html b/Documentation/doc/2 classes/Flow.Statistics.html index 0c3663c4b..9cc173115 100644 --- a/Documentation/doc/2 classes/Flow.Statistics.html +++ b/Documentation/doc/2 classes/Flow.Statistics.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.AIObject.html b/Documentation/doc/2 classes/Objects.AIObject.html index 951d0e4d3..0122971a9 100644 --- a/Documentation/doc/2 classes/Objects.AIObject.html +++ b/Documentation/doc/2 classes/Objects.AIObject.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html index 4899f78e0..630d1a44f 100644 --- a/Documentation/doc/2 classes/Objects.Camera.html +++ b/Documentation/doc/2 classes/Objects.Camera.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.LaraObject.html b/Documentation/doc/2 classes/Objects.LaraObject.html index 2b43e2d46..41fefa5bc 100644 --- a/Documentation/doc/2 classes/Objects.LaraObject.html +++ b/Documentation/doc/2 classes/Objects.LaraObject.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index e4152b181..cddc5ebb0 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.Room.html b/Documentation/doc/2 classes/Objects.Room.html index 04cd67ef3..acc0de38b 100644 --- a/Documentation/doc/2 classes/Objects.Room.html +++ b/Documentation/doc/2 classes/Objects.Room.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.Sink.html b/Documentation/doc/2 classes/Objects.Sink.html index 322a09400..54ee6f9de 100644 --- a/Documentation/doc/2 classes/Objects.Sink.html +++ b/Documentation/doc/2 classes/Objects.Sink.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.SoundSource.html b/Documentation/doc/2 classes/Objects.SoundSource.html index 19e05dff7..6daf287f2 100644 --- a/Documentation/doc/2 classes/Objects.SoundSource.html +++ b/Documentation/doc/2 classes/Objects.SoundSource.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.Static.html b/Documentation/doc/2 classes/Objects.Static.html index cddabdcf2..faa84c20f 100644 --- a/Documentation/doc/2 classes/Objects.Static.html +++ b/Documentation/doc/2 classes/Objects.Static.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Objects.Volume.html b/Documentation/doc/2 classes/Objects.Volume.html index af6e4b1ed..77e6b626a 100644 --- a/Documentation/doc/2 classes/Objects.Volume.html +++ b/Documentation/doc/2 classes/Objects.Volume.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html index 005c134f0..d4b209327 100644 --- a/Documentation/doc/2 classes/Strings.DisplayString.html +++ b/Documentation/doc/2 classes/Strings.DisplayString.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/2 classes/View.DisplaySprite.html b/Documentation/doc/2 classes/View.DisplaySprite.html index 1dbe32283..f6f4917b7 100644 --- a/Documentation/doc/2 classes/View.DisplaySprite.html +++ b/Documentation/doc/2 classes/View.DisplaySprite.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html index 9ccc6e9d6..e10a2c8ec 100644 --- a/Documentation/doc/3 primitive classes/Color.html +++ b/Documentation/doc/3 primitive classes/Color.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Flow.Fog.html b/Documentation/doc/3 primitive classes/Flow.Fog.html index 49d245efb..dbf35a6b5 100644 --- a/Documentation/doc/3 primitive classes/Flow.Fog.html +++ b/Documentation/doc/3 primitive classes/Flow.Fog.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Flow.Horizon.html b/Documentation/doc/3 primitive classes/Flow.Horizon.html index c8097d43b..891539543 100644 --- a/Documentation/doc/3 primitive classes/Flow.Horizon.html +++ b/Documentation/doc/3 primitive classes/Flow.Horizon.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Flow.InventoryItem.html b/Documentation/doc/3 primitive classes/Flow.InventoryItem.html index 4daff8cd5..ac66af1ac 100644 --- a/Documentation/doc/3 primitive classes/Flow.InventoryItem.html +++ b/Documentation/doc/3 primitive classes/Flow.InventoryItem.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Flow.LensFlare.html b/Documentation/doc/3 primitive classes/Flow.LensFlare.html index 5f7538fba..493f9432b 100644 --- a/Documentation/doc/3 primitive classes/Flow.LensFlare.html +++ b/Documentation/doc/3 primitive classes/Flow.LensFlare.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Flow.SkyLayer.html b/Documentation/doc/3 primitive classes/Flow.SkyLayer.html index 1289afc53..dc92bbb1d 100644 --- a/Documentation/doc/3 primitive classes/Flow.SkyLayer.html +++ b/Documentation/doc/3 primitive classes/Flow.SkyLayer.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Flow.Starfield.html b/Documentation/doc/3 primitive classes/Flow.Starfield.html index f4aa48998..9182b0b89 100644 --- a/Documentation/doc/3 primitive classes/Flow.Starfield.html +++ b/Documentation/doc/3 primitive classes/Flow.Starfield.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html index 728815250..08d1dedf6 100644 --- a/Documentation/doc/3 primitive classes/Rotation.html +++ b/Documentation/doc/3 primitive classes/Rotation.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Time.html b/Documentation/doc/3 primitive classes/Time.html index c1b159661..1edf989a5 100644 --- a/Documentation/doc/3 primitive classes/Time.html +++ b/Documentation/doc/3 primitive classes/Time.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Vec2.html b/Documentation/doc/3 primitive classes/Vec2.html index 825d7fa48..eb65b2271 100644 --- a/Documentation/doc/3 primitive classes/Vec2.html +++ b/Documentation/doc/3 primitive classes/Vec2.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/3 primitive classes/Vec3.html b/Documentation/doc/3 primitive classes/Vec3.html index 696df8778..5ff74ce81 100644 --- a/Documentation/doc/3 primitive classes/Vec3.html +++ b/Documentation/doc/3 primitive classes/Vec3.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Collision.MaterialType.html b/Documentation/doc/4 enums/Collision.MaterialType.html index 69c90fa69..564b8ca1f 100644 --- a/Documentation/doc/4 enums/Collision.MaterialType.html +++ b/Documentation/doc/4 enums/Collision.MaterialType.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Effects.BlendID.html b/Documentation/doc/4 enums/Effects.BlendID.html index 738be8a6b..bd2f1aca9 100644 --- a/Documentation/doc/4 enums/Effects.BlendID.html +++ b/Documentation/doc/4 enums/Effects.BlendID.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Effects.EffectID.html b/Documentation/doc/4 enums/Effects.EffectID.html index 9b33780a8..32b783f43 100644 --- a/Documentation/doc/4 enums/Effects.EffectID.html +++ b/Documentation/doc/4 enums/Effects.EffectID.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Effects.ParticleAnimationType.html b/Documentation/doc/4 enums/Effects.ParticleAnimationType.html index 82bc18a38..f1351b9af 100644 --- a/Documentation/doc/4 enums/Effects.ParticleAnimationType.html +++ b/Documentation/doc/4 enums/Effects.ParticleAnimationType.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Effects.StreamerFeatherMode.html b/Documentation/doc/4 enums/Effects.StreamerFeatherMode.html index 7415e2354..47692e9c5 100644 --- a/Documentation/doc/4 enums/Effects.StreamerFeatherMode.html +++ b/Documentation/doc/4 enums/Effects.StreamerFeatherMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Flow.ErrorMode.html b/Documentation/doc/4 enums/Flow.ErrorMode.html index 5bab3199b..4bf7d6fab 100644 --- a/Documentation/doc/4 enums/Flow.ErrorMode.html +++ b/Documentation/doc/4 enums/Flow.ErrorMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Flow.FreezeMode.html b/Documentation/doc/4 enums/Flow.FreezeMode.html index d3144922d..d01a30a1a 100644 --- a/Documentation/doc/4 enums/Flow.FreezeMode.html +++ b/Documentation/doc/4 enums/Flow.FreezeMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Flow.GameStatus.html b/Documentation/doc/4 enums/Flow.GameStatus.html index b3ec60f29..0e9262274 100644 --- a/Documentation/doc/4 enums/Flow.GameStatus.html +++ b/Documentation/doc/4 enums/Flow.GameStatus.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Input.ActionID.html b/Documentation/doc/4 enums/Input.ActionID.html index 0d3e1c9ba..b0c16ee50 100644 --- a/Documentation/doc/4 enums/Input.ActionID.html +++ b/Documentation/doc/4 enums/Input.ActionID.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.AmmoType.html b/Documentation/doc/4 enums/Objects.AmmoType.html index 812f506e8..cf02b25c1 100644 --- a/Documentation/doc/4 enums/Objects.AmmoType.html +++ b/Documentation/doc/4 enums/Objects.AmmoType.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.HandStatus.html b/Documentation/doc/4 enums/Objects.HandStatus.html index 06cc70974..5e6f31be9 100644 --- a/Documentation/doc/4 enums/Objects.HandStatus.html +++ b/Documentation/doc/4 enums/Objects.HandStatus.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.MoveableStatus.html b/Documentation/doc/4 enums/Objects.MoveableStatus.html index 9ce6251e0..21ceb56ef 100644 --- a/Documentation/doc/4 enums/Objects.MoveableStatus.html +++ b/Documentation/doc/4 enums/Objects.MoveableStatus.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index b10a91473..87fb56147 100644 --- a/Documentation/doc/4 enums/Objects.ObjID.html +++ b/Documentation/doc/4 enums/Objects.ObjID.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.RoomFlagID.html b/Documentation/doc/4 enums/Objects.RoomFlagID.html index 517ed6b71..3edc7b5ce 100644 --- a/Documentation/doc/4 enums/Objects.RoomFlagID.html +++ b/Documentation/doc/4 enums/Objects.RoomFlagID.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.RoomReverb.html b/Documentation/doc/4 enums/Objects.RoomReverb.html index e8282b8dc..420e1731c 100644 --- a/Documentation/doc/4 enums/Objects.RoomReverb.html +++ b/Documentation/doc/4 enums/Objects.RoomReverb.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Objects.WeaponType.html b/Documentation/doc/4 enums/Objects.WeaponType.html index 219c79085..c45efc459 100644 --- a/Documentation/doc/4 enums/Objects.WeaponType.html +++ b/Documentation/doc/4 enums/Objects.WeaponType.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Sound.SoundTrackType.html b/Documentation/doc/4 enums/Sound.SoundTrackType.html index 359b78984..ad9eb5e39 100644 --- a/Documentation/doc/4 enums/Sound.SoundTrackType.html +++ b/Documentation/doc/4 enums/Sound.SoundTrackType.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Strings.DisplayStringOption.html b/Documentation/doc/4 enums/Strings.DisplayStringOption.html index d561e2684..e43f3200b 100644 --- a/Documentation/doc/4 enums/Strings.DisplayStringOption.html +++ b/Documentation/doc/4 enums/Strings.DisplayStringOption.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/Util.LogLevel.html b/Documentation/doc/4 enums/Util.LogLevel.html index d00c53ea6..3e463cf45 100644 --- a/Documentation/doc/4 enums/Util.LogLevel.html +++ b/Documentation/doc/4 enums/Util.LogLevel.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/View.AlignMode.html b/Documentation/doc/4 enums/View.AlignMode.html index 1f95d4bf0..479a64e04 100644 --- a/Documentation/doc/4 enums/View.AlignMode.html +++ b/Documentation/doc/4 enums/View.AlignMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/View.CameraType.html b/Documentation/doc/4 enums/View.CameraType.html index 255946261..8059b3c65 100644 --- a/Documentation/doc/4 enums/View.CameraType.html +++ b/Documentation/doc/4 enums/View.CameraType.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/View.PostProcessMode.html b/Documentation/doc/4 enums/View.PostProcessMode.html index 825aa6742..03b0419d6 100644 --- a/Documentation/doc/4 enums/View.PostProcessMode.html +++ b/Documentation/doc/4 enums/View.PostProcessMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/4 enums/View.ScaleMode.html b/Documentation/doc/4 enums/View.ScaleMode.html index 868e2f41e..d00970ef0 100644 --- a/Documentation/doc/4 enums/View.ScaleMode.html +++ b/Documentation/doc/4 enums/View.ScaleMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/5 lua utility modules/CustomBar.html b/Documentation/doc/5 lua utility modules/CustomBar.html index 940e0b6bd..2940474c8 100644 --- a/Documentation/doc/5 lua utility modules/CustomBar.html +++ b/Documentation/doc/5 lua utility modules/CustomBar.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/5 lua utility modules/Diary.html b/Documentation/doc/5 lua utility modules/Diary.html index 27e48878c..58d81a722 100644 --- a/Documentation/doc/5 lua utility modules/Diary.html +++ b/Documentation/doc/5 lua utility modules/Diary.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index 9f68608b1..cea188d4f 100644 --- a/Documentation/doc/5 lua utility modules/EventSequence.html +++ b/Documentation/doc/5 lua utility modules/EventSequence.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index fead185e8..5cff92477 100644 --- a/Documentation/doc/5 lua utility modules/Timer.html +++ b/Documentation/doc/5 lua utility modules/Timer.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/5 lua utility modules/Type.html b/Documentation/doc/5 lua utility modules/Type.html index 290e73067..dad15e9ec 100644 --- a/Documentation/doc/5 lua utility modules/Type.html +++ b/Documentation/doc/5 lua utility modules/Type.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html index e934b8f98..780a8b9e5 100644 --- a/Documentation/doc/index.html +++ b/Documentation/doc/index.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API @@ -115,7 +115,7 @@
    -

    TombEngine 1.8 scripting interface

    +

    TombEngine 1.8.1 scripting interface

    Welcome to the TombEngine scripting API.

    Note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse. From 410250bf2d900810e520c8091ccbe0a1ee92e933 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 29 Mar 2025 09:55:09 +0100 Subject: [PATCH 25/53] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3d47c249b..6c8243091 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed crash with incorrectly applied animated textures on static meshes. * Fixed console window not hiding in non-debug mode on Windows 11. * Fixed key binding settings saving for the current play session after hitting Esc to cancel. +* Fixed lensflare blending formula to avoid screen overbright. ### Lua API changes * Added missing constructor for `Collision.Probe` without room number. From 5c83574a0e1d253cab1bee8a071e0ef07c6f2164 Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Sat, 29 Mar 2025 14:16:09 +0000 Subject: [PATCH 26/53] Updated changelog for release version Bug Fixes moved to top (as per other version entries) --- CHANGELOG.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c8243091..a1be08042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,7 @@ The dates are in European standard format where date is presented as **YYYY-MM-DD**. TombEngine releases are located in this repository (alongside with Tomb Editor): https://github.com/TombEngine/TombEditorReleases -## [Version 1.8.1](link to release) - yyyy-mm-dd - -### New features -* Added Firefly Emitter object (ID 1099) with corresponding sprite slot (ID 1379). -* Added live console input to perform Lua commands in realtime. +## [Version 1.8.1](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8.1) - 2025-03-29 ### Bug fixes * Fixed pathfinding for friendly NPCs such as monkeys. @@ -19,6 +15,10 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed key binding settings saving for the current play session after hitting Esc to cancel. * Fixed lensflare blending formula to avoid screen overbright. +### New features +* Added Firefly Emitter object (ID 1099) with corresponding sprite slot (ID 1379). +* Added live console input to perform Lua commands in realtime. + ### Lua API changes * Added missing constructor for `Collision.Probe` without room number. * Added optional looping argument for `View.GetFlybyPosition` and `View.GetFlybyRotation` functions. From ed596ba07be092529ba5077d120e71fa5ddb7f32 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 30 Mar 2025 14:26:36 +1100 Subject: [PATCH 27/53] Update spotcam.cpp --- TombEngine/Game/spotcam.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/TombEngine/Game/spotcam.cpp b/TombEngine/Game/spotcam.cpp index 2b6ea8d10..3225d38d9 100644 --- a/TombEngine/Game/spotcam.cpp +++ b/TombEngine/Game/spotcam.cpp @@ -841,6 +841,10 @@ int Spline(int x, int* knots, int nk) Pose GetCameraTransform(int sequence, float alpha, bool loop) { + constexpr auto BLEND_RANGE = 0.1f; + constexpr auto BLEND_START = BLEND_RANGE; + constexpr auto BLEND_END = 1.0f - BLEND_RANGE; + alpha = std::clamp(alpha, 0.0f, 1.0f); // Retrieve camera count in sequence. @@ -887,18 +891,14 @@ Pose GetCameraTransform(int sequence, float alpha, bool loop) return Spline(tAlpha, rolls.data(), splinePoints); }; - Vector3 origin = {}; - Vector3 target = {}; + auto origin = Vector3::Zero; + auto target = Vector3::Zero; short orientZ = 0; - constexpr float BLEND_RANGE = 0.1f; - constexpr float BLEND_START = BLEND_RANGE; - constexpr float BLEND_END = 1.0f - BLEND_RANGE; - - // If loop is enabled and we are at the start or end of the sequence, blend between the last and first cameras. + // If loop is enabled and alpha is at sequence start or end, blend between last and first cameras. if (loop && (alpha < BLEND_START || alpha >= BLEND_END)) { - float blendFactor = (alpha < BLEND_START) ? 0.5f + (alpha / BLEND_RANGE) * 0.5f : (alpha - BLEND_END) / BLEND_START * 0.5f; + float blendFactor = (alpha < BLEND_START) ? (0.5f + ((alpha / BLEND_RANGE) * 0.5f)) : (((alpha - BLEND_END) / BLEND_START) * 0.5f); origin = Vector3::Lerp(getInterpolatedPoint(BLEND_END, xOrigins, yOrigins, zOrigins), getInterpolatedPoint(BLEND_START, xOrigins, yOrigins, zOrigins), blendFactor); target = Vector3::Lerp(getInterpolatedPoint(BLEND_END, xTargets, yTargets, zTargets), getInterpolatedPoint(BLEND_START, xTargets, yTargets, zTargets), blendFactor); From 8bc15b32006b868571dc5610bfbecb6be77d996b Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 30 Mar 2025 11:29:17 +0200 Subject: [PATCH 28/53] Update spotcam.cpp --- TombEngine/Game/spotcam.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/TombEngine/Game/spotcam.cpp b/TombEngine/Game/spotcam.cpp index 3225d38d9..e58df71d2 100644 --- a/TombEngine/Game/spotcam.cpp +++ b/TombEngine/Game/spotcam.cpp @@ -847,10 +847,19 @@ Pose GetCameraTransform(int sequence, float alpha, bool loop) alpha = std::clamp(alpha, 0.0f, 1.0f); + if (sequence < 0 || sequence >= MAX_SPOTCAMS) + { + TENLog("Wrong flyby sequence number provided for getting camera coordinates.", LogLevel::Warning); + return Pose::Zero; + } + // Retrieve camera count in sequence. int cameraCount = CameraCnt[SpotCamRemap[sequence]]; if (cameraCount < 2) - return Pose::Zero; // Not enough cameras to interpolate. + { + TENLog("Not enough cameras in flyby sequence to calculate the coordinates.", LogLevel::Warning); + return Pose::Zero; + } // Find first ID for sequence. int firstSeqID = 0; From 7c8b67d2bb10db9c42b418a5da2dde0f00d8e83d Mon Sep 17 00:00:00 2001 From: Jakub <80340234+Jakub768@users.noreply.github.com> Date: Sun, 30 Mar 2025 23:56:01 +0100 Subject: [PATCH 29/53] Update AUTHORS.md --- AUTHORS.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AUTHORS.md b/AUTHORS.md index 096d4944c..7bff5eeb4 100644 --- a/AUTHORS.md +++ b/AUTHORS.md @@ -49,5 +49,4 @@ This is the credit list of **all** the people who contributed to TombEngine in a - JoeyQuint (Standing 180° turn, monkey swing 180° turn) ### TombEngine Marketing -- Kubsy (Twitter and forum posts) -- Stranger1992 (This website, Facebook, Instagram, Youtube and Twitch. +- Stranger1992 (This website, Facebook, Instagram, Youtube, Twitter, and Twitch. From 5a71239d7b9a9247b95e81bb1b399a5623a46a99 Mon Sep 17 00:00:00 2001 From: MontyTRC89 Date: Tue, 1 Apr 2025 10:01:57 +0200 Subject: [PATCH 30/53] SSAO fixes for alpha blended surfaces and possibly performance improvements; --- TombEngine/Renderer/RendererDraw.cpp | 8 ++++++-- TombEngine/Shaders/CBCamera.hlsli | 4 ++-- TombEngine/Shaders/SSAO.fx | 14 ++++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 1c63b24d8..391f07fc6 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -3229,13 +3229,17 @@ namespace TEN::Renderer case RendererPass::GBuffer: if (blendMode != BlendMode::Opaque && blendMode != BlendMode::AlphaTest && - blendMode != BlendMode::FastAlphaBlend) + blendMode != BlendMode::FastAlphaBlend && + // WARNING: For G-Buffer step we consider alpha blend like alpha test + // assuming that most of the geometry used in rooms, items and statics + // are fences, foliages, trees... But it could fail with translucent surfaces! + blendMode != BlendMode::AlphaBlend) { return false; } if (blendMode == BlendMode::Opaque) - { + { SetBlendMode(BlendMode::Opaque); SetAlphaTest(AlphaTestMode::None, 1.0f); } diff --git a/TombEngine/Shaders/CBCamera.hlsli b/TombEngine/Shaders/CBCamera.hlsli index 34a7709c0..457b89526 100644 --- a/TombEngine/Shaders/CBCamera.hlsli +++ b/TombEngine/Shaders/CBCamera.hlsli @@ -7,8 +7,8 @@ cbuffer CBCamera : register(b0) { float4x4 ViewProjection; float4x4 View; - float4x4 Projection; - float4x4 InverseProjection; + float4x4 Projection; + float4x4 InverseProjection; float4x4 DualParaboloidView; float4 CamPositionWS; float4 CamDirectionWS; diff --git a/TombEngine/Shaders/SSAO.fx b/TombEngine/Shaders/SSAO.fx index b5a9c5dba..844419b7e 100644 --- a/TombEngine/Shaders/SSAO.fx +++ b/TombEngine/Shaders/SSAO.fx @@ -50,11 +50,12 @@ float PS(PixelShaderInput input) : SV_Target float3 position = ReconstructPositionFromDepth(input.UV); float3 encodedNormal = NormalsTexture.Sample(NormalsSampler, input.UV).xyz; - // Let's avoid SSAO on the skybox and on surfaces with no normals - if (length(encodedNormal) <= 0.0001f) - { - return float4(1.0f, 1.0f, 1.0f, 1.0f); - } + float farMask = step(40960.0f, length(position)); // 1 if too far + float noNormalMask = step(length(encodedNormal), 0.0001f); // 1 if normal is too small + float earlyExit = saturate(farMask + noNormalMask); // 0 if both are fine + + if (earlyExit > 0.0f) + return float4(1.0f, 1.0f, 1.0f, 1.0f); float3 normal = DecodeNormal(encodedNormal); float3 randomVec = NoiseTexture.Sample(NoiseSampler, input.UV * noiseScale).xyz; @@ -82,7 +83,8 @@ float PS(PixelShaderInput input) : SV_Target float sampleDepth = ReconstructPositionFromDepth(offset.xy).z; float rangeCheck = smoothstep(0.0, 1.0, radius / abs(position.z - sampleDepth)); - occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck; + occlusion += lerp(0.0f, rangeCheck, step(0.0, sampleDepth - samplePos.z - bias)); + //occlusion += (sampleDepth >= samplePos.z + bias ? 1.0 : 0.0) * rangeCheck; } occlusion = 1.0 - (occlusion / kernelSize); From 2fb0a609a3e2aa46d4540df4598550099ceef6d5 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 2 Apr 2025 05:01:51 +0200 Subject: [PATCH 31/53] Remove duplicate log entry --- TombEngine/Renderer/RendererCompatibility.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/TombEngine/Renderer/RendererCompatibility.cpp b/TombEngine/Renderer/RendererCompatibility.cpp index 7ae2ef7d5..ef561320b 100644 --- a/TombEngine/Renderer/RendererCompatibility.cpp +++ b/TombEngine/Renderer/RendererCompatibility.cpp @@ -68,9 +68,6 @@ namespace TEN::Renderer _animatedTextures[i] = tex; } - if (_animatedTextures.size() > 0) - TENLog("Generated " + std::to_string(_animatedTextures.size()) + " animated textures.", LogLevel::Info); - std::transform(g_Level.AnimatedTexturesSequences.begin(), g_Level.AnimatedTexturesSequences.end(), std::back_inserter(_animatedTextureSets), [](ANIMATED_TEXTURES_SEQUENCE& sequence) { RendererAnimatedTextureSet set{}; set.NumTextures = sequence.numFrames; From 4e523957a5940339b034af520384089eb695eb88 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 2 Apr 2025 05:42:18 +0200 Subject: [PATCH 32/53] Fixed #1603 and gunshell/flash renderer crashes --- CHANGELOG.md | 6 + .../Objects/TR5/Object/tr5_teleporter.cpp | 170 +----------------- .../Objects/TR5/Object/tr5_teleporter.h | 1 - TombEngine/Objects/TR5/tr5_objects.cpp | 1 - TombEngine/Renderer/RendererDraw.cpp | 3 + TombEngine/Renderer/RendererDrawEffect.cpp | 45 ++--- 6 files changed, 42 insertions(+), 184 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1be08042..a74dc0ee6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,12 @@ The dates are in European standard format where date is presented as **YYYY-MM-DD**. TombEngine releases are located in this repository (alongside with Tomb Editor): https://github.com/TombEngine/TombEditorReleases +## [Version 1.8.2] + +### Bug fixes +* Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level. +* Fixed Teleporter object. + ## [Version 1.8.1](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8.1) - 2025-03-29 ### Bug fixes diff --git a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp index 6ebb9961a..a3166f832 100644 --- a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp @@ -7,22 +7,11 @@ #include "Game/effects/weather.h" #include "Game/Lara/lara.h" #include "Game/camera.h" +#include "Game/collision/Point.h" +using namespace TEN::Collision::Point; using namespace TEN::Effects::Environment; -void InitializeTeleporter(short itemNumber) -{ - /*ItemInfo* item = &g_Level.Items[itemNumber]; - - if (item->triggerFlags == 512) - { - ItemInfo* puzzleHoleItem = FindItem(ID_PUZZLE_HOLE2); - v4 = (signed int)((unsigned __int64)(391146079i64 * ((char*)v3 - (char*)items)) >> 32) >> 9; - result = (unsigned int)((unsigned __int64)(391146079i64 * ((char*)v3 - (char*)items)) >> 32) >> 31; - item->itemFlags[1] = result + v4; - }*/ -} - void ControlTeleporter(short itemNumber) { ItemInfo* item = &g_Level.Items[itemNumber]; @@ -30,149 +19,6 @@ void ControlTeleporter(short itemNumber) if (!TriggerActive(item)) return; - /*if (item->triggerFlags == 512) - { - if (item->itemFlags[2]) - { - Lara.Puzzles[1] = 1; - RemoveActiveItem(itemNumber); - item->flags &= 0xC1FF; - } - else - { - item->itemFlags[0] += 2; - - if (item->itemFlags[0] <= 255) - { - int flags = item->itemFlags[0] >> 3; - if (flags >= 4) - { - if (flags > 31) - flags = 31; - } - else - { - flags = 4; - } - - ItemInfo* targetItem = &g_Level.Items[item->itemFlags[1]]; - SoundEffect(SFX_TR5_TELEPORT, &targetItem->pos, SoundEnvironment::Land); - - if (GlobalCounter & 1) - { - Vector3i src; - pos.x = targetItem->pos.Position.x; - pos.y = targetItem->pos.Position.y - 496; - pos.z = targetItem->pos.Position.z + 472; - - int dl = 4 * item->itemFlags[0] + 256; - - Vector3i dest; - dest.x = src.x + GetRandomControl() % dl - (dl >> 1); - dest.y = src.y + GetRandomControl() % dl - (dl >> 1); - dest.z = src.z + GetRandomControl() % dl - (dl >> 1); - - int color = (item->itemFlags[0] >> 2) | (((item->itemFlags[0] - (GetRandomControl() % (item->itemFlags[0] >> 1))) | (item->itemFlags[0] << 8)) << 8); - color |= 0x18; // BYTE1 - - //TriggerEnergyArc(&src, &dest, (GetRandomControl() & 0x1F) + 16, color, 15, 40, 5); - - v20 = v16; - v21 = v12 & 0xFFFFFFFE; - LOBYTE(v20) = v16 & 0xFE; - BYTE1(v21) |= 0x80u; - TriggerLightningGlow(src.x, src.y, src.z, (item->itemFlags[0] >> 3) | ((v20 | (v21 << 8)) << 7)); - v22 = GetRandomControl(); - SpawnDynamicLight(src.x, src.y, src.z, (v22 & 3) + (item->itemFlags[0] >> 5) + 8, v12, v16, v13); - } - LOBYTE(v3) = GetRandomControl(); - if (v3 & 1) - { - v23 = item->itemFlags[0]; - v24 = item->itemFlags[0]; - v25 = GetRandomControl(); - - auto R = v23; - auto G = v24 - v25 % (v24 >> 1); - auto B = v24 >> 2; - Weather.Flash(R, G, B, 0.03f); - - LOBYTE(v3) = SoundEffect(SFX_TR5_TELEPORT_CRACKLES, nullptr); - } - if (!(GlobalCounter & 3)) - { - v26 = GetRandomControl(); - v27 = 0; - v28 = v26 & 3; - v29 = 0; - if (v28) - { - if (v28 == 1) - v29 = 512; - else - v27 = v28 != 2 ? 512 : -512; - } - else - { - v29 = -512; - } - v30 = item->itemFlags[0]; - v31 = &g_Level.Items[item->itemFlags[1]]; - src.Position.x = v29 + v31->pos.Position.x; - src.Position.y = v31->pos.Position.y - 2328; - src.zPos = v27 + v31->pos.Position.z; - *(_DWORD*)& src.xRot = v31->pos.Position.x; - v32 = item->itemFlags[0]; - *(_DWORD*)& src.zRot = v31->pos.Position.y - 496; - v45 = v31->pos.Position.z + 472; - v33 = (v30 >> 2) | (((v30 - GetRandomControl() % (v30 >> 1)) | ((v32 | 0x2400) << 8)) << 8); - v34 = GetRandomControl(); - TriggerEnergyArc((Vector3i*)& src, (Vector3i*)& src.xRot, (v34 & 0xF) + 16, v33, 13, 56, 5); - v35* = GetFreeParticle(); - v35->On = 1; - v36 = item->itemFlags[0]; - v35->dR = v36; - v35->sR = v36; - v37 = item->itemFlags[0] >> 1; - v35->dG = v37; - v35->sG = v37; - v38 = item->itemFlags[0]; - v35->ColFadeSpeed = 20; - v38 >>= 2; - v35->dB = v38; - v35->sB = v38; - v35->FadeToBlack = 4; - v35->Life = 24; - v35->sLife = 24; - v35->blendMode = BlendMode::Additive; - v35->x = src.Position.x; - v35->y = src.Position.y; - v35->z = src.zPos; - v35->Zvel = 0; - v35->Yvel = 0; - v35->Xvel = 0; - v35->Flags = 10; - v39 = objects[458].mesh_index; - v35->Scalar = 3; - v35->MaxYvel = 0; - v35->Def = v39 + 11; - v35->Gravity = 0; - v3 = (GetRandomControl() & 3) + 24; - v35->dSize = v3; - v35->sSize = v3; - v35->Size = v3; - } - return v3; - } - FlashFadeR = 255; - FlashFadeG = 255; - FlashFadeB = 64; - FlashFader = 32; - item->itemFlags[2] = 1; - SoundEffect(SFX_TR5_TELEPORT_FLASH, nullptr, SoundEnvironment::Land); - } - }*/ - Lara.Control.IsLocked = false; if (item->TriggerFlags == 666) @@ -196,12 +42,14 @@ void ControlTeleporter(short itemNumber) LaraItem->Pose.Position.z = item->Pose.Position.z; LaraItem->Pose.Orientation.y = item->Pose.Orientation.y - ANGLE(180.0f); - short roomNumber = item->RoomNumber; - FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); - LaraItem->Pose.Position.y = GetFloorHeight(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); + auto& pointColl = GetPointCollision(*item); + LaraItem->Pose.Position.y = pointColl.GetPosition().y; - if (LaraItem->RoomNumber != roomNumber) - ItemNewRoom(LaraItem->Index, roomNumber); + if (LaraItem->RoomNumber != pointColl.GetRoomNumber()) + { + ItemNewRoom(LaraItem->Index, pointColl.GetRoomNumber()); + LaraItem->Location.RoomNumber = pointColl.GetRoomNumber(); + } if (item->Flags & IFLAG_INVISIBLE) { diff --git a/TombEngine/Objects/TR5/Object/tr5_teleporter.h b/TombEngine/Objects/TR5/Object/tr5_teleporter.h index 547ddcaba..dde7fc827 100644 --- a/TombEngine/Objects/TR5/Object/tr5_teleporter.h +++ b/TombEngine/Objects/TR5/Object/tr5_teleporter.h @@ -1,4 +1,3 @@ #pragma once -void InitializeTeleporter(short itemNumber); void ControlTeleporter(short itemNumber); diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp index 130d7405f..76c70133f 100644 --- a/TombEngine/Objects/TR5/tr5_objects.cpp +++ b/TombEngine/Objects/TR5/tr5_objects.cpp @@ -774,7 +774,6 @@ static void StartObject(ObjectInfo *obj) obj = &Objects[ID_TELEPORTER]; if (obj->loaded) { - obj->Initialize = InitializeTeleporter; obj->control = ControlTeleporter; obj->drawRoutine = nullptr; } diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 391f07fc6..e22c9357c 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -263,6 +263,9 @@ namespace TEN::Renderer objectID = gunshell->objectNumber; + if (!_moveableObjects[objectID].has_value()) + continue; + auto translation = Matrix::CreateTranslation(gunshell->pos.Position.ToVector3()); auto rotMatrix = gunshell->pos.Orientation.ToRotationMatrix(); auto worldMatrix = rotMatrix * translation; diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp index e647f86b1..cb903c2f6 100644 --- a/TombEngine/Renderer/RendererDrawEffect.cpp +++ b/TombEngine/Renderer/RendererDrawEffect.cpp @@ -1085,31 +1085,10 @@ namespace TEN::Renderer if (!settings.MuzzleFlash) return false; - _shaders.Bind(Shader::Statics); - - unsigned int stride = sizeof(Vertex); - unsigned int offset = 0; - - _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); - _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); - _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); - - const auto& room = _rooms[LaraItem->RoomNumber]; - auto* itemPtr = &_items[LaraItem->Index]; - - // Divide gunflash tint by 2 because tinting uses multiplication and additive color which doesn't look good with overbright color values. - _stStatic.Color = settings.ColorizeMuzzleFlash ? ((Vector4)settings.FlashColor / 2) : Vector4::One; - _stStatic.AmbientLight = room.AmbientLight; - _stStatic.LightMode = (int)LightMode::Static; - BindStaticLights(itemPtr->LightsToDraw); - short length = 0; short zOffset = 0; short rotationX = 0; - SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD); - SetBlendMode(BlendMode::Additive); - if (Lara.Control.Weapon.GunType != LaraWeaponType::Flare && Lara.Control.Weapon.GunType != LaraWeaponType::Crossbow) { @@ -1151,9 +1130,33 @@ namespace TEN::Renderer zOffset += 10; } + if (!_moveableObjects[gunflash].has_value()) + return false; + const auto& flashMoveable = *_moveableObjects[gunflash]; const auto& flashMesh = *flashMoveable.ObjectMeshes[0]; + _shaders.Bind(Shader::Statics); + + unsigned int stride = sizeof(Vertex); + unsigned int offset = 0; + + _context->IASetVertexBuffers(0, 1, _moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); + _context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + _context->IASetIndexBuffer(_moveablesIndexBuffer.Buffer.Get(), DXGI_FORMAT_R32_UINT, 0); + + const auto& room = _rooms[LaraItem->RoomNumber]; + auto* itemPtr = &_items[LaraItem->Index]; + + // Divide gunflash tint by 2 because tinting uses multiplication and additive color which doesn't look good with overbright color values. + _stStatic.Color = settings.ColorizeMuzzleFlash ? ((Vector4)settings.FlashColor / 2) : Vector4::One; + _stStatic.AmbientLight = room.AmbientLight; + _stStatic.LightMode = (int)LightMode::Static; + BindStaticLights(itemPtr->LightsToDraw); + + SetAlphaTest(AlphaTestMode::GreatherThan, ALPHA_TEST_THRESHOLD); + SetBlendMode(BlendMode::Additive); + for (const auto& flashBucket : flashMesh.Buckets) { if (flashBucket.BlendMode == BlendMode::Opaque) From 144a93dfe8ee9c290dc146405175faa4ecda0566 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 2 Apr 2025 06:02:03 +0200 Subject: [PATCH 33/53] Fixed #1616 --- CHANGELOG.md | 1 + TombEngine/Objects/TR4/Entity/Wraith.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a74dc0ee6..234608089 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): ### Bug fixes * Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level. * Fixed Teleporter object. +* Fixed Wraith objects not working correctly in flipped rooms. ## [Version 1.8.1](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8.1) - 2025-03-29 diff --git a/TombEngine/Objects/TR4/Entity/Wraith.cpp b/TombEngine/Objects/TR4/Entity/Wraith.cpp index 90860c590..e84ada397 100644 --- a/TombEngine/Objects/TR4/Entity/Wraith.cpp +++ b/TombEngine/Objects/TR4/Entity/Wraith.cpp @@ -308,6 +308,11 @@ namespace TEN::Entities::TR4 item.Pose.Orientation.x += angleV; } + // Translate wraith. + item.Pose.Position.x += item.Animation.Velocity.z * phd_sin(item.Pose.Orientation.y); + item.Pose.Position.y += item.Animation.Velocity.z * phd_sin(item.Pose.Orientation.x); + item.Pose.Position.z += item.Animation.Velocity.z * phd_cos(item.Pose.Orientation.y); + auto pointColl = GetPointCollision(item); bool hasHitWall = false; @@ -317,13 +322,8 @@ namespace TEN::Entities::TR4 hasHitWall = true; } - // Translate wraith. - item.Pose.Position.x += item.Animation.Velocity.z * phd_sin(item.Pose.Orientation.y); - item.Pose.Position.y += item.Animation.Velocity.z * phd_sin(item.Pose.Orientation.x); - item.Pose.Position.z += item.Animation.Velocity.z * phd_cos(item.Pose.Orientation.y); - if (pointColl.GetRoomNumber() != item.RoomNumber) - ItemNewRoom(itemNumber, pointColl.GetRoomNumber()); + ItemNewRoom(itemNumber, FindRoomNumber(item.Pose.Position, item.RoomNumber)); for (int linkItemNumber = g_Level.Rooms[item.RoomNumber].itemNumber; linkItemNumber != NO_VALUE; linkItemNumber = g_Level.Items[linkItemNumber].NextItem) { From 3a7d375dd99f023727fda5f2d10f91eee543e7ee Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 2 Apr 2025 06:12:06 +0200 Subject: [PATCH 34/53] Update tr5_teleporter.cpp --- TombEngine/Objects/TR5/Object/tr5_teleporter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp index a3166f832..0620d6397 100644 --- a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp @@ -38,6 +38,7 @@ void ControlTeleporter(short itemNumber) else { Camera.fixedCamera = true; + LaraItem->DisableInterpolation = true; LaraItem->Pose.Position.x = item->Pose.Position.x; LaraItem->Pose.Position.z = item->Pose.Position.z; LaraItem->Pose.Orientation.y = item->Pose.Orientation.y - ANGLE(180.0f); From 5b9836dea06533d129373d7399b7ea620476e121 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 2 Apr 2025 06:15:57 +0200 Subject: [PATCH 35/53] Update tr5_teleporter.cpp --- TombEngine/Objects/TR5/Object/tr5_teleporter.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp index 0620d6397..a71934996 100644 --- a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp @@ -1,13 +1,14 @@ #include "framework.h" -#include "tr5_teleporter.h" -#include "Game/items.h" -#include "Specific/level.h" -#include "Game/collision/collide_room.h" -#include "Sound/sound.h" -#include "Game/effects/weather.h" -#include "Game/Lara/lara.h" +#include "Objects/TR5/Object/tr5_teleporter.h" + #include "Game/camera.h" +#include "Game/collision/collide_room.h" #include "Game/collision/Point.h" +#include "Game/effects/weather.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Sound/sound.h" +#include "Specific/level.h" using namespace TEN::Collision::Point; using namespace TEN::Effects::Environment; From fc4cef38dfb006ec2749e44c220fc6a83402c3d8 Mon Sep 17 00:00:00 2001 From: MontyTRC89 Date: Thu, 3 Apr 2025 09:38:20 +0200 Subject: [PATCH 36/53] Fixed caustics when DDS compression is used --- .../Renderer/ConstantBuffers/RoomBuffer.h | 2 +- TombEngine/Renderer/Graphics/Texture2D.h | 42 ------------------- TombEngine/Renderer/Renderer.h | 2 +- TombEngine/Renderer/RendererCompatibility.cpp | 19 --------- TombEngine/Renderer/RendererDraw.cpp | 13 ++++-- TombEngine/Shaders/Rooms.fx | 42 ++++++++++--------- 6 files changed, 35 insertions(+), 85 deletions(-) diff --git a/TombEngine/Renderer/ConstantBuffers/RoomBuffer.h b/TombEngine/Renderer/ConstantBuffers/RoomBuffer.h index d78a77965..c73f4f9ca 100644 --- a/TombEngine/Renderer/ConstantBuffers/RoomBuffer.h +++ b/TombEngine/Renderer/ConstantBuffers/RoomBuffer.h @@ -15,7 +15,7 @@ namespace TEN::Renderer::ConstantBuffers int Padding; //-- Vector2 CausticsStartUV; - Vector2 CausticsScale; + Vector2 CausticsSize; //-- Vector4 AmbientColor; //-- diff --git a/TombEngine/Renderer/Graphics/Texture2D.h b/TombEngine/Renderer/Graphics/Texture2D.h index 1608b7ea2..2a398def9 100644 --- a/TombEngine/Renderer/Graphics/Texture2D.h +++ b/TombEngine/Renderer/Graphics/Texture2D.h @@ -144,48 +144,6 @@ namespace TEN::Renderer::Graphics Height = desc.Height; } - Texture2D(ID3D11Device* device, ID3D11DeviceContext* context, ID3D11Texture2D* texture, int x, int y, int width, int height) - { - Width = width; - Height = height; - - D3D11_TEXTURE2D_DESC fromDesc = {}; - texture->GetDesc(&fromDesc); - - auto desc = D3D11_TEXTURE2D_DESC{}; - desc.Width = width; - desc.Height = height; - desc.Format = fromDesc.Format; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.BindFlags = D3D11_BIND_SHADER_RESOURCE; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - - throwIfFailed(device->CreateTexture2D(&desc, nullptr, &Texture)); - - D3D11_BOX sourceRegion; - sourceRegion.left = x; - sourceRegion.right = x + width; - sourceRegion.top = y; - sourceRegion.bottom = y + height; - sourceRegion.front = 0; - sourceRegion.back = 1; - - context->CopySubresourceRegion(Texture.Get(), 0, 0, 0, 0, texture, 0, &sourceRegion); - - auto shaderDesc = D3D11_SHADER_RESOURCE_VIEW_DESC{}; - shaderDesc.Format = desc.Format; - shaderDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - shaderDesc.Texture2D.MostDetailedMip = 0; - shaderDesc.Texture2D.MipLevels = 1; - - throwIfFailed(device->CreateShaderResourceView(Texture.Get(), &shaderDesc, ShaderResourceView.GetAddressOf())); - } - ~Texture2D() = default; }; } diff --git a/TombEngine/Renderer/Renderer.h b/TombEngine/Renderer/Renderer.h index 4e643388d..16c6325c2 100644 --- a/TombEngine/Renderer/Renderer.h +++ b/TombEngine/Renderer/Renderer.h @@ -340,7 +340,7 @@ namespace TEN::Renderer // Special effects - std::vector _causticTextures; + //std::vector _causticTextures; RendererMirror* _currentMirror = nullptr; // Transparency diff --git a/TombEngine/Renderer/RendererCompatibility.cpp b/TombEngine/Renderer/RendererCompatibility.cpp index 7ae2ef7d5..2239f8450 100644 --- a/TombEngine/Renderer/RendererCompatibility.cpp +++ b/TombEngine/Renderer/RendererCompatibility.cpp @@ -882,25 +882,6 @@ namespace TEN::Renderer } _spriteSequences[SpriteSequencesIds[i]] = sequence; - - if (SpriteSequencesIds[i] == ID_CAUSTIC_TEXTURES) - { - _causticTextures.clear(); - for (int j = 0; j < sequence.SpritesList.size(); j++) - { - _causticTextures.push_back( - Texture2D( - _device.Get(), - _context.Get(), - sequence.SpritesList[j]->Texture->Texture.Get(), - sequence.SpritesList[j]->X, - sequence.SpritesList[j]->Y, - sequence.SpritesList[j]->Width, - sequence.SpritesList[j]->Height - ) - ); - } - } } } diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 391f07fc6..dddca503e 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -2709,12 +2709,19 @@ namespace TEN::Renderer if (rendererPass != RendererPass::GBuffer) { // Bind caustics texture. - if (_causticTextures.size() > 0) + if (std::find(SpriteSequencesIds.begin(), SpriteSequencesIds.end(), ID_CAUSTIC_TEXTURES) != SpriteSequencesIds.end()) { int nmeshes = -Objects[ID_CAUSTIC_TEXTURES].nmeshes; int meshIndex = Objects[ID_CAUSTIC_TEXTURES].meshIndex; - int causticsFrame = GlobalCounter % _causticTextures.size(); - BindTexture(TextureRegister::CausticsMap, &_causticTextures[causticsFrame], SamplerStateRegister::AnisotropicClamp); + int causticsFrame = GlobalCounter % nmeshes; + auto causticsSprite = _spriteSequences[ID_CAUSTIC_TEXTURES].SpritesList[causticsFrame]; + + BindTexture(TextureRegister::CausticsMap, causticsSprite->Texture, SamplerStateRegister::AnisotropicClamp); + + _stRoom.CausticsSize = Vector2( + (float)causticsSprite->Width / (float)causticsSprite->Texture->Width, + (float)causticsSprite->Height / (float)causticsSprite->Texture->Height); + _stRoom.CausticsStartUV = causticsSprite->UV[0]; } // Set shadow map data and bind shadow map texture. diff --git a/TombEngine/Shaders/Rooms.fx b/TombEngine/Shaders/Rooms.fx index 1ed9a57ba..b1da5c9ec 100644 --- a/TombEngine/Shaders/Rooms.fx +++ b/TombEngine/Shaders/Rooms.fx @@ -16,7 +16,7 @@ cbuffer RoomBuffer : register(b5) int NumRoomLights; int Padding; float2 CausticsStartUV; - float2 CausticsScale; + float2 CausticsSize; float4 AmbientColor; ShaderLight RoomLights[MAX_LIGHTS_PER_ROOM]; }; @@ -170,29 +170,33 @@ PixelShaderOutput PS(PixelShaderInput input) } } - if (Caustics) - { - float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal)); + if (Caustics) + { + float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal)); - float3 blending = abs(normal); - blending = normalize(max(blending, 0.00001f)); - float b = (blending.x + blending.y + blending.z); - blending /= float3(b, b, b); + float3 blending = abs(normal); + blending = normalize(max(blending, 0.00001f)); + float b = (blending.x + blending.y + blending.z); + blending /= float3(b, b, b); - float3 p = frac(input.WorldPosition.xyz / 2048.0f); - - float3 xaxis = CausticsTexture.SampleLevel(CausticsTextureSampler, float2(p.z, p.y), 0).xyz; - float3 yaxis = CausticsTexture.SampleLevel(CausticsTextureSampler, float2(p.z, p.x), 0).xyz; - float3 zaxis = CausticsTexture.SampleLevel(CausticsTextureSampler, float2(p.y, p.x), 0).xyz; + float3 p = frac(input.WorldPosition.xyz / 2048.0f); + + float2 uv_x = CausticsStartUV + float2(p.z, p.y) * CausticsSize; + float2 uv_y = CausticsStartUV + float2(p.z, p.x) * CausticsSize; + float2 uv_z = CausticsStartUV + float2(p.y, p.x) * CausticsSize; - float3 xc = xaxis * blending.x; - float3 yc = yaxis * blending.y; - float3 zc = zaxis * blending.z; + float3 xaxis = CausticsTexture.SampleLevel(CausticsTextureSampler, uv_x, 0).xyz; + float3 yaxis = CausticsTexture.SampleLevel(CausticsTextureSampler, uv_y, 0).xyz; + float3 zaxis = CausticsTexture.SampleLevel(CausticsTextureSampler, uv_z, 0).xyz; - float3 caustics = xc + yc + zc; + float3 xc = xaxis * blending.x; + float3 yc = yaxis * blending.y; + float3 zc = zaxis * blending.z; - lighting += (caustics * attenuation * 2.0f); - } + float3 caustics = xc + yc + zc; + + lighting += (caustics * attenuation * 2.0f); + } lighting -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w); output.Color.xyz = output.Color.xyz * lighting * occlusion; From 3745cdadbdcc2c644d445281975e9c2bdda86df8 Mon Sep 17 00:00:00 2001 From: MontyTRC89 Date: Thu, 3 Apr 2025 10:50:02 +0200 Subject: [PATCH 37/53] Possible fix for GetJointPosition problem when objects are off-screen --- TombEngine/Renderer/RendererFrame.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index 6fddadff9..3e5f2ac53 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -422,12 +422,15 @@ namespace TEN::Renderer // Clip object by frustum only if it doesn't cast shadows and is not in mirror room, // otherwise disappearing shadows or reflections may be seen if object gets out of frustum. + bool inFrustum = true; + if (!isRoomReflected && obj.ShadowType == ShadowMode::None) { + inFrustum = false; + // Get all spheres and check if frustum intersects any of them. auto spheres = GetSpheres(itemNumber); - bool inFrustum = false; for (int i = 0; !inFrustum, i < spheres.size(); i++) { // Blow up sphere radius by half for cases of too small calculated spheres. @@ -435,8 +438,8 @@ namespace TEN::Renderer inFrustum = true; } - if (!inFrustum) - continue; + // NOTE: removed continue loop here if not in frustum, + // for updating first positions and animations data } auto& newItem = _items[itemNumber]; @@ -487,6 +490,12 @@ namespace TEN::Renderer for (int j = 0; j < MAX_BONES; j++) newItem.InterpolatedAnimTransforms[j] = Matrix::Lerp(newItem.PrevAnimTransforms[j], newItem.AnimTransforms[j], GetInterpolationFactor(forceValue)); + // NOTE: now at least positions and animations are updated, + // because even off-screen the correct position is required + // by GetJointPosition functions and similars + if (!inFrustum) + continue; + CalculateLightFades(&newItem); CollectLightsForItem(&newItem); From d2d6645fe86522ce073d615cb899b692a2d5b623 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 4 Apr 2025 08:57:06 +0200 Subject: [PATCH 38/53] Fallback for GetJointPosition --- CHANGELOG.md | 4 ++++ TombEngine/Game/animation.cpp | 12 ++++++++++++ .../Internal/TEN/Objects/Moveable/MoveableObject.cpp | 6 +++--- 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 234608089..eb51790f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level. * Fixed Teleporter object. * Fixed Wraith objects not working correctly in flipped rooms. +* Fixed caustics not rendered correctly if texture compression was enabled. + +### Lua API changes +* Fixed `Moveable.GetJointPosition` not returning correct results if moveable is invisible or not rendered. ## [Version 1.8.1](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8.1) - 2025-03-29 diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp index 04eb59905..3588ef746 100644 --- a/TombEngine/Game/animation.cpp +++ b/TombEngine/Game/animation.cpp @@ -689,6 +689,18 @@ void ClampRotation(Pose& outPose, short angle, short rotation) Vector3i GetJointPosition(const ItemInfo& item, int jointIndex, const Vector3i& relOffset) { + bool incorrectJoint = false; + if (jointIndex < 0 || jointIndex >= Objects[item.ObjectNumber].nmeshes) + { + TENLog("Unknown joint ID specified for object " + GetObjectName(item.ObjectNumber), LogLevel::Warning, LogConfig::All); + incorrectJoint = true; + } + + // Always return object's root position if it's invisible, because we can't predict its + // joint position otherwise, since it's not animated. + if (incorrectJoint || Objects[item.ObjectNumber].drawRoutine == nullptr || item.Status == ITEM_INVISIBLE) + return Geometry::TranslatePoint(item.Pose.Position, item.Pose.Orientation, relOffset); + // Use matrices done in renderer to transform relative offset. return Vector3i(g_Renderer.GetMoveableBonePosition(item.Index, jointIndex, relOffset.ToVector3())); } diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index eb1ef5760..36028332a 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -430,13 +430,13 @@ void Moveable::SetPosition(const Vec3& pos, sol::optional updateRoom) /// Get the moveable's joint position with an optional relative offset. // @function Moveable:GetJointPosition -// @tparam int jointID Joint ID. +// @tparam int jointIndex Index of a joint to get position. // @tparam[opt] Vec3 offset Offset relative to the joint. // @treturn Vec3 World position. -Vec3 Moveable::GetJointPos(int jointID, sol::optional offset) const +Vec3 Moveable::GetJointPos(int jointIndex, sol::optional offset) const { auto convertedOffset = offset.has_value() ? offset->ToVector3i() : Vector3i::Zero; - return Vec3(GetJointPosition(_moveable, jointID, convertedOffset)); + return Vec3(GetJointPosition(_moveable, jointIndex, convertedOffset)); } /// Get the object's joint rotation From ab55a7cf14bfa6c5389e8b86cdbe1bef5c471e8b Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 4 Apr 2025 09:08:55 +0200 Subject: [PATCH 39/53] Use Contains method where applicable --- Documentation/doc/2 classes/Objects.Moveable.html | 8 ++++---- TombEngine/Game/Lara/lara_one_gun.cpp | 3 ++- TombEngine/Game/camera.cpp | 3 ++- TombEngine/Renderer/RendererDraw.cpp | 3 ++- TombEngine/Renderer/RendererFrame.cpp | 2 +- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index cddc5ebb0..45f4fa252 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -172,7 +172,7 @@ (e.g. - Moveable:GetJointPosition(jointID[, offset]) + Moveable:GetJointPosition(jointIndex[, offset]) Get the moveable's joint position with an optional relative offset. @@ -771,7 +771,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)

    - Moveable:GetJointPosition(jointID[, offset]) + Moveable:GetJointPosition(jointIndex[, offset])
    Get the moveable's joint position with an optional relative offset. @@ -780,9 +780,9 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)

    Parameters:

      -
    • jointID +
    • jointIndex int - Joint ID. + Index of a joint to get position.
    • offset Vec3 diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index 592b9d99c..32b7d60bf 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -32,6 +32,7 @@ #include "Specific/clock.h" #include "Specific/Input/Input.h" #include "Specific/level.h" +#include "Specific/trutils.h" using namespace TEN::Collision::Point; using namespace TEN::Effects::Bubble; @@ -1594,7 +1595,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p for (auto* itemPtr : collObjects.Items) { // Object was already affected by collision, skip it. - if (std::find(affectedObjects.begin(), affectedObjects.end(), itemPtr->Index) != affectedObjects.end()) + if (TEN::Utils::Contains(affectedObjects, itemPtr->Index)) continue; const auto& currentObject = Objects[itemPtr->ObjectNumber]; diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp index fa5f62f02..b6095f8f1 100644 --- a/TombEngine/Game/camera.cpp +++ b/TombEngine/Game/camera.cpp @@ -22,6 +22,7 @@ #include "Sound/sound.h" #include "Specific/Input/Input.h" #include "Specific/level.h" +#include "Specific/trutils.h" #include "Specific/winmain.h" using namespace TEN::Collision::Point; @@ -1392,7 +1393,7 @@ static std::vector FillCollideableItemList() { const auto& item = g_Level.Items[i]; - if (std::find(roomList.begin(), roomList.end(), item.RoomNumber) == roomList.end()) + if (!TEN::Utils::Contains(roomList, (int)item.RoomNumber)) continue; if (!g_Level.Rooms[item.RoomNumber].Active()) diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 491f38b0b..341a7f986 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -31,6 +31,7 @@ #include "Renderer/Structures/RendererSortableObject.h" #include "Specific/configuration.h" #include "Specific/level.h" +#include "Specific/trutils.h" #include "Specific/winmain.h" using namespace TEN::Effects::Hair; @@ -2712,7 +2713,7 @@ namespace TEN::Renderer if (rendererPass != RendererPass::GBuffer) { // Bind caustics texture. - if (std::find(SpriteSequencesIds.begin(), SpriteSequencesIds.end(), ID_CAUSTIC_TEXTURES) != SpriteSequencesIds.end()) + if (TEN::Utils::Contains(SpriteSequencesIds, (int)ID_CAUSTIC_TEXTURES)) { int nmeshes = -Objects[ID_CAUSTIC_TEXTURES].nmeshes; int meshIndex = Objects[ID_CAUSTIC_TEXTURES].meshIndex; diff --git a/TombEngine/Renderer/RendererFrame.cpp b/TombEngine/Renderer/RendererFrame.cpp index 3e5f2ac53..d8d0fcdb0 100644 --- a/TombEngine/Renderer/RendererFrame.cpp +++ b/TombEngine/Renderer/RendererFrame.cpp @@ -835,7 +835,7 @@ namespace TEN::Renderer } // Light already on a list - if (std::find(renderView.LightsToDraw.begin(), renderView.LightsToDraw.end(), light) != renderView.LightsToDraw.end()) + if (TEN::Utils::Contains(renderView.LightsToDraw, light)) { continue; } From 783d7f5fa35fe41979f1e3de04510e37b2a3d129 Mon Sep 17 00:00:00 2001 From: TrainWrack <120750885+TrainWrack@users.noreply.github.com> Date: Sat, 5 Apr 2025 11:24:06 -0400 Subject: [PATCH 40/53] Remove active requirement from ObjectCamera --- .../Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 36028332a..b11d4ab72 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -1240,7 +1240,6 @@ bool Moveable::MeshExists(int index) const // @tparam int mesh Mesh of a target moveable to use as a camera target. void Moveable::AttachObjCamera(short camMeshId, Moveable& mov, short targetMeshId) { - if ((_moveable->Active || _moveable->IsLara()) && (mov._moveable->Active || mov._moveable->IsLara())) ObjCamera(_moveable, camMeshId, mov._moveable, targetMeshId, true); } From 88b1971848604b81791781708aacc30986a9ae4f Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 6 Apr 2025 01:39:37 +0200 Subject: [PATCH 41/53] Correct exclude blend mode --- CHANGELOG.md | 1 + TombEngine/Renderer/RendererInit.cpp | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eb51790f1..fecd0365f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed Teleporter object. * Fixed Wraith objects not working correctly in flipped rooms. * Fixed caustics not rendered correctly if texture compression was enabled. +* Fixed exclusion blend mode not working correctly. ### Lua API changes * Fixed `Moveable.GetJointPosition` not returning correct results if moveable is invisible or not rendered. diff --git a/TombEngine/Renderer/RendererInit.cpp b/TombEngine/Renderer/RendererInit.cpp index 46fac3c2f..81ee2c115 100644 --- a/TombEngine/Renderer/RendererInit.cpp +++ b/TombEngine/Renderer/RendererInit.cpp @@ -133,11 +133,11 @@ namespace TEN::Renderer blendStateDesc.AlphaToCoverageEnable = false; blendStateDesc.IndependentBlendEnable = false; blendStateDesc.RenderTarget[0].BlendEnable = true; - blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; - blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; - blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_REV_SUBTRACT; - blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; - blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_DEST_ALPHA; + blendStateDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_INV_DEST_COLOR; + blendStateDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_COLOR; + blendStateDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_ADD; + blendStateDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; + blendStateDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ZERO; blendStateDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_ADD; blendStateDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; Utils::throwIfFailed(_device->CreateBlendState(&blendStateDesc, _excludeBlendState.GetAddressOf())); From 517f5b30694bf194c1a80fc138170ee8b21377bd Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 7 Apr 2025 08:23:04 +0200 Subject: [PATCH 42/53] Use single version for TE and TEN --- TombEngine/Resources.rc | 4 ++-- .../Internal/TEN/Objects/Moveable/MoveableObject.cpp | 2 +- TombEngine/version.h | 9 +-------- 3 files changed, 4 insertions(+), 11 deletions(-) diff --git a/TombEngine/Resources.rc b/TombEngine/Resources.rc index 0fa0b9c9e..46163b7a4 100644 --- a/TombEngine/Resources.rc +++ b/TombEngine/Resources.rc @@ -28,7 +28,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL VS_VERSION_INFO VERSIONINFO FILEVERSION TEN_MAJOR_VERSION,TEN_MINOR_VERSION,TEN_BUILD_NUMBER,TEN_REVISION_NUMBER - PRODUCTVERSION TE_MAJOR_VERSION,TE_MINOR_VERSION,TE_BUILD_NUMBER,TE_REVISION_NUMBER + PRODUCTVERSION TEN_MAJOR_VERSION, TEN_MINOR_VERSION, TEN_BUILD_NUMBER, TEN_REVISION_NUMBER FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -49,7 +49,7 @@ BEGIN VALUE "OriginalFilename", "TombEngine.exe" VALUE "ProductName", "Tomb Engine" VALUE "FileVersion", TEN_VERSION_STRING - VALUE "ProductVersion", TE_VERSION_STRING + VALUE "ProductVersion", TEN_VERSION_STRING END END BLOCK "VarFileInfo" diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index b11d4ab72..04e4e000b 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -1240,7 +1240,7 @@ bool Moveable::MeshExists(int index) const // @tparam int mesh Mesh of a target moveable to use as a camera target. void Moveable::AttachObjCamera(short camMeshId, Moveable& mov, short targetMeshId) { - ObjCamera(_moveable, camMeshId, mov._moveable, targetMeshId, true); + ObjCamera(_moveable, camMeshId, mov._moveable, targetMeshId, true); } /// Borrow animation from an object diff --git a/TombEngine/version.h b/TombEngine/version.h index 654ddf744..a7bbed0aa 100644 --- a/TombEngine/version.h +++ b/TombEngine/version.h @@ -1,19 +1,12 @@ #pragma once -#define TE_MAJOR_VERSION 1 -#define TE_MINOR_VERSION 8 -#define TE_BUILD_NUMBER 1 -#define TE_REVISION_NUMBER 0 - #define TEN_MAJOR_VERSION 1 #define TEN_MINOR_VERSION 8 -#define TEN_BUILD_NUMBER 1 +#define TEN_BUILD_NUMBER 2 #define TEN_REVISION_NUMBER 0 #define TEST_BUILD 1 #define TOSTR(x) #x #define MAKE_VERSION_STRING(major, minor, build, revision) TOSTR(major) "." TOSTR(minor) "." TOSTR(build) "." TOSTR(revision) - -#define TE_VERSION_STRING MAKE_VERSION_STRING(TE_MAJOR_VERSION, TE_MINOR_VERSION, TE_BUILD_NUMBER, TE_REVISION_NUMBER) #define TEN_VERSION_STRING MAKE_VERSION_STRING(TEN_MAJOR_VERSION, TEN_MINOR_VERSION, TEN_BUILD_NUMBER, TEN_REVISION_NUMBER) From b643eec16582a5b1738d1c6db51be5c862d4a1b2 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:29:39 +0200 Subject: [PATCH 43/53] Added muzzle glow effect for firearms --- CHANGELOG.md | 4 ++ .../doc/2 classes/Flow.Settings.html | 50 +++++++++++++++++++ TombEngine/Game/control/control.cpp | 1 + TombEngine/Game/effects/tomb4fx.cpp | 46 +++++++++++++++++ TombEngine/Game/effects/tomb4fx.h | 1 + TombEngine/Renderer/RendererDraw.cpp | 8 +-- TombEngine/Renderer/RendererDrawEffect.cpp | 41 +-------------- .../Internal/TEN/Flow/Settings/Settings.cpp | 28 +++++++---- .../Internal/TEN/Flow/Settings/Settings.h | 2 + 9 files changed, 126 insertions(+), 55 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fecd0365f..b5f5d1329 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,7 +12,11 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed caustics not rendered correctly if texture compression was enabled. * Fixed exclusion blend mode not working correctly. +### New features +* Added muzzle glow effect for firearms. + ### Lua API changes +* Added `muzzleGlow` and `muzzleOffset` parameters to weapon settings. * Fixed `Moveable.GetJointPosition` not returning correct results if moveable is invisible or not rendered. ## [Version 1.8.1](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8.1) - 2025-03-29 diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index 6003f5cdc..c59098a2a 100644 --- a/Documentation/doc/2 classes/Flow.Settings.html +++ b/Documentation/doc/2 classes/Flow.Settings.html @@ -300,9 +300,17 @@ Display muzzle flash. + muzzleGlow + Display muzzle glow. + + colorizeMuzzleFlash Colorize muzzle flash. + + muzzleOffset + Muzzle offset. +

      System

      @@ -1214,6 +1222,27 @@ + +
      + + muzzleGlow +
      +
      + Display muzzle glow. + + + +
        +
      • muzzleGlow + bool + specifies whether muzzle glow should be displayed or not. Applicable only for firearms. +
      • +
      + + + + +
      @@ -1235,6 +1264,27 @@ + +
      + + muzzleOffset +
      +
      + Muzzle offset. + + + +
        +
      • muzzleOffset + Vec3 + specifies offset for spawning muzzle gunflash effects. Applicable only for firearms. +
      • +
      + + + + +

      System

      diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index d5171cbae..b543b9ee5 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -194,6 +194,7 @@ GameStatus GamePhase(bool insideMenu) UpdateBlood(); UpdateBubbles(); UpdateDebris(); + UpdateGunFlashes(); UpdateGunShells(); UpdateFootprints(); UpdateSplashes(); diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp index c97fd5a8b..12bd28a61 100644 --- a/TombEngine/Game/effects/tomb4fx.cpp +++ b/TombEngine/Game/effects/tomb4fx.cpp @@ -941,6 +941,52 @@ void TriggerGunShell(short hand, short objNum, LaraWeaponType weaponType) } } +void UpdateGunFlashes() +{ + if (Lara.Control.Weapon.GunType == LaraWeaponType::None) + return; + + const auto& settings = g_GameFlow->GetSettings()->Weapons[(int)Lara.Control.Weapon.GunType - 1]; + + if (!settings.MuzzleGlow) + return; + + for (int hand = 0; hand < 2; hand++) + { + if ((hand ? Lara.RightArm.GunFlash : Lara.LeftArm.GunFlash) == 0) + continue; + + auto& part = *GetFreeParticle(); + + part.on = true; + part.SpriteSeqID = ID_DEFAULT_SPRITES; + part.SpriteID = 11; + part.blendMode = BlendMode::Additive; + + auto pos = GetJointPosition(LaraItem, hand ? LM_RHAND : LM_LHAND, settings.MuzzleOffset.ToVector3i()); + part.x = pos.x; + part.y = pos.y; + part.z = pos.z; + part.roomNumber = LaraItem->RoomNumber; + + part.sSize = part.size = part.dSize = 192; + part.scalar = 2; + + part.xVel = part.yVel = part.zVel = 0; + part.gravity = part.friction = part.maxYvel = 0; + + part.sR = part.dR = settings.FlashColor.GetR() / 2; + part.sG = part.dG = settings.FlashColor.GetG() / 2; + part.sB = part.dB = settings.FlashColor.GetB() / 2; + + part.life = part.sLife = 2; + part.colFadeSpeed = 1; + part.fadeToBlack = 1; + + part.flags = SP_SCALE | SP_DEF | SP_EXPDEF; + } +} + void UpdateGunShells() { for (int i = 0; i < MAX_GUNSHELL; i++) diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h index b65f8b41e..629d4e4bc 100644 --- a/TombEngine/Game/effects/tomb4fx.h +++ b/TombEngine/Game/effects/tomb4fx.h @@ -323,6 +323,7 @@ void TriggerBlood(int x, int y, int z, int unk, int num); void UpdateBlood(); int GetFreeGunshell(); void TriggerGunShell(short hand, short objNum, LaraWeaponType weaponType); +void UpdateGunFlashes(); void UpdateGunShells(); void AddWaterSparks(int x, int y, int z, int num); void ExplodingDeath(short itemNumber, short flags); // BODY_ flags diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index 341a7f986..f068a8fd1 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -2824,12 +2824,8 @@ namespace TEN::Renderer } else { - BindTexture( - TextureRegister::ColorMap, &std::get<0>(_roomTextures[bucket.Texture]), - SamplerStateRegister::AnisotropicClamp); - BindTexture( - TextureRegister::NormalMap, &std::get<1>(_roomTextures[bucket.Texture]), - SamplerStateRegister::AnisotropicClamp); + BindTexture(TextureRegister::ColorMap, &std::get<0>(_roomTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp); + BindTexture(TextureRegister::NormalMap, &std::get<1>(_roomTextures[bucket.Texture]), SamplerStateRegister::AnisotropicClamp); } DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0); diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp index cb903c2f6..04104ca09 100644 --- a/TombEngine/Renderer/RendererDrawEffect.cpp +++ b/TombEngine/Renderer/RendererDrawEffect.cpp @@ -1085,50 +1085,13 @@ namespace TEN::Renderer if (!settings.MuzzleFlash) return false; - short length = 0; - short zOffset = 0; - short rotationX = 0; - if (Lara.Control.Weapon.GunType != LaraWeaponType::Flare && Lara.Control.Weapon.GunType != LaraWeaponType::Crossbow) { - switch (Lara.Control.Weapon.GunType) - { - case LaraWeaponType::Revolver: - length = 192; - zOffset = 68; - rotationX = -14560; - break; - - case LaraWeaponType::Uzi: - length = 190; - zOffset = 50; - rotationX = -14560; - break; - - case LaraWeaponType::HK: - case LaraWeaponType::Shotgun: - length = 300; - zOffset = 92; - rotationX = -14560; - break; - - default: - case LaraWeaponType::Pistol: - length = 180; - zOffset = 40; - rotationX = -16830; - break; - } - // Use MP5 flash if available. auto gunflash = GAME_OBJECT_ID::ID_GUN_FLASH; if (Lara.Control.Weapon.GunType == LaraWeaponType::HK && Objects[GAME_OBJECT_ID::ID_GUN_FLASH2].loaded) - { gunflash = GAME_OBJECT_ID::ID_GUN_FLASH2; - length += 20; - zOffset += 10; - } if (!_moveableObjects[gunflash].has_value()) return false; @@ -1167,8 +1130,8 @@ namespace TEN::Renderer BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[flashBucket.Texture]), SamplerStateRegister::AnisotropicClamp); - auto tMatrix = Matrix::CreateTranslation(0, length, zOffset); - auto rotMatrix = Matrix::CreateRotationX(TO_RAD(rotationX)); + auto tMatrix = Matrix::CreateTranslation(settings.MuzzleOffset); + auto rotMatrix = Matrix::CreateRotationX(TO_RAD(Lara.Control.Weapon.GunType == LaraWeaponType::Pistol ? -16830 : -14560)); // HACK auto worldMatrix = Matrix::Identity; if (Lara.LeftArm.GunFlash) diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp index 51cda08ee..88637ce35 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp @@ -25,15 +25,15 @@ namespace TEN::Scripting // NOTE: Since Weapons array is bound to Lua directly and Lua accesses this array by native enum, where 0 is NONE, and 1 is PISTOLS, // 0 index is omitted due to Lua indexing arrays starting from 1. 1 must be subtracted from initializer index. - Weapons[(int)LaraWeaponType::Pistol - 1] = { 8.0f, BLOCK(8), 9, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 3, true, true, true, false }; - Weapons[(int)LaraWeaponType::Revolver - 1] = { 4.0f, BLOCK(8), 16, (int)BLOCK(0.65f), 21, 21, 6, ScriptColor(192, 128, 0), 9, 3, true, false, true, false }; - Weapons[(int)LaraWeaponType::Uzi - 1] = { 8.0f, BLOCK(8), 3, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 2, true, true, true, false }; - Weapons[(int)LaraWeaponType::Shotgun - 1] = { 10.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 3, 3, 6, ScriptColor(192, 128, 0), 12, 3, true, true, false, false }; - Weapons[(int)LaraWeaponType::HK - 1] = { 4.0f, BLOCK(12), 0, (int)BLOCK(0.50f), 4, 4, 30, ScriptColor(192, 128, 0), 12, 2, true, true, true, false }; - Weapons[(int)LaraWeaponType::Crossbow - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 5, 20, 10, ScriptColor(192, 128, 0), 0, 0, false, false, false, false }; - Weapons[(int)LaraWeaponType::GrenadeLauncher - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 30, 30, 10, ScriptColor(192, 128, 0), 0, 0, true, false, false, false }; - Weapons[(int)LaraWeaponType::RocketLauncher - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 30, 30, 1, ScriptColor(192, 128, 0), 0, 0, true, false, false, false }; - Weapons[(int)LaraWeaponType::HarpoonGun - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 6, 6, 10, ScriptColor(192, 128, 0), 0, 0, false, false, false, false }; + Weapons[(int)LaraWeaponType::Pistol - 1] = { 8.0f, BLOCK(8), 9, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 3, true, true, true, true, false, Vec3(0, 180, 40) }; + Weapons[(int)LaraWeaponType::Revolver - 1] = { 4.0f, BLOCK(8), 16, (int)BLOCK(0.65f), 21, 21, 6, ScriptColor(192, 128, 0), 9, 3, true, false, true, true, false, Vec3(0, 192, 68) }; + Weapons[(int)LaraWeaponType::Uzi - 1] = { 8.0f, BLOCK(8), 3, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 2, true, true, true, true, false, Vec3(0, 190, 50) }; + Weapons[(int)LaraWeaponType::Shotgun - 1] = { 10.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 3, 3, 6, ScriptColor(192, 128, 0), 12, 3, true, true, false, false, false, Vec3(0, 300, 92) }; + Weapons[(int)LaraWeaponType::HK - 1] = { 4.0f, BLOCK(12), 0, (int)BLOCK(0.50f), 4, 4, 30, ScriptColor(192, 128, 0), 12, 2, true, true, true, true, false, Vec3(0, 320, 102) }; + Weapons[(int)LaraWeaponType::Crossbow - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 5, 20, 10, ScriptColor(192, 128, 0), 0, 0, false, false, false, false, false, Vec3() }; + Weapons[(int)LaraWeaponType::GrenadeLauncher - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 30, 30, 10, ScriptColor(192, 128, 0), 0, 0, true, false, false, false, false, Vec3() }; + Weapons[(int)LaraWeaponType::RocketLauncher - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 30, 30, 1, ScriptColor(192, 128, 0), 0, 0, true, false, false, false, false, Vec3() }; + Weapons[(int)LaraWeaponType::HarpoonGun - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 6, 6, 10, ScriptColor(192, 128, 0), 0, 0, false, false, false, false, false, Vec3() }; } void Settings::Register(sol::table& parent) @@ -309,9 +309,17 @@ namespace TEN::Scripting // @tfield bool muzzleFlash specifies whether muzzle flash should be displayed or not. Applicable only for firearms. "muzzleFlash", &WeaponSettings::MuzzleFlash, + /// Display muzzle glow. + // @tfield bool muzzleGlow specifies whether muzzle glow should be displayed or not. Applicable only for firearms. + "muzzleGlow", &WeaponSettings::MuzzleGlow, + /// Colorize muzzle flash. // @tfield bool colorizeMuzzleFlash specifies whether muzzle flash should be tinted with the same color as gunflash color. Applicable only for firearms. - "colorizeMuzzleFlash", &WeaponSettings::ColorizeMuzzleFlash); + "colorizeMuzzleFlash", &WeaponSettings::ColorizeMuzzleFlash, + + /// Muzzle offset. + // @tfield Vec3 muzzleOffset specifies offset for spawning muzzle gunflash effects. Applicable only for firearms. + "muzzleOffset", &WeaponSettings::MuzzleOffset); } /// System diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.h b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.h index 7b2d962ad..f4f110141 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.h +++ b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.h @@ -103,7 +103,9 @@ namespace TEN::Scripting bool Smoke = false; bool Shell = false; bool MuzzleFlash = true; + bool MuzzleGlow = true; bool ColorizeMuzzleFlash = false; + Vec3 MuzzleOffset = {}; static void Register(sol::table& parent); }; From ba166aa6fa72943e19e23b9cc7e6ae719ce9e2b7 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 9 Apr 2025 09:48:40 +0200 Subject: [PATCH 44/53] Randomize glow angle --- TombEngine/Game/effects/tomb4fx.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp index 12bd28a61..b100e8ed3 100644 --- a/TombEngine/Game/effects/tomb4fx.cpp +++ b/TombEngine/Game/effects/tomb4fx.cpp @@ -969,6 +969,9 @@ void UpdateGunFlashes() part.z = pos.z; part.roomNumber = LaraItem->RoomNumber; + part.rotAng = ANGLE(TO_DEGREES(Random::GenerateAngle())) >> 4; + part.rotAdd = 0; + part.sSize = part.size = part.dSize = 192; part.scalar = 2; From c81feb7da14d430786622f59207d732b587bdc76 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Wed, 9 Apr 2025 23:47:12 +0200 Subject: [PATCH 45/53] Dehardcode gun smoke positions, calculate gunflash offset --- TombEngine/Game/Lara/lara_one_gun.cpp | 29 ++++--------------- TombEngine/Game/Lara/lara_two_guns.cpp | 21 ++------------ TombEngine/Renderer/RendererDrawEffect.cpp | 6 +++- .../Internal/TEN/Flow/Settings/Settings.cpp | 10 +++---- 4 files changed, 17 insertions(+), 49 deletions(-) diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index 32b7d60bf..d651388ea 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -68,27 +68,6 @@ constexpr auto HK_RAPID_MODE_SHOT_INTERVAL = 3.0f; constexpr auto SHOTGUN_PELLET_COUNT = 6; -static Vector3i GetWeaponSmokeRelOffset(LaraWeaponType weaponType) -{ - switch (weaponType) - { - case LaraWeaponType::HK: - return Vector3i(0, 228, 96); - - case LaraWeaponType::Shotgun: - return Vector3i(0, 228, 0); - - case LaraWeaponType::GrenadeLauncher: - return Vector3i(0, 180, 80); - - case LaraWeaponType::RocketLauncher: - return Vector3i(0, 84, 72);; - - default: - return Vector3i::Zero; - } -} - void AnimateShotgun(ItemInfo& laraItem, LaraWeaponType weaponType) { auto& player = *GetLaraInfo(&laraItem); @@ -96,7 +75,7 @@ void AnimateShotgun(ItemInfo& laraItem, LaraWeaponType weaponType) if (player.LeftArm.GunSmoke > 0) { - auto relOffset = GetWeaponSmokeRelOffset(weaponType); + auto relOffset = g_GameFlow->GetSettings()->Weapons[(int)weaponType - 1].MuzzleOffset.ToVector3(); auto pos = GetJointPosition(&laraItem, LM_RHAND, relOffset); if (laraItem.MeshBits.TestAny()) @@ -411,8 +390,10 @@ void FireShotgun(ItemInfo& laraItem) if (!ammo.HasInfinite()) ammo--; - auto pos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(0, 1508, 32)); - auto pos2 = GetJointPosition(&laraItem, LM_RHAND, Vector3i(0, 228, 32)); + auto offset = g_GameFlow->GetSettings()->Weapons[(int)LaraWeaponType::Shotgun].MuzzleOffset.ToVector3i(); + + auto pos = GetJointPosition(&laraItem, LM_RHAND, offset + Vector3::UnitY * CLICK(2)); + auto pos2 = GetJointPosition(&laraItem, LM_RHAND, offset); player.LeftArm.GunSmoke = 32; diff --git a/TombEngine/Game/Lara/lara_two_guns.cpp b/TombEngine/Game/Lara/lara_two_guns.cpp index a044c4282..48a26e200 100644 --- a/TombEngine/Game/Lara/lara_two_guns.cpp +++ b/TombEngine/Game/Lara/lara_two_guns.cpp @@ -45,24 +45,6 @@ static WeaponAnimData GetWeaponAnimData(LaraWeaponType weaponType) return ((it != ANIM_DATA_MAP.end()) ? it->second : ANIM_DATA_MAP.at(LaraWeaponType::None)); } -static Vector3i GetWeaponSmokeRelOffset(LaraWeaponType weaponType, bool isRightWeapon) -{ - switch (weaponType) - { - case LaraWeaponType::Pistol: - return Vector3i(isRightWeapon ? -16 : 4, 128, 40); - - case LaraWeaponType::Revolver: - return Vector3i(isRightWeapon ? -32 : 16, 160, 56); - - case LaraWeaponType::Uzi: - return Vector3i(isRightWeapon ? -16 : 8, 140, 48); - - default: - return Vector3i::Zero; - } -} - static void SetArmInfo(const ItemInfo& laraItem, ArmInfo& arm, int frame) { const auto& player = GetLaraInfo(laraItem); @@ -118,8 +100,9 @@ static void AnimateWeapon(ItemInfo& laraItem, LaraWeaponType weaponType, bool& h // Spawn weapon smoke. if (laraItem.MeshBits.TestAny() && arm.GunSmoke) { - auto relOffset = GetWeaponSmokeRelOffset(weaponType, isRightWeapon); + auto relOffset = g_GameFlow->GetSettings()->Weapons[(int)weaponType - 1].MuzzleOffset.ToVector3(); auto pos = GetJointPosition(&laraItem, isRightWeapon ? LM_RHAND : LM_LHAND, relOffset); + TriggerGunSmoke(pos.x, pos.y, pos.z, 0, 0, 0, 0, weaponType, arm.GunSmoke); } diff --git a/TombEngine/Renderer/RendererDrawEffect.cpp b/TombEngine/Renderer/RendererDrawEffect.cpp index 04104ca09..ce6ed8034 100644 --- a/TombEngine/Renderer/RendererDrawEffect.cpp +++ b/TombEngine/Renderer/RendererDrawEffect.cpp @@ -1130,7 +1130,11 @@ namespace TEN::Renderer BindTexture(TextureRegister::ColorMap, &std::get<0>(_moveablesTextures[flashBucket.Texture]), SamplerStateRegister::AnisotropicClamp); - auto tMatrix = Matrix::CreateTranslation(settings.MuzzleOffset); + + auto meshOffset = g_Level.Frames[GetAnimData(gunflash, 0).FramePtr].Offset; + auto offset = settings.MuzzleOffset + Vector3(meshOffset.x, meshOffset.z, meshOffset.y); // Offsets are inverted because of bone orientation. + + auto tMatrix = Matrix::CreateTranslation(offset); auto rotMatrix = Matrix::CreateRotationX(TO_RAD(Lara.Control.Weapon.GunType == LaraWeaponType::Pistol ? -16830 : -14560)); // HACK auto worldMatrix = Matrix::Identity; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp index 88637ce35..cb65ca8d7 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp @@ -25,11 +25,11 @@ namespace TEN::Scripting // NOTE: Since Weapons array is bound to Lua directly and Lua accesses this array by native enum, where 0 is NONE, and 1 is PISTOLS, // 0 index is omitted due to Lua indexing arrays starting from 1. 1 must be subtracted from initializer index. - Weapons[(int)LaraWeaponType::Pistol - 1] = { 8.0f, BLOCK(8), 9, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 3, true, true, true, true, false, Vec3(0, 180, 40) }; - Weapons[(int)LaraWeaponType::Revolver - 1] = { 4.0f, BLOCK(8), 16, (int)BLOCK(0.65f), 21, 21, 6, ScriptColor(192, 128, 0), 9, 3, true, false, true, true, false, Vec3(0, 192, 68) }; - Weapons[(int)LaraWeaponType::Uzi - 1] = { 8.0f, BLOCK(8), 3, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 2, true, true, true, true, false, Vec3(0, 190, 50) }; - Weapons[(int)LaraWeaponType::Shotgun - 1] = { 10.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 3, 3, 6, ScriptColor(192, 128, 0), 12, 3, true, true, false, false, false, Vec3(0, 300, 92) }; - Weapons[(int)LaraWeaponType::HK - 1] = { 4.0f, BLOCK(12), 0, (int)BLOCK(0.50f), 4, 4, 30, ScriptColor(192, 128, 0), 12, 2, true, true, true, true, false, Vec3(0, 320, 102) }; + Weapons[(int)LaraWeaponType::Pistol - 1] = { 8.0f, BLOCK(8), 9, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 3, true, true, true, true, false, Vec3( 0, 120, 30) }; + Weapons[(int)LaraWeaponType::Revolver - 1] = { 4.0f, BLOCK(8), 16, (int)BLOCK(0.65f), 21, 21, 6, ScriptColor(192, 128, 0), 9, 3, true, false, true, true, false, Vec3(-10, 130, 45) }; + Weapons[(int)LaraWeaponType::Uzi - 1] = { 8.0f, BLOCK(8), 3, (int)BLOCK(0.65f), 1, 1, 30, ScriptColor(192, 128, 0), 9, 2, true, true, true, true, false, Vec3( 0, 110, 40) }; + Weapons[(int)LaraWeaponType::Shotgun - 1] = { 10.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 3, 3, 6, ScriptColor(192, 128, 0), 12, 3, true, true, false, false, false, Vec3( 0, 210, 42) }; + Weapons[(int)LaraWeaponType::HK - 1] = { 4.0f, BLOCK(12), 0, (int)BLOCK(0.50f), 4, 4, 30, ScriptColor(192, 128, 0), 12, 2, true, true, true, true, false, Vec3( 0, 220, 102) }; Weapons[(int)LaraWeaponType::Crossbow - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 5, 20, 10, ScriptColor(192, 128, 0), 0, 0, false, false, false, false, false, Vec3() }; Weapons[(int)LaraWeaponType::GrenadeLauncher - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 30, 30, 10, ScriptColor(192, 128, 0), 0, 0, true, false, false, false, false, Vec3() }; Weapons[(int)LaraWeaponType::RocketLauncher - 1] = { 8.0f, BLOCK(8), 0, (int)BLOCK(0.50f), 30, 30, 1, ScriptColor(192, 128, 0), 0, 0, true, false, false, false, false, Vec3() }; From ee5147eb4f0d18d83c42f14334dfc25abeb3de4b Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 10 Apr 2025 21:23:34 +0200 Subject: [PATCH 46/53] Fixed spamming of HK sound effects --- CHANGELOG.md | 1 + TombEngine/Game/Lara/lara_one_gun.cpp | 7 ++----- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5f5d1329..2fd24b052 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed Wraith objects not working correctly in flipped rooms. * Fixed caustics not rendered correctly if texture compression was enabled. * Fixed exclusion blend mode not working correctly. +* Fixed HK sound effects. ### New features * Added muzzle glow effect for firearms. diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index d651388ea..3dcefb301 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -231,9 +231,8 @@ void AnimateShotgun(ItemInfo& laraItem, LaraWeaponType weaponType) player.Control.Weapon.Timer = 0.0f; } } - else if (player.Control.Weapon.Timer != 0.0f) + else if (weaponType == LaraWeaponType::HK && player.Control.Weapon.Timer != 0.0f) { - SoundEffect(SFX_TR4_EXPLOSION1, &laraItem.Pose, SoundEnvironment::Land, 1.0f, 0.4f); SoundEffect(SFX_TR4_HK_FIRE, &laraItem.Pose); } else if (weaponType == LaraWeaponType::Shotgun && !IsHeld(In::Action) && !player.LeftArm.Locked) @@ -312,9 +311,8 @@ void AnimateShotgun(ItemInfo& laraItem, LaraWeaponType weaponType) player.Control.Weapon.Timer = 0.0f; } } - else if (player.Control.Weapon.Timer != 0.0f) + else if (weaponType == LaraWeaponType::HK && player.Control.Weapon.Timer != 0.0f) { - SoundEffect(SFX_TR4_EXPLOSION1, &laraItem.Pose, SoundEnvironment::Land, 1.0f, 0.4f); SoundEffect(SFX_TR4_HK_FIRE, &laraItem.Pose); } @@ -1233,7 +1231,6 @@ void LasersightWeaponHandler(ItemInfo& item, LaraWeaponType weaponType) if (playSound) { - SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f); SoundEffect(SFX_TR4_HK_FIRE, nullptr); Camera.bounce = -16 - (GetRandomControl() & 0x1F); } From 218299193fc9b1b01aa5ccb9e60e93410396e442 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Fri, 11 Apr 2025 03:11:05 +0200 Subject: [PATCH 47/53] Another method for SSAO fix --- CHANGELOG.md | 1 + TombEngine/Renderer/RendererDraw.cpp | 6 +----- TombEngine/Shaders/InstancedStatics.fx | 3 +++ TombEngine/Shaders/Items.fx | 3 +++ TombEngine/Shaders/Rooms.fx | 3 +++ 5 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fd24b052..47356f0a8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed Wraith objects not working correctly in flipped rooms. * Fixed caustics not rendered correctly if texture compression was enabled. * Fixed exclusion blend mode not working correctly. +* Fixed SSAO incorrectly applied through alpha blended textures. * Fixed HK sound effects. ### New features diff --git a/TombEngine/Renderer/RendererDraw.cpp b/TombEngine/Renderer/RendererDraw.cpp index f068a8fd1..1949fc062 100644 --- a/TombEngine/Renderer/RendererDraw.cpp +++ b/TombEngine/Renderer/RendererDraw.cpp @@ -3236,11 +3236,7 @@ namespace TEN::Renderer case RendererPass::GBuffer: if (blendMode != BlendMode::Opaque && blendMode != BlendMode::AlphaTest && - blendMode != BlendMode::FastAlphaBlend && - // WARNING: For G-Buffer step we consider alpha blend like alpha test - // assuming that most of the geometry used in rooms, items and statics - // are fences, foliages, trees... But it could fail with translucent surfaces! - blendMode != BlendMode::AlphaBlend) + blendMode != BlendMode::FastAlphaBlend) { return false; } diff --git a/TombEngine/Shaders/InstancedStatics.fx b/TombEngine/Shaders/InstancedStatics.fx index 26ed08921..e284579e9 100644 --- a/TombEngine/Shaders/InstancedStatics.fx +++ b/TombEngine/Shaders/InstancedStatics.fx @@ -110,6 +110,9 @@ PixelShaderOutput PS(PixelShaderInput input) samplePosition = samplePosition * 0.5f + 0.5f; samplePosition.y = 1.0f - samplePosition.y; occlusion = pow(SSAOTexture.Sample(SSAOSampler, samplePosition).x, AmbientOcclusionExponent); + + if (BlendMode == BLENDMODE_ALPHABLEND) + occlusion = lerp(occlusion, 1.0f, tex.w); } float3 color = (mode == 0) ? diff --git a/TombEngine/Shaders/Items.fx b/TombEngine/Shaders/Items.fx index c789da24c..d8a13d5dc 100644 --- a/TombEngine/Shaders/Items.fx +++ b/TombEngine/Shaders/Items.fx @@ -140,6 +140,9 @@ PixelShaderOutput PS(PixelShaderInput input) samplePosition = samplePosition * 0.5f + 0.5f; // transform to range 0.0 - 1.0 samplePosition.y = 1.0f - samplePosition.y; occlusion = pow(SSAOTexture.Sample(SSAOSampler, samplePosition).x, AmbientOcclusionExponent); + + if (BlendMode == BLENDMODE_ALPHABLEND) + occlusion = lerp(occlusion, 1.0f, tex.w); } float3 color = (BoneLightModes[input.Bone / 4][input.Bone % 4] == 0) ? diff --git a/TombEngine/Shaders/Rooms.fx b/TombEngine/Shaders/Rooms.fx index b1da5c9ec..619e18972 100644 --- a/TombEngine/Shaders/Rooms.fx +++ b/TombEngine/Shaders/Rooms.fx @@ -141,6 +141,9 @@ PixelShaderOutput PS(PixelShaderInput input) samplePosition = samplePosition * 0.5f + 0.5f; // transform to range 0.0 - 1.0 samplePosition.y = 1.0f - samplePosition.y; occlusion = pow(SSAOTexture.Sample(SSAOSampler, samplePosition).x, AmbientOcclusionExponent); + + if (BlendMode == BLENDMODE_ALPHABLEND) + occlusion = lerp(occlusion, 1.0f, output.Color.w); } lighting = DoShadow(input.WorldPosition, normal, lighting, -2.5f); From 0128660f0747d8f15046fef5ca59784e5277388f Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sat, 12 Apr 2025 17:27:06 +0200 Subject: [PATCH 48/53] Change LDoc to properly format optional arguments and defaults --- Documentation/compiler/ldoc/ldoc/doc.lua | 15 +++++++-------- .../compiler/ldoc/ldoc/html/ldoc_ltp.lua | 6 +++--- Documentation/ldoc.ltp | 6 +++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/Documentation/compiler/ldoc/ldoc/doc.lua b/Documentation/compiler/ldoc/ldoc/doc.lua index 30f8eafc5..52860ccba 100644 --- a/Documentation/compiler/ldoc/ldoc/doc.lua +++ b/Documentation/compiler/ldoc/ldoc/doc.lua @@ -868,20 +868,19 @@ function build_arg_list (names,pmods) local opt if m then if not m.optchain then - acc ((']'):rep(npending)) npending=0 end opt = m.optchain or m.opt - if opt then - acc('[') - npending=npending+1 - end end if i>1 then acc (', ') end - acc(names[i]) - if opt and opt ~= true then acc('='..opt) end + if opt then + acc('[' .. names[i]) + if opt ~= true then acc('='..opt) end + acc(']') + else + acc(names[i]) + end end - acc ((']'):rep(npending)) return '('..table.concat(buffer)..')' end diff --git a/Documentation/compiler/ldoc/ldoc/html/ldoc_ltp.lua b/Documentation/compiler/ldoc/ldoc/html/ldoc_ltp.lua index 31b09d72c..2efb79a43 100644 --- a/Documentation/compiler/ldoc/ldoc/html/ldoc_ltp.lua +++ b/Documentation/compiler/ldoc/ldoc/html/ldoc_ltp.lua @@ -215,12 +215,12 @@ return [==[ # end $(M(item.params.map[p],item)) # if def == true then - (optional) + (Optional.) # elseif def then - (default $(def)) + (Default. $(def)) # end # if item:readonly(p) then - readonly + Read-only. # end # end diff --git a/Documentation/ldoc.ltp b/Documentation/ldoc.ltp index 77472d077..5034016d4 100644 --- a/Documentation/ldoc.ltp +++ b/Documentation/ldoc.ltp @@ -216,12 +216,12 @@ # end $(M(item.params.map[p],item)) # if def == true then - (optional) + Optional. # elseif def then - (default $(def)) + Default: $(def). # end # if item:readonly(p) then - readonly + Read-only. # end # end From 73af37dbe15f194f50e828c8a5b6971da04a3cfb Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 13 Apr 2025 16:19:58 +0200 Subject: [PATCH 49/53] Fixed lensflare enabled status not saved in a savegame --- TombEngine/Game/savegame.cpp | 2 ++ .../flatbuffers/ten_savegame_generated.h | 30 ++++++++++++++----- .../Specific/savegame/schema/ten_savegame.fbs | 1 + 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index 8f3f1394c..26b41d8ad 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -1143,6 +1143,7 @@ const std::vector SaveGame::Build() levelData.add_sky_layer_2_color(level->GetSkyLayerColor(1)); levelData.add_sky_layer_2_speed(level->GetSkyLayerSpeed(1)); + levelData.add_lensflare_enabled(level->LensFlare.GetEnabled()); levelData.add_lensflare_color(level->LensFlare.GetColor()); levelData.add_lensflare_pitch(level->LensFlare.GetPitch()); levelData.add_lensflare_yaw(level->LensFlare.GetYaw()); @@ -1844,6 +1845,7 @@ static void ParseLua(const Save::SaveGame* s, bool hubMode) level->Layer2.CloudSpeed = s->level_data()->sky_layer_2_speed(); level->Layer2.SetColor(s->level_data()->sky_layer_2_color()); + level->LensFlare.SetEnabled(s->level_data()->lensflare_enabled()); level->LensFlare.SetSunSpriteID(s->level_data()->lensflare_sprite_id()); level->LensFlare.SetPitch(s->level_data()->lensflare_pitch()); level->LensFlare.SetYaw(s->level_data()->lensflare_yaw()); diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index a99d79882..3c85b7494 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h @@ -571,6 +571,7 @@ struct LevelDataT : public flatbuffers::NativeTable { std::unique_ptr horizon2_position{}; std::unique_ptr horizon2_orientation{}; float horizon2_transparency = 0.0f; + bool lensflare_enabled = false; int32_t lensflare_sprite_id = 0; float lensflare_pitch = 0.0f; float lensflare_yaw = 0.0f; @@ -610,14 +611,15 @@ struct LevelData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_HORIZON2_POSITION = 46, VT_HORIZON2_ORIENTATION = 48, VT_HORIZON2_TRANSPARENCY = 50, - VT_LENSFLARE_SPRITE_ID = 52, - VT_LENSFLARE_PITCH = 54, - VT_LENSFLARE_YAW = 56, - VT_LENSFLARE_COLOR = 58, - VT_STARFIELD_STAR_COUNT = 60, - VT_STARFIELD_METEOR_COUNT = 62, - VT_STARFIELD_METEOR_SPAWN_DENSITY = 64, - VT_STARFIELD_METEOR_VELOCITY = 66 + VT_LENSFLARE_ENABLED = 52, + VT_LENSFLARE_SPRITE_ID = 54, + VT_LENSFLARE_PITCH = 56, + VT_LENSFLARE_YAW = 58, + VT_LENSFLARE_COLOR = 60, + VT_STARFIELD_STAR_COUNT = 62, + VT_STARFIELD_METEOR_COUNT = 64, + VT_STARFIELD_METEOR_SPAWN_DENSITY = 66, + VT_STARFIELD_METEOR_VELOCITY = 68 }; int32_t level_far_view() const { return GetField(VT_LEVEL_FAR_VIEW, 0); @@ -691,6 +693,9 @@ struct LevelData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { float horizon2_transparency() const { return GetField(VT_HORIZON2_TRANSPARENCY, 0.0f); } + bool lensflare_enabled() const { + return GetField(VT_LENSFLARE_ENABLED, 0) != 0; + } int32_t lensflare_sprite_id() const { return GetField(VT_LENSFLARE_SPRITE_ID, 0); } @@ -741,6 +746,7 @@ struct LevelData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_HORIZON2_POSITION) && VerifyField(verifier, VT_HORIZON2_ORIENTATION) && VerifyField(verifier, VT_HORIZON2_TRANSPARENCY) && + VerifyField(verifier, VT_LENSFLARE_ENABLED) && VerifyField(verifier, VT_LENSFLARE_SPRITE_ID) && VerifyField(verifier, VT_LENSFLARE_PITCH) && VerifyField(verifier, VT_LENSFLARE_YAW) && @@ -832,6 +838,9 @@ struct LevelDataBuilder { void add_horizon2_transparency(float horizon2_transparency) { fbb_.AddElement(LevelData::VT_HORIZON2_TRANSPARENCY, horizon2_transparency, 0.0f); } + void add_lensflare_enabled(bool lensflare_enabled) { + fbb_.AddElement(LevelData::VT_LENSFLARE_ENABLED, static_cast(lensflare_enabled), 0); + } void add_lensflare_sprite_id(int32_t lensflare_sprite_id) { fbb_.AddElement(LevelData::VT_LENSFLARE_SPRITE_ID, lensflare_sprite_id, 0); } @@ -893,6 +902,7 @@ inline flatbuffers::Offset CreateLevelData( const TEN::Save::Vector3 *horizon2_position = 0, const TEN::Save::EulerAngles *horizon2_orientation = 0, float horizon2_transparency = 0.0f, + bool lensflare_enabled = false, int32_t lensflare_sprite_id = 0, float lensflare_pitch = 0.0f, float lensflare_yaw = 0.0f, @@ -928,6 +938,7 @@ inline flatbuffers::Offset CreateLevelData( builder_.add_weather_strength(weather_strength); builder_.add_weather_type(weather_type); builder_.add_level_far_view(level_far_view); + builder_.add_lensflare_enabled(lensflare_enabled); builder_.add_horizon2_enabled(horizon2_enabled); builder_.add_horizon1_enabled(horizon1_enabled); builder_.add_sky_layer_2_enabled(sky_layer_2_enabled); @@ -9260,6 +9271,7 @@ inline void LevelData::UnPackTo(LevelDataT *_o, const flatbuffers::resolver_func { auto _e = horizon2_position(); if (_e) _o->horizon2_position = std::unique_ptr(new TEN::Save::Vector3(*_e)); } { auto _e = horizon2_orientation(); if (_e) _o->horizon2_orientation = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } { auto _e = horizon2_transparency(); _o->horizon2_transparency = _e; } + { auto _e = lensflare_enabled(); _o->lensflare_enabled = _e; } { auto _e = lensflare_sprite_id(); _o->lensflare_sprite_id = _e; } { auto _e = lensflare_pitch(); _o->lensflare_pitch = _e; } { auto _e = lensflare_yaw(); _o->lensflare_yaw = _e; } @@ -9302,6 +9314,7 @@ inline flatbuffers::Offset CreateLevelData(flatbuffers::FlatBufferBui auto _horizon2_position = _o->horizon2_position ? _o->horizon2_position.get() : 0; auto _horizon2_orientation = _o->horizon2_orientation ? _o->horizon2_orientation.get() : 0; auto _horizon2_transparency = _o->horizon2_transparency; + auto _lensflare_enabled = _o->lensflare_enabled; auto _lensflare_sprite_id = _o->lensflare_sprite_id; auto _lensflare_pitch = _o->lensflare_pitch; auto _lensflare_yaw = _o->lensflare_yaw; @@ -9336,6 +9349,7 @@ inline flatbuffers::Offset CreateLevelData(flatbuffers::FlatBufferBui _horizon2_position, _horizon2_orientation, _horizon2_transparency, + _lensflare_enabled, _lensflare_sprite_id, _lensflare_pitch, _lensflare_yaw, diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs index bc41d27be..11d988d99 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -38,6 +38,7 @@ table LevelData { horizon2_orientation: EulerAngles; horizon2_transparency: float; + lensflare_enabled: bool; lensflare_sprite_id: int32; lensflare_pitch: float; lensflare_yaw: float; From 0d604678339363e1a806ef0baeac9d131e6a1c7e Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 13 Apr 2025 16:22:41 +0200 Subject: [PATCH 50/53] Fixed script API documentation mistakes --- Documentation/doc/3 primitive classes/Flow.LensFlare.html | 4 ++-- Documentation/doc/3 primitive classes/Vec2.html | 2 +- .../Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp | 2 +- TombEngine/Scripting/Internal/TEN/Types/Vec2/Vec2.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Documentation/doc/3 primitive classes/Flow.LensFlare.html b/Documentation/doc/3 primitive classes/Flow.LensFlare.html index 493f9432b..172afbfdf 100644 --- a/Documentation/doc/3 primitive classes/Flow.LensFlare.html +++ b/Documentation/doc/3 primitive classes/Flow.LensFlare.html @@ -127,7 +127,7 @@ - + @@ -178,7 +178,7 @@ spriteID
      - (Objects.ObjID.SpriteConstants) Lens flare's sun sprite object ID. + (int) Lens flare's sun sprite ID in DEFAULT_SPRITES sequence. diff --git a/Documentation/doc/3 primitive classes/Vec2.html b/Documentation/doc/3 primitive classes/Vec2.html index eb65b2271..4bedd88bf 100644 --- a/Documentation/doc/3 primitive classes/Vec2.html +++ b/Documentation/doc/3 primitive classes/Vec2.html @@ -354,7 +354,7 @@

      Parameters:

      • rot - Rotation + float Rotation in degrees defining the direction.
      • dist diff --git a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp index 564b278ef..c46eb7429 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/LensFlare/LensFlare.cpp @@ -30,7 +30,7 @@ namespace TEN::Scripting // @mem enabled "enabled", sol::property(&LensFlare::GetEnabled, &LensFlare::SetEnabled), - /// (@{Objects.ObjID.SpriteConstants}) Lens flare's sun sprite object ID. + /// (int) Lens flare's sun sprite ID in DEFAULT_SPRITES sequence. // @mem spriteID "spriteID", sol::property(&LensFlare::GetSunSpriteID, &LensFlare::SetSunSpriteID), diff --git a/TombEngine/Scripting/Internal/TEN/Types/Vec2/Vec2.cpp b/TombEngine/Scripting/Internal/TEN/Types/Vec2/Vec2.cpp index 33b8caac9..1f728dcb0 100644 --- a/TombEngine/Scripting/Internal/TEN/Types/Vec2/Vec2.cpp +++ b/TombEngine/Scripting/Internal/TEN/Types/Vec2/Vec2.cpp @@ -107,7 +107,7 @@ Vec2 Vec2::Translate(const Vec2& dir, float dist) /// Get a copy of this Vec2 translated in the direction of the input rotation in degrees by the input distance. // @function Vec2:Translate -// @tparam Rotation rot Rotation in degrees defining the direction. +// @tparam float rot Rotation in degrees defining the direction. // @tparam float dist Distance. // @treturn Vec2 Translated vector. Vec2 Vec2::Translate(float rot, float dist) From 394e71cb2b9c8d732881cba5bafd512f993154d8 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 13 Apr 2025 16:22:46 +0200 Subject: [PATCH 51/53] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 47356f0a8..5898fb6fe 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ TombEngine releases are located in this repository (alongside with Tomb Editor): * Fixed crashes when shooting, if gunflash or gunshell objects are not present in a level. * Fixed Teleporter object. * Fixed Wraith objects not working correctly in flipped rooms. +* Fixed lensflare enabled status not saved in a savegame. * Fixed caustics not rendered correctly if texture compression was enabled. * Fixed exclusion blend mode not working correctly. * Fixed SSAO incorrectly applied through alpha blended textures. From 821a4e844eab648588e67eab9894ef261ec1339b Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Sun, 13 Apr 2025 16:26:51 +0200 Subject: [PATCH 52/53] Fixed ldoc incorrectly displaying optional parameters --- Documentation/compiler/ldoc/ldoc/doc.lua | 6 +- Documentation/doc/1 modules/Effects.html | 112 +++++++++--------- Documentation/doc/1 modules/Flow.html | 10 +- Documentation/doc/1 modules/Input.html | 7 +- Documentation/doc/1 modules/Inventory.html | 14 +-- Documentation/doc/1 modules/Sound.html | 6 +- Documentation/doc/1 modules/Util.html | 6 +- Documentation/doc/1 modules/View.html | 12 +- .../doc/2 classes/Collision.Probe.html | 6 +- .../doc/2 classes/Objects.Camera.html | 2 +- .../doc/2 classes/Objects.LaraObject.html | 2 +- .../doc/2 classes/Objects.Moveable.html | 36 +++--- .../doc/2 classes/Strings.DisplayString.html | 10 +- .../doc/2 classes/View.DisplaySprite.html | 18 +-- .../5 lua utility modules/EventSequence.html | 6 +- .../doc/5 lua utility modules/Timer.html | 12 +- .../Internal/TEN/Input/InputHandler.cpp | 4 +- 17 files changed, 134 insertions(+), 135 deletions(-) diff --git a/Documentation/compiler/ldoc/ldoc/doc.lua b/Documentation/compiler/ldoc/ldoc/doc.lua index 52860ccba..e0325f4dc 100644 --- a/Documentation/compiler/ldoc/ldoc/doc.lua +++ b/Documentation/compiler/ldoc/ldoc/doc.lua @@ -846,7 +846,7 @@ end function build_arg_list (names,pmods) -- build up the string representation of the argument list, -- using any opt and optchain modifiers if present. - -- For instance, '(a [, b])' if b is marked as optional + -- For instance, '(a, [b])' if b is marked as optional -- with @param[opt] b local buffer, npending = { }, 0 local function acc(x) table.insert(buffer, x) end @@ -874,9 +874,7 @@ function build_arg_list (names,pmods) end if i>1 then acc (', ') end if opt then - acc('[' .. names[i]) - if opt ~= true then acc('='..opt) end - acc(']') + acc('[' .. names[i] .. ']') else acc(names[i]) end diff --git a/Documentation/doc/1 modules/Effects.html b/Documentation/doc/1 modules/Effects.html index d8d58667e..b8726289c 100644 --- a/Documentation/doc/1 modules/Effects.html +++ b/Documentation/doc/1 modules/Effects.html @@ -140,11 +140,11 @@
      - + - + @@ -152,7 +152,7 @@ - + @@ -172,7 +172,7 @@ - +
      spriteID(Objects.ObjID.SpriteConstants) Lens flare's sun sprite object ID.(int) Lens flare's sun sprite ID in DEFAULT_SPRITES sequence.
      pitch Emit a shockwave, similar to that seen when a harpy projectile hits something.
      EmitLight(pos[, color][, radius][, shadows][, name])EmitLight(pos, [color], [radius], [shadows], [name]) Emit dynamic light that lasts for a single frame.
      EmitSpotLight(pos, dir[, color][, radius][, falloff][, distance][, shadows][, name])EmitSpotLight(pos, dir, [color], [radius], [falloff], [distance], [shadows], [name]) Emit dynamic directional spotlight that lasts for a single frame.
      Emit blood.
      EmitAirBubble(pos[, size][, amp])EmitAirBubble(pos, [size], [amp]) Emit an air bubble in a water room.
      Get the wind vector for the current game frame.
      EmitStreamer(mov, tag, pos, dir[, rot][, startColor][, endColor][, width][, life][, vel][, expRate][, rotRate][, edgeFeatherMode][, lengthFeatherMode][, blendID])EmitStreamer(mov, tag, pos, dir, [rot], [startColor], [endColor], [width], [life], [vel], [expRate], [rotRate], [edgeFeatherMode], [lengthFeatherMode], [blendID]) Emit an extending streamer effect.
      @@ -454,7 +454,7 @@ EmitAdvancedParticle(particle)
    - EmitLight(pos[, color][, radius][, shadows][, name]) + EmitLight(pos, [color], [radius], [shadows], [name])
    Emit dynamic light that lasts for a single frame. @@ -471,22 +471,22 @@ EmitAdvancedParticle(particle)
  • color Color light color (default Color(255, 255, 255)) - (optional) + Optional.
  • radius int measured in "clicks" or 256 world units (default 20) - (optional) + Optional.
  • shadows bool determines whether light should generate dynamic shadows for applicable moveables (default is false) - (optional) + Optional.
  • name string if provided, engine will interpolate this light for high framerate mode (be careful not to use same name for different lights) - (optional) + Optional.
  • @@ -497,7 +497,7 @@ EmitAdvancedParticle(particle)
    - EmitSpotLight(pos, dir[, color][, radius][, falloff][, distance][, shadows][, name]) + EmitSpotLight(pos, dir, [color], [radius], [falloff], [distance], [shadows], [name])
    Emit dynamic directional spotlight that lasts for a single frame. @@ -518,32 +518,32 @@ EmitAdvancedParticle(particle)
  • color Color (default Color(255, 255, 255)) - (optional) + Optional.
  • radius int overall radius at the endpoint of a light cone, measured in "clicks" or 256 world units (default 10) - (optional) + Optional.
  • falloff int radius, at which light starts to fade out, measured in "clicks" (default 5) - (optional) + Optional.
  • distance int distance, at which light cone fades out, measured in "clicks" (default 20) - (optional) + Optional.
  • shadows bool determines whether light should generate dynamic shadows for applicable moveables (default is false) - (optional) + Optional.
  • name string if provided, engine will interpolate this light for high framerate mode (be careful not to use same name for different lights) - (optional) + Optional.
  • @@ -582,7 +582,7 @@ EmitAdvancedParticle(particle)
    - EmitAirBubble(pos[, size][, amp]) + EmitAirBubble(pos, [size], [amp])
    Emit an air bubble in a water room. @@ -598,12 +598,12 @@ EmitAdvancedParticle(particle)
  • size float Sprite size. Default: 32 - (optional) + Optional.
  • amp float Oscillation amplitude. Default: 32 - (optional) + Optional.
  • @@ -718,7 +718,7 @@ EmitAdvancedParticle(particle)
    - EmitStreamer(mov, tag, pos, dir[, rot][, startColor][, endColor][, width][, life][, vel][, expRate][, rotRate][, edgeFeatherMode][, lengthFeatherMode][, blendID]) + EmitStreamer(mov, tag, pos, dir, [rot], [startColor], [endColor], [width], [life], [vel], [expRate], [rotRate], [edgeFeatherMode], [lengthFeatherMode], [blendID])
    Emit an extending streamer effect. @@ -746,57 +746,57 @@ EmitAdvancedParticle(particle)
  • rot float Start rotation in degrees. Default: 0 - (optional) + Optional.
  • startColor Color Color at the start of life. Default: Color(255, 255, 255, 255)) - (optional) + Optional.
  • endColor Color Color at the end of life. Default: Color(0, 0, 0, 0)) - (optional) + Optional.
  • width float Width in world units. Default: 0 - (optional) + Optional.
  • life float Lifetime in seconds. Default: 1 - (optional) + Optional.
  • vel float Movement velocity in world units per second. Default: 0 - (optional) + Optional.
  • expRate float Width expansion rate in world units per second. Default: 0 - (optional) + Optional.
  • rotRate float Rotation rate in degrees per second. Default: 0 - (optional) + Optional.
  • edgeFeatherMode StreamerFeatherMode Edge feather mode. Default: Effects.StreamerFeatherMode.NONE - (optional) + Optional.
  • lengthFeatherMode StreamerFeatherMode Length feather mode. UNIMPLEMENTED, currently will always leave a fading tail - (optional) + Optional.
  • blendID BlendID Renderer blend ID. Default: Effects.BlendID.ALPHA_BLEND - (optional) + Optional.
  • @@ -831,127 +831,127 @@ EmitAdvancedParticle(particle)
  • spriteSeqID SpriteConstants Sprite sequence slot ID. default: Objects.ObjID.DEFAULT_SPRITES - (optional) + Optional.
  • spriteID int Sprite ID in the sprite sequence slot. default: 0 - (optional) + Optional.
  • life float Lifespan in seconds. default: 2 - (optional) + Optional.
  • maxYVel float Maximum vertical velocity in world units per second. default: 0 - (optional) + Optional.
  • gravity float Effect of gravity in world units per second. Positive value ascend, negative value descend. default: 0 - (optional) + Optional.
  • friction float Friction affecting velocity over time in world units per second. default: 0 - (optional) + Optional.
  • startRot float Rotation at start of life. default: random - (optional) + Optional.
  • rotVel float Rotational velocity in degrees per second. default: 0 - (optional) + Optional.
  • startSize float Size at start of life. default: 10 - (optional) + Optional.
  • endSize float Size at end of life. default: 0 - (optional) + Optional.
  • startColor Color Color at start of life. default: Color(255, 255, 255) - (optional) + Optional.
  • endColor Color Color at end of life. Note that this will finish long before the end of life due to internal math. default: Color(255, 255, 255) - (optional) + Optional.
  • blendMode BlendID Render blend mode. default: TEN.Effects.BlendID.ALPHA_BLEND - (optional) + Optional.
  • damage bool Harm the player on collision. default: false - (optional) + Optional.
  • poison bool Poison the player on collision. default: false - (optional) + Optional.
  • burn bool Burn the player on collision. default: false - (optional) + Optional.
  • wind bool Affect position by wind in outside rooms. default: false - (optional) + Optional.
  • damageHit int Player damage amount on collision. default: 2 - (optional) + Optional.
  • light bool Emit a colored light. CAUTION: Recommended only for a single particle. Too many particles with lights can overwhelm the lighting system. default: false - (optional) + Optional.
  • lightRadius int Light radius in 1/4 blocks. default: 0 - (optional) + Optional.
  • lightFlicker int Interval at which the light should flicker. default: 0 - (optional) + Optional.
  • soundID int Sound ID to play. CAUTION: Recommended only for a single particle. Too many particles with sounds can overwhelm the sound system. default: none - (optional) + Optional.
  • animated bool Play animates sprite sequence. default: false - (optional) + Optional.
  • animType ParticleAnimationType Animation type of the sprite sequence. default: TEN.Effects.ParticleAnimationType.LOOP - (optional) + Optional.
  • frameRate float Sprite sequence animation framerate. default: 1 - (optional) + Optional.
  • diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index a8ae0a9b0..4a680cba5 100644 --- a/Documentation/doc/1 modules/Flow.html +++ b/Documentation/doc/1 modules/Flow.html @@ -175,7 +175,7 @@ scripts too.

    Returns the level that the game control is running in that moment. - EndLevel([index][, startPos]) + EndLevel([index], [startPos]) Finishes the current level, with optional level index and start position index provided. @@ -570,7 +570,7 @@ have an ID of 0, the second an ID of 1, and so on.
    - EndLevel([index][, startPos]) + EndLevel([index], [startPos])
    Finishes the current level, with optional level index and start position index provided. @@ -585,12 +585,12 @@ teleported to such object with OCB similar to provided second argument.
  • index int level index (default 0) - (optional) + Optional.
  • startPos int player start position (default 0) - (optional) + Optional.
  • @@ -959,7 +959,7 @@ Must be an integer value (0 means no secrets).
  • index int Flipmap group ID to check. If no group specified or group is -1, function returns overall flipmap status (on or off). - (optional) + Optional.
  • diff --git a/Documentation/doc/1 modules/Input.html b/Documentation/doc/1 modules/Input.html index c3439c75c..7cf9f7de0 100644 --- a/Documentation/doc/1 modules/Input.html +++ b/Documentation/doc/1 modules/Input.html @@ -124,7 +124,7 @@

    Functions

    - + @@ -162,7 +162,7 @@
    - Vibrate(strength, time) + Vibrate(strength, [time])
    Vibrate the game controller if the function is available and the setting is on. @@ -177,7 +177,8 @@
  • time float - (default 0.3) Vibration time in seconds. + Vibration time in seconds. + Default: 0.3.
  • diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index 45a377928..1c069126b 100644 --- a/Documentation/doc/1 modules/Inventory.html +++ b/Documentation/doc/1 modules/Inventory.html @@ -124,11 +124,11 @@

    Functions

    Vibrate(strength, time)Vibrate(strength, [time]) Vibrate the game controller if the function is available and the setting is on.
    - + - + @@ -162,7 +162,7 @@
    - GiveItem(objectID[, count][, addToPickupSummary]) + GiveItem(objectID, [count], [addToPickupSummary])
    Add an item to the player's inventory. @@ -178,12 +178,12 @@
  • count int The amount of items to add. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack. - (optional) + Optional.
  • addToPickupSummary bool If true, display the item in the pickup summary. Default is false. - (optional) + Optional.
  • @@ -194,7 +194,7 @@
    - TakeItem(Object[, count]) + TakeItem(Object, [count])
    Remove an item from the player's inventory. @@ -210,7 +210,7 @@
  • count int The amount of items to remove. Default is the yield from a single pickup, e.g. 1 from a medipack, 12 from a flare pack. - (optional) + Optional.
  • diff --git a/Documentation/doc/1 modules/Sound.html b/Documentation/doc/1 modules/Sound.html index 6f1305b02..be07997d5 100644 --- a/Documentation/doc/1 modules/Sound.html +++ b/Documentation/doc/1 modules/Sound.html @@ -144,7 +144,7 @@
    - + @@ -291,7 +291,7 @@
    - PlaySound(soundID[, position]) + PlaySound(soundID, [position])
    Play sound effect. @@ -307,7 +307,7 @@
  • position Vec3 The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional. - (optional) + Optional.
  • diff --git a/Documentation/doc/1 modules/Util.html b/Documentation/doc/1 modules/Util.html index a9b7c3972..4981e18db 100644 --- a/Documentation/doc/1 modules/Util.html +++ b/Documentation/doc/1 modules/Util.html @@ -152,7 +152,7 @@
    - +
    GiveItem(objectID[, count][, addToPickupSummary])GiveItem(objectID, [count], [addToPickupSummary]) Add an item to the player's inventory.
    TakeItem(Object[, count])TakeItem(Object, [count]) Remove an item from the player's inventory.
    Get current loudness level for specified track type.
    PlaySound(soundID[, position])PlaySound(soundID, [position]) Play sound effect.
    Pick a static mesh by the given display position.
    PrintLog(message, logLevel[, allowSpam])PrintLog(message, logLevel, [allowSpam]) Write messages within the Log file
    @@ -414,7 +414,7 @@ To be used with - PrintLog(message, logLevel[, allowSpam]) + PrintLog(message, logLevel, [allowSpam])
    Write messages within the Log file @@ -439,7 +439,7 @@ To be used with allowSpam bool true allows spamming of the message - (optional) + Optional. diff --git a/Documentation/doc/1 modules/View.html b/Documentation/doc/1 modules/View.html index 557e35756..51c5b824e 100644 --- a/Documentation/doc/1 modules/View.html +++ b/Documentation/doc/1 modules/View.html @@ -176,11 +176,11 @@ Play a flyby sequence. - GetFlybyPosition(seqID, progress[, loop]) + GetFlybyPosition(seqID, progress, [loop]) Get a flyby sequence's position at a specified progress point in percent. - GetFlybyRotation(seqID, progress[, loop]) + GetFlybyRotation(seqID, progress, [loop]) Get a flyby sequence's rotation at a specified progress point in percent. @@ -499,7 +499,7 @@
    - GetFlybyPosition(seqID, progress[, loop]) + GetFlybyPosition(seqID, progress, [loop])
    Get a flyby sequence's position at a specified progress point in percent. @@ -519,7 +519,7 @@
  • loop bool Smooth the position near start and end points, as if the sequence is looped. - (optional) + Optional.
  • @@ -536,7 +536,7 @@
    - GetFlybyRotation(seqID, progress[, loop]) + GetFlybyRotation(seqID, progress, [loop])
    Get a flyby sequence's rotation at a specified progress point in percent. @@ -556,7 +556,7 @@
  • loop bool Smooth the position near start and end points, as if the sequence is looped. - (optional) + Optional.
  • diff --git a/Documentation/doc/2 classes/Collision.Probe.html b/Documentation/doc/2 classes/Collision.Probe.html index 19c7f4ec2..f10d87d34 100644 --- a/Documentation/doc/2 classes/Collision.Probe.html +++ b/Documentation/doc/2 classes/Collision.Probe.html @@ -122,7 +122,7 @@

    Functions

    - + @@ -220,7 +220,7 @@
    - Probe(pos[, roomNumber]) + Probe(pos, [roomNumber])
    Create a Probe at a specified world position in a room. @@ -236,7 +236,7 @@
  • roomNumber int Room number. Must be used if probing a position in an overlapping room. - (optional) + Optional.
  • diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html index 630d1a44f..3ca2f2939 100644 --- a/Documentation/doc/2 classes/Objects.Camera.html +++ b/Documentation/doc/2 classes/Objects.Camera.html @@ -330,7 +330,7 @@
  • Target Moveable If you put a moveable, the camera will look at it. Otherwise, it will look at Lara. - (optional) + Optional.
  • diff --git a/Documentation/doc/2 classes/Objects.LaraObject.html b/Documentation/doc/2 classes/Objects.LaraObject.html index 41fefa5bc..7192dc620 100644 --- a/Documentation/doc/2 classes/Objects.LaraObject.html +++ b/Documentation/doc/2 classes/Objects.LaraObject.html @@ -229,7 +229,7 @@
  • poison int Poison strength. Maximum value is 128 (default 0) - (optional) + Optional.
  • diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 45f4fa252..5810dedcc 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -166,13 +166,13 @@
    - + - + @@ -217,11 +217,11 @@ - + - + @@ -285,7 +285,7 @@ - + @@ -364,7 +364,7 @@ if it is not swapped. - + @@ -741,7 +741,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
    - Moveable:SetPosition(position[, updateRoom]) + Moveable:SetPosition(position, [updateRoom])
    Set the moveable's position @@ -760,7 +760,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
  • updateRoom bool Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true) - (optional) + Optional.
  • @@ -771,7 +771,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
    - Moveable:GetJointPosition(jointIndex[, offset]) + Moveable:GetJointPosition(jointIndex, [offset])
    Get the moveable's joint position with an optional relative offset. @@ -787,7 +787,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
  • offset Vec3 Offset relative to the joint. - (optional) + Optional.
  • @@ -1026,7 +1026,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
    - Moveable:SetEffect(effect[, timeout]) + Moveable:SetEffect(effect, [timeout])
    Set the effect for this moveable. @@ -1042,7 +1042,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
  • timeout float time (in seconds) after which effect turns off. - (optional) + Optional.
  • @@ -1053,7 +1053,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
    - Moveable:SetCustomEffect(color1, color2[, timeout]) + Moveable:SetCustomEffect(color1, color2, [timeout])
    Set custom colored burn effect to moveable @@ -1073,7 +1073,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
  • timeout float Time (in seconds) after which effect turns off. - (optional) + Optional.
  • @@ -1423,7 +1423,7 @@ sas:SetAIBits({1, 0,
    - Moveable:SetAnim(index[, slot]) + Moveable:SetAnim(index, [slot])
    Set the object's animation to the one specified by the given index. @@ -1441,7 +1441,7 @@ sas:SetAIBits({1, 0, slot int slot ID of the desired anim (if omitted, moveable's own slot ID is used) - (optional) + Optional. @@ -1857,7 +1857,7 @@ sas:SetPosition(newPos, false)
    - Moveable:SwapMesh(index, slotIndex[, swapIndex]) + Moveable:SwapMesh(index, slotIndex, [swapIndex])
    Set state of specified mesh swap of object @@ -1878,7 +1878,7 @@ sas:SetPosition(newPos, false)
  • swapIndex int index of a mesh from meshswap slot to use - (optional) + Optional.
  • diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html index d4b209327..4f1088fad 100644 --- a/Documentation/doc/2 classes/Strings.DisplayString.html +++ b/Documentation/doc/2 classes/Strings.DisplayString.html @@ -129,7 +129,7 @@ when you need to use screen-space coordinates.

    Functions

    Probe(pos[, roomNumber])Probe(pos, [roomNumber]) Create a Probe at a specified world position in a room.
    Get the moveable's position
    Moveable:SetPosition(position[, updateRoom])Moveable:SetPosition(position, [updateRoom]) Set the moveable's position If you are moving a moveable whose behaviour involves knowledge of room geometry, (e.g.
    Moveable:GetJointPosition(jointIndex[, offset])Moveable:GetJointPosition(jointIndex, [offset]) Get the moveable's joint position with an optional relative offset.
    Set OCB (object code bit) of the moveable
    Moveable:SetEffect(effect[, timeout])Moveable:SetEffect(effect, [timeout]) Set the effect for this moveable.
    Moveable:SetCustomEffect(color1, color2[, timeout])Moveable:SetCustomEffect(color1, color2, [timeout]) Set custom colored burn effect to moveable
    Retrieve the index of the current animation.
    Moveable:SetAnim(index[, slot])Moveable:SetAnim(index, [slot]) Set the object's animation to the one specified by the given index.
    Moveable:SwapMesh(index, slotIndex[, swapIndex])Moveable:SwapMesh(index, slotIndex, [swapIndex]) Set state of specified mesh swap of object Use this to swap specified mesh of an object.
    - + @@ -183,7 +183,7 @@ when you need to use screen-space coordinates.

    - DisplayString(string, Position[, scale][, color][, translated], table) + DisplayString(string, Position, [scale], [color], [translated], table)
    Create a DisplayString. @@ -204,18 +204,18 @@ For use in ShowString and scale float size of the string, relative to the default size. Default: 1.0 - (optional) + Optional.
  • color Color the color of the text. Default: white - (optional) + Optional.
  • translated bool If false or omitted, the input string argument will be displayed. If true, the string argument will be the key of a translated string specified in strings.lua. Default: false. - (optional) + Optional.
  • table DisplayStringOption diff --git a/Documentation/doc/2 classes/View.DisplaySprite.html b/Documentation/doc/2 classes/View.DisplaySprite.html index f6f4917b7..2b097a9bb 100644 --- a/Documentation/doc/2 classes/View.DisplaySprite.html +++ b/Documentation/doc/2 classes/View.DisplaySprite.html @@ -124,7 +124,7 @@

    Functions

  • DisplayString(string, Position[, scale][, color][, translated], table)DisplayString(string, Position, [scale], [color], [translated], table) Create a DisplayString.
    - + @@ -176,7 +176,7 @@ - +
    DisplaySprite(ID, int, pos, rot, scale[, color])DisplaySprite(ID, int, pos, rot, scale, [color]) Create a DisplaySprite object.
    Set the color of the display sprite.
    DisplaySprite:Draw([priority][, alignMode][, scaleMode][, blendMode])DisplaySprite:Draw([priority], [alignMode], [scaleMode], [blendMode]) Draw the display sprite in display space for the current frame.
    @@ -190,7 +190,7 @@
    - DisplaySprite(ID, int, pos, rot, scale[, color]) + DisplaySprite(ID, int, pos, rot, scale, [color])
    Create a DisplaySprite object. () @@ -222,7 +222,7 @@
  • color Color Color. Default: Color(255, 255, 255, 255) - (optional) + Optional.
  • @@ -497,7 +497,7 @@
    - DisplaySprite:Draw([priority][, alignMode][, scaleMode][, blendMode]) + DisplaySprite:Draw([priority], [alignMode], [scaleMode], [blendMode])
    Draw the display sprite in display space for the current frame. @@ -509,22 +509,22 @@
  • priority int Draw priority. Can be thought of as a layer, with higher values having precedence. Default: 0 - (optional) + Optional.
  • alignMode AlignMode Align mode interpreting an offset from the sprite's position. Default: View.AlignMode.CENTER - (optional) + Optional.
  • scaleMode ScaleMode Scale mode interpreting the display sprite's horizontal and vertical scale. Default: View.ScaleMode.FIT - (optional) + Optional.
  • blendMode BlendID Blend mode. Default: Effects.BlendID.ALPHABLEND - (optional) + Optional.
  • diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index cea188d4f..e0557249c 100644 --- a/Documentation/doc/5 lua utility modules/EventSequence.html +++ b/Documentation/doc/5 lua utility modules/EventSequence.html @@ -168,7 +168,7 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)

    Functions

    - + @@ -206,7 +206,7 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
    - Create(name, loop, timerFormat[, ...]) + Create(name, loop, timerFormat, [...])
    Create (but do not start) a new event sequence. @@ -229,7 +229,7 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
  • ... a variable number of pairs of arguments - a time in seconds, followed by the function (must be defined in the LevelFuncs table) to call once the time has elapsed, followed by another duration in seconds, another function name, etc. You can specify a function either by its name as a string, or by a table with the function name as the first member, followed by its arguments (see above example). - (optional) + Optional.
  • diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index 5cff92477..2bdecfa5e 100644 --- a/Documentation/doc/5 lua utility modules/Timer.html +++ b/Documentation/doc/5 lua utility modules/Timer.html @@ -152,7 +152,7 @@ LevelFuncs.TriggerTimer = function(obj)

    Functions

    Create(name, loop, timerFormat[, ...])Create(name, loop, timerFormat, [...]) Create (but do not start) a new event sequence.
    - + @@ -160,7 +160,7 @@ LevelFuncs.TriggerTimer = function(obj) - + @@ -214,7 +214,7 @@ LevelFuncs.TriggerTimer = function(obj)
    - Create(name, totalTime, loop, timerFormat, func[, ...]) + Create(name, totalTime, loop, timerFormat, func, [...])
    Create (but do not start) a new timer.

    @@ -267,7 +267,7 @@ LevelFuncs.TriggerTimer = function(obj)
  • ... a variable number of arguments with which the above function will be called - (optional) + Optional.
  • @@ -312,7 +312,7 @@ LevelFuncs.TriggerTimer = function(obj)
    - myTimer:SetFunction(func[, ...]) + myTimer:SetFunction(func, [...])
    Give the timer a new function and args @@ -327,7 +327,7 @@ LevelFuncs.TriggerTimer = function(obj)
  • ... a variable number of arguments with which the above function will be called - (optional) + Optional.
  • diff --git a/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp b/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp index 2352d3c35..f68607d88 100644 --- a/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Input/InputHandler.cpp @@ -19,8 +19,8 @@ namespace TEN::Scripting::Input { /// Vibrate the game controller if the function is available and the setting is on. // @function Vibrate - // @tparam float strength Vibration strength. - // @tparam float time __(default 0.3)__ Vibration time in seconds. + // @tparam float strength Vibration strength. + // @tparam[opt=0.3] float time Vibration time in seconds. static void Vibrate(float strength, sol::optional time) { Rumble(strength, time.value_or(0.3f), RumbleMode::Both); From ef9ba4a40dc2dd3395726eee32f2ca1e8997e46b Mon Sep 17 00:00:00 2001 From: Stranger1992 <84292688+Stranger1992@users.noreply.github.com> Date: Sun, 13 Apr 2025 21:02:49 +0100 Subject: [PATCH 53/53] Updated Diary docs --- Scripts/Engine/CustomDiary.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/Engine/CustomDiary.lua b/Scripts/Engine/CustomDiary.lua index e62e2424d..20b029c37 100644 --- a/Scripts/Engine/CustomDiary.lua +++ b/Scripts/Engine/CustomDiary.lua @@ -531,9 +531,9 @@ end -- @tparam Objects.ObjID objectIdBg Object ID for the diary's sprite. -- @tparam int spriteIdBg SpriteID from the specified object for the diary's sprite. -- @tparam Color colorBg Color of diary's sprite. --- @tparam Vec2 pos X,Y position of the bar's background in screen percent (0-100). +-- @tparam Vec2 pos X,Y position of the diary background sprite in screen percent (0-100). -- @tparam float rot rotation of the diary's sprite (0-360). --- @tparam Vec2 scale X,Y Scaling factor for the bar's background sprite. +-- @tparam Vec2 scale X,Y Scaling factor for the diary background sprite. -- @tparam View.AlignMode alignMode Alignment for the diary's sprite. -- @tparam View.ScaleMode scaleMode Scaling for the diary's sprite. -- @tparam Effects.BlendID blendMode Blending modes for the diary's sprite.
    Create(name, totalTime, loop, timerFormat, func[, ...])Create(name, totalTime, loop, timerFormat, func, [...]) Create (but do not start) a new timer.
    Get a timer by its name.
    myTimer:SetFunction(func[, ...])myTimer:SetFunction(func, [...]) Give the timer a new function and args