diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fe88a532..a1be08042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,26 @@ 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](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8.1) - 2025-03-29 + +### 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. +* 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. + ## [Version 1.8](https://github.com/TombEngine/TombEditorReleases/releases/tag/v1.8) - 2025-03-16 ### Bug fixes @@ -24,7 +44,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 @@ -73,7 +93,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. @@ -123,7 +143,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. @@ -199,7 +219,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 @@ -259,7 +279,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: @@ -306,7 +326,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. @@ -365,7 +385,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. @@ -448,7 +468,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. @@ -496,7 +516,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. @@ -554,7 +574,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. @@ -603,7 +623,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: @@ -655,7 +675,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. @@ -707,7 +727,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. @@ -721,7 +741,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). @@ -793,7 +813,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. @@ -861,7 +881,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. @@ -916,7 +936,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/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 45b15294c..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -784,12 +784,12 @@ EmitAdvancedParticle(particle) (optional)
  • edgeFeatherMode - Effects.StreamerFeatherMode - Edge feather mode. Default: Effects.FeatherID.NONE + StreamerFeatherMode + Edge feather mode. Default: Effects.StreamerFeatherMode.NONE (optional)
  • lengthFeatherMode - Effects.StreamerFeatherMode + StreamerFeatherMode Length feather mode. UNIMPLEMENTED, currently will always leave a fading tail (optional)
  • diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index a8af377fd..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Input.html b/Documentation/doc/1 modules/Input.html index d895fb863..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index 2aad7fda5..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index fa7dc6e57..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Objects.html b/Documentation/doc/1 modules/Objects.html index fa8430af0..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Sound.html b/Documentation/doc/1 modules/Sound.html index 76d850aa4..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html index fe511f379..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/Util.html b/Documentation/doc/1 modules/Util.html index 6365605b9..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/1 modules/View.html b/Documentation/doc/1 modules/View.html index 6e99c337d..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -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/Documentation/doc/2 classes/Collision.Probe.html b/Documentation/doc/2 classes/Collision.Probe.html index 8be1e951a..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -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. @@ -235,7 +235,8 @@
  • roomNumber int - [opt] Room number. Must be used if probing a position in an overlapping room. + Room number. Must be used if probing a position in an overlapping room. + (optional)
  • diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html index 6cb778133..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -473,7 +473,7 @@ Invisible

    e.g. myLevel.laraType = LaraType.Divesuit

    -

    (not yet fully implemented) +

    Not yet fully implemented. Only types Normal and Young are guaranteed to work. diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index 96e83ad22..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 @@ -80,7 +80,7 @@

  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -517,7 +517,7 @@
    • objectCollision bool - when enabled, camera will collide with moveables and statics. Disable or TR4-like camera behaviour. + when enabled, camera will collide with moveables and statics. Disable for TR4-like camera behaviour.
    @@ -1255,7 +1255,7 @@
    • errorMode ErrorMode - error mode to use. */ + error mode to use.
    @@ -1278,7 +1278,7 @@
    • multithreaded bool - determines whether to use multithreading or not. */ + determines whether to use multithreading or not.
    diff --git a/Documentation/doc/2 classes/Flow.Statistics.html b/Documentation/doc/2 classes/Flow.Statistics.html index fef4baf27..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.AIObject.html b/Documentation/doc/2 classes/Objects.AIObject.html index e3417bdff..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html index e5e8fde01..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.LaraObject.html b/Documentation/doc/2 classes/Objects.LaraObject.html index e9047c5de..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 6ef4a0404..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -130,7 +130,7 @@
    - + @@ -221,7 +221,7 @@ - + @@ -418,7 +418,7 @@ - +
    Probe(pos, roomNumber)Probe(pos[, roomNumber]) Create a Probe at a specified world position in a room.
    Retrieve the object ID
    Moveable:SetObjectID(ID)Moveable:SetObjectID(objectID) Change the object's ID.
    Set the effect for this moveable.
    Moveable:SetCustomEffect(Color1, Color2[, timeout])Moveable:SetCustomEffect(color1, color2[, timeout]) Set custom colored burn effect to moveable
    Attach camera to an object.
    Moveable:AnimFromObject(ObjectID, animNumber, stateID)Moveable:AnimFromObject(objectID, animNumber, stateID) Borrow animation from an object
    @@ -518,7 +518,7 @@ most can just be ignored (see usage).
      ObjID - a number representing the ID of the object + a number representing the ID of the object.
    @@ -527,7 +527,7 @@ most can just be ignored (see usage).
    - Moveable:SetObjectID(ID) + Moveable:SetObjectID(objectID)
    Change the object's ID. This will literally change the object. @@ -536,7 +536,7 @@ most can just be ignored (see usage).

    Parameters:

    - Moveable:SetCustomEffect(Color1, Color2[, timeout]) + Moveable:SetCustomEffect(color1, color2[, timeout])
    Set custom colored burn effect to moveable @@ -1062,17 +1062,17 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)

    Parameters:

    @@ -1096,7 +1096,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided)
      EffectID - Sffect type currently assigned. + Effect type currently assigned.
    @@ -1116,7 +1116,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided) @@ -1144,11 +1144,11 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided) @@ -1191,7 +1191,7 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided) @@ -1248,18 +1248,22 @@ baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided) Moveable:GetAIBits()
    - Get AIBits of object + +

    Get AIBits of object This will return a table with six values, each corresponding to an active behaviour. If the object is in a certain AI mode, the table will have a 1 in the corresponding cell. Otherwise, the cell will hold a 0.

    -


    1 - guard -
    2 - ambush -
    3 - patrol 1 -
    4 - modify -
    5 - follow -
    6 - patrol 2 +

    1 - Guard
    +2 - Ambush
    +3 - Patrol 1
    +4 - Modify
    +5 - Follow
    +6 - Patrol 2
    +
    + + @@ -1681,7 +1685,7 @@ sas:SetPosition(newPos, false) Moveable:GetStatus()
    - Get the moveable's status. () + Get the moveable's status. @@ -1702,7 +1706,7 @@ sas:SetPosition(newPos, false) Moveable:SetStatus(status)
    - Set the moveable's status. () + Set the moveable's status. @@ -2103,15 +2107,15 @@ sas:SetPosition(newPos, false) @@ -2122,7 +2126,7 @@ sas:SetPosition(newPos, false)
    - Moveable:AnimFromObject(ObjectID, animNumber, stateID) + Moveable:AnimFromObject(objectID, animNumber, stateID)
    Borrow animation from an object @@ -2131,17 +2135,17 @@ sas:SetPosition(newPos, false)

    Parameters:

    diff --git a/Documentation/doc/2 classes/Objects.Room.html b/Documentation/doc/2 classes/Objects.Room.html index 1b36cd4bb..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.Sink.html b/Documentation/doc/2 classes/Objects.Sink.html index 0ba93f4a6..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.SoundSource.html b/Documentation/doc/2 classes/Objects.SoundSource.html index 4f658cb93..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.Static.html b/Documentation/doc/2 classes/Objects.Static.html index 5259af90f..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Objects.Volume.html b/Documentation/doc/2 classes/Objects.Volume.html index 5db162a3e..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html index f1f29c123..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/2 classes/View.DisplaySprite.html b/Documentation/doc/2 classes/View.DisplaySprite.html index 9f9c723fa..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html index a54514919..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Flow.Fog.html b/Documentation/doc/3 primitive classes/Flow.Fog.html index f8dd36f4d..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -127,11 +127,11 @@ minDistance - (int) Minimum distance. + (float) Minimum distance. maxDistance - (int) Maximum distance. + (float) Maximum distance.

    Functions

    @@ -171,8 +171,8 @@ minDistance
    - (int) Minimum distance. - This is the distance at which the fog starts. + (float) Minimum distance. + This is the distance at which the fog starts (in sectors). @@ -187,8 +187,8 @@ maxDistance
    - (int) Maximum distance. - This is the distance at which the fog reaches the maximum strength. + (float) Maximum distance. + This is the distance at which the fog reaches the maximum strength (in sectors). diff --git a/Documentation/doc/3 primitive classes/Flow.Horizon.html b/Documentation/doc/3 primitive classes/Flow.Horizon.html index 4d9d69be1..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Flow.InventoryItem.html b/Documentation/doc/3 primitive classes/Flow.InventoryItem.html index 2623737c0..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Flow.LensFlare.html b/Documentation/doc/3 primitive classes/Flow.LensFlare.html index 5c666ea9d..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Flow.SkyLayer.html b/Documentation/doc/3 primitive classes/Flow.SkyLayer.html index 27427363c..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Flow.Starfield.html b/Documentation/doc/3 primitive classes/Flow.Starfield.html index 0efed6489..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html index 7fad8cac1..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Time.html b/Documentation/doc/3 primitive classes/Time.html index c51d6a015..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Vec2.html b/Documentation/doc/3 primitive classes/Vec2.html index 2cef44350..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/3 primitive classes/Vec3.html b/Documentation/doc/3 primitive classes/Vec3.html index 15a50a1dc..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/4 enums/Collision.MaterialType.html b/Documentation/doc/4 enums/Collision.MaterialType.html index 4d6bd8af7..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/4 enums/Effects.BlendID.html b/Documentation/doc/4 enums/Effects.BlendID.html index 55662a65e..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/4 enums/Effects.EffectID.html b/Documentation/doc/4 enums/Effects.EffectID.html index 62e5adfcc..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/4 enums/Effects.ParticleAnimationType.html b/Documentation/doc/4 enums/Effects.ParticleAnimationType.html index 35ac618af..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 @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • diff --git a/Documentation/doc/4 enums/Effects.FeatherMode.html b/Documentation/doc/4 enums/Effects.StreamerFeatherMode.html similarity index 93% rename from Documentation/doc/4 enums/Effects.FeatherMode.html rename to Documentation/doc/4 enums/Effects.StreamerFeatherMode.html index c0534f46f..47692e9c5 100644 --- a/Documentation/doc/4 enums/Effects.FeatherMode.html +++ b/Documentation/doc/4 enums/Effects.StreamerFeatherMode.html @@ -3,7 +3,7 @@ - TombEngine 1.8 Lua API + TombEngine 1.8.1 Lua API @@ -80,7 +80,7 @@
  • Collision.MaterialType
  • Effects.BlendID
  • Effects.EffectID
  • -
  • Effects.FeatherMode
  • +
  • Effects.StreamerFeatherMode
  • Effects.ParticleAnimationType
  • Flow.ErrorMode
  • Flow.FreezeMode
  • @@ -114,7 +114,7 @@
    -

    Enum Effects.FeatherMode

    +

    Enum Effects.StreamerFeatherMode

    Constants for feather modes.

    @@ -124,8 +124,8 @@

    Tables

    - - + +
    Effects.FeatherModeTable of Effects.FeatherMode constants.Effects.StreamerFeatherModeTable of Effects.StreamerFeatherMode constants.
    @@ -137,12 +137,12 @@
    - - Effects.FeatherMode + + Effects.StreamerFeatherMode
    -

    Table of Effects.FeatherMode constants. +

    Table of Effects.StreamerFeatherMode constants. To be used with Effects.EmitStreamer function.

      diff --git a/Documentation/doc/4 enums/Flow.ErrorMode.html b/Documentation/doc/4 enums/Flow.ErrorMode.html index 2c34b0af0..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Flow.FreezeMode.html b/Documentation/doc/4 enums/Flow.FreezeMode.html index 3cedf2c1b..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Flow.GameStatus.html b/Documentation/doc/4 enums/Flow.GameStatus.html index c6ceaed62..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Input.ActionID.html b/Documentation/doc/4 enums/Input.ActionID.html index 7543a8366..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Objects.AmmoType.html b/Documentation/doc/4 enums/Objects.AmmoType.html index cd2bd79ad..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Objects.HandStatus.html b/Documentation/doc/4 enums/Objects.HandStatus.html index e5bd505b2..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Objects.MoveableStatus.html b/Documentation/doc/4 enums/Objects.MoveableStatus.html index 9432736cc..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index 89f7433b4..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • @@ -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/Documentation/doc/4 enums/Objects.RoomFlagID.html b/Documentation/doc/4 enums/Objects.RoomFlagID.html index a180900b0..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Objects.RoomReverb.html b/Documentation/doc/4 enums/Objects.RoomReverb.html index 267676ff2..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Objects.WeaponType.html b/Documentation/doc/4 enums/Objects.WeaponType.html index bb8bd5eb7..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Sound.SoundTrackType.html b/Documentation/doc/4 enums/Sound.SoundTrackType.html index 09c61531c..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Strings.DisplayStringOption.html b/Documentation/doc/4 enums/Strings.DisplayStringOption.html index b7bb2d0ee..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/Util.LogLevel.html b/Documentation/doc/4 enums/Util.LogLevel.html index 3621c96d1..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/View.AlignMode.html b/Documentation/doc/4 enums/View.AlignMode.html index dbbd64adb..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/View.CameraType.html b/Documentation/doc/4 enums/View.CameraType.html index ff920be2f..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/View.PostProcessMode.html b/Documentation/doc/4 enums/View.PostProcessMode.html index c33764ce3..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/4 enums/View.ScaleMode.html b/Documentation/doc/4 enums/View.ScaleMode.html index e649a6403..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/5 lua utility modules/CustomBar.html b/Documentation/doc/5 lua utility modules/CustomBar.html index 7dcd65fe5..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/5 lua utility modules/Diary.html b/Documentation/doc/5 lua utility modules/Diary.html index 752fe3569..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index 3fa6249f6..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index cd52ae85b..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/5 lua utility modules/Type.html b/Documentation/doc/5 lua utility modules/Type.html index a16041ec9..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html index 2109237b0..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 @@ -80,7 +80,7 @@
    • Collision.MaterialType
    • Effects.BlendID
    • Effects.EffectID
    • -
    • Effects.FeatherMode
    • +
    • Effects.StreamerFeatherMode
    • Effects.ParticleAnimationType
    • Flow.ErrorMode
    • Flow.FreezeMode
    • @@ -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. @@ -305,7 +305,7 @@ local door = GetMoveableByName("door_type4_14") Constants for effect IDs. - Effects.FeatherMode + Effects.StreamerFeatherMode Constants for feather modes. 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. 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. diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp index 733989cb6..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; @@ -174,6 +175,7 @@ void InitializeGameFlags() FlipEffect = NO_VALUE; FlipStatus = false; + NumRPickups = 0; Camera.underwater = false; } @@ -199,6 +201,7 @@ void InitializeSpecialEffects() TEN::Entities::TR4::ClearBeetleSwarm(); TEN::Entities::Creatures::TR3::ClearFishSwarm(); + TEN::Effects::Fireflies::ClearFireflySwarm(); } void CustomObjects() @@ -208,6 +211,8 @@ void CustomObjects() void InitializeObjects() { + TENLog("Initializing objects...", LogLevel::Info); + AllocTR4Objects(); AllocTR5Objects(); @@ -250,10 +255,6 @@ void InitializeObjects() // User defined objects CustomObjects(); - HairEffect.Initialize(); - InitializeSpecialEffects(); - - NumRPickups = 0; CurrentSequence = 0; SequenceResults[0][1][2] = 0; SequenceResults[0][2][1] = 1; 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/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/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index 446dbac9c..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. @@ -389,6 +392,7 @@ GameStatus DoLevel(int levelIndex, bool loadGame) InitializeCamera(); InitializeSpotCamSequences(isTitle); InitializeItemBoxData(); + InitializeSpecialEffects(); // Initialize scripting. InitializeScripting(levelIndex, loadGame); 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/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 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/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/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/Trap/MovingLaser.cpp b/TombEngine/Objects/TR5/Trap/MovingLaser.cpp new file mode 100644 index 000000000..830d14746 --- /dev/null +++ b/TombEngine/Objects/TR5/Trap/MovingLaser.cpp @@ -0,0 +1,146 @@ +#include "framework.h" +#include "Objects/TR5/Trap/MovingLaser.h" + +#include "Game/animation.h" +#include "Game/collision/collide_item.h" +#include "Game/collision/collide_room.h" +#include "Game/collision/Point.h" +#include "Game/collision/Sphere.h" +#include "Game/control/control.h" +#include "Game/effects/effects.h" +#include "Game/effects/light.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Sound/sound.h" +#include "Specific/level.h" + +using namespace TEN::Collision::Sphere; + +namespace TEN::Entities::Traps +{ + constexpr auto MOVING_LASER_DAMAGE = 100; + constexpr auto MOVING_LASER_VELOCITY_MIN = 1.0f; + constexpr auto MOVING_LASER_ACCEL = 1.0f; + constexpr auto MOVING_LASER_PAUSE_FRAME_COUNT = 30; + + enum class MovingLaserFlags + { + Velocity, + PauseTimer, + DirectionSign, + DistanceTraveled, + VelocityCalc + }; + + void InitializeMovingLaser(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + 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)); + } + + void ControlMovingLaser(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + if (!TriggerActive(&item)) + return; + + // Calculate distances. + float moveDist = BLOCK(item.TriggerFlags) + BLOCK(0.5f); + float distPerFrame = (BLOCK(item.ItemFlags[(int)MovingLaserFlags::Velocity]) * 0.25f) / (float)FPS; + + item.Animation.ActiveState = 0; + + // TODO: Use SpawnDynamicPointLight(). + SpawnDynamicLight( + item.Pose.Position.x, item.Pose.Position.y - 64, item.Pose.Position.z, (Random::GenerateInt() % 2) + 8, + (Random::GenerateInt() % 4) + 24, Random::GenerateInt() % 4, Random::GenerateInt() % 2); + /*auto lightPos = item.Pose.Position.ToVector3() + Vector3(0.0f, -64, 0.0f); + auto lightColor = Color(Random::GenerateFloat(0.1f, 0.2f), Random::GenerateFloat(0.0f, 0.01f), Random::GenerateFloat(Random::GenerateFloat(0.0f, 0.01f))); + float lightFalloff = ?? + SpawnDynamicPointLight(lightPos, lightPos, lightFalloff);*/ + + // TODO: Demagic. + // Used for flicker. + item.MeshBits = -1 - (GetRandomControl() & 20); + + if (item.TriggerFlags == 0) + { + AnimateItem(&item); + return; + } + + if (item.ItemFlags[(int)MovingLaserFlags::PauseTimer] > 0) + { + item.ItemFlags[(int)MovingLaserFlags::PauseTimer]--; + if (item.ItemFlags[(int)MovingLaserFlags::PauseTimer] == 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)MovingLaserFlags::DirectionSign] * item.ItemFlags[(int)MovingLaserFlags::VelocityCalc])); + + item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] += item.ItemFlags[(int)MovingLaserFlags::VelocityCalc]; + + if (item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] < (moveDist - BLOCK(0.5f))) + { + item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] = std::min(distPerFrame, item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] + MOVING_LASER_ACCEL); + } + else + { + item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] = std::max(MOVING_LASER_VELOCITY_MIN, item.ItemFlags[(int)MovingLaserFlags::VelocityCalc] - MOVING_LASER_ACCEL); + } + + if (item.ItemFlags[(int)MovingLaserFlags::DistanceTraveled] >= moveDist) + { + item.ItemFlags[(int)MovingLaserFlags::PauseTimer] = MOVING_LASER_PAUSE_FRAME_COUNT; + } + + if (item.ItemFlags[(int)MovingLaserFlags::PauseTimer] == 0) + { + SoundEffect(SFX_TR5_MOVING_LASER_LOOP, &item.Pose, SoundEnvironment::Always); + } + + // Update room if necessary. + int roomNumber = GetPointCollision(item).GetRoomNumber(); + if (roomNumber != item.RoomNumber) + ItemNewRoom(itemNumber, roomNumber); + + AnimateItem(&item); + } + + void CollideMovingLaser(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) + { + auto& item = g_Level.Items[itemNumber]; + + // Collide with objects. + if (item.Status == ITEM_ACTIVE) + { + if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + return; + + HandleItemSphereCollision(item, *playerItem); + } + else if (item.Status != ITEM_INVISIBLE) + { + ObjectCollision(itemNumber, playerItem, coll); + } + + // Damage player. + if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + { + DoDamage(playerItem, MOVING_LASER_DAMAGE); + DoLotsOfBlood(playerItem->Pose.Position.x, playerItem->Pose.Position.y + CLICK(3), playerItem->Pose.Position.z, 4, playerItem->Pose.Orientation.y, playerItem->RoomNumber, 3); + playerItem->TouchBits.ClearAll(); + } + } +} diff --git a/TombEngine/Objects/TR5/Trap/tr5_movinglaser.h b/TombEngine/Objects/TR5/Trap/MovingLaser.h similarity index 100% rename from TombEngine/Objects/TR5/Trap/tr5_movinglaser.h rename to TombEngine/Objects/TR5/Trap/MovingLaser.h diff --git a/TombEngine/Objects/TR5/Trap/tr5_movinglaser.cpp b/TombEngine/Objects/TR5/Trap/tr5_movinglaser.cpp deleted file mode 100644 index 79d0b7bba..000000000 --- a/TombEngine/Objects/TR5/Trap/tr5_movinglaser.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "framework.h" -#include "Objects/TR5/Trap/tr5_movinglaser.h" - -#include "Game/animation.h" -#include "Game/collision/collide_item.h" -#include "Game/collision/collide_room.h" -#include "Game/collision/Point.h" -#include "Game/collision/Sphere.h" -#include "Game/control/control.h" -#include "Game/effects/effects.h" -#include "Game/effects/light.h" -#include "Game/items.h" -#include "Game/Lara/lara.h" -#include "Sound/sound.h" -#include "Math/Utils.h" -#include "Specific/level.h" - -using namespace TEN::Collision::Sphere; - -namespace TEN::Entities::Traps -{ - enum MovingLaserFlags - { - Speed, - PauseCounter, - Direction, - DistanceTravelled, - SpeedCalc - }; - - constexpr auto MOVING_LASER_DAMAGE = 100; - constexpr int PAUSE_FRAMES = 30; - constexpr float MAX_SPEED_THRESHOLD = 0.9f; - constexpr float MIN_SPEED = 1.0f; - constexpr float ACCELERATION = 1.0f; - - void InitializeMovingLaser(short itemNumber) - { - auto& item = g_Level.Items[itemNumber]; - item.ItemFlags[MovingLaserFlags::Direction] = 1; - item.ItemFlags[MovingLaserFlags::Speed] = 10; - item.Pose.Translate(item.Pose.Orientation, -CLICK(1)); // Offset by one click to make it dangerous at the edges of the block. - } - - void ControlMovingLaser(short itemNumber) - { - auto& item = g_Level.Items[itemNumber]; - - if (!TriggerActive(&item)) - return; - - float moveDistance = (BLOCK(1) * item.TriggerFlags) + CLICK(2); // Use OCB to calculate the distance and add 2 clicks. - - float distancePerFrame = ((float)(CLICK(1)) * item.ItemFlags[MovingLaserFlags::Speed]) / FPS; // Calculate distance per frame - - item.Animation.ActiveState = 0; - SpawnDynamicLight(item.Pose.Position.x, item.Pose.Position.y - 64, item.Pose.Position.z, (Random::GenerateInt() % 2) + 8, (Random::GenerateInt() % 4) + 24, Random::GenerateInt() % 4, Random::GenerateInt() % 2); - item.MeshBits = -1 - (GetRandomControl() & 0x14); // To make lasers flicker - - if (item.TriggerFlags == 0) - { - AnimateItem(&item); - return; - } - - if (item.ItemFlags[MovingLaserFlags::PauseCounter] > 0) - { - item.ItemFlags[MovingLaserFlags::PauseCounter]--; - - if (item.ItemFlags[MovingLaserFlags::PauseCounter] == 0) - { - item.ItemFlags[MovingLaserFlags::Direction] *= -1; - item.ItemFlags[MovingLaserFlags::DistanceTravelled] = 0; - } - - AnimateItem(&item); - return; - } - - item.Pose.Translate(item.Pose.Orientation, (item.ItemFlags[MovingLaserFlags::Direction] * item.ItemFlags[MovingLaserFlags::SpeedCalc])); - - item.ItemFlags[MovingLaserFlags::DistanceTravelled] += item.ItemFlags[MovingLaserFlags::SpeedCalc]; - - if (item.ItemFlags[DistanceTravelled] < (moveDistance -BLOCK(0.5f))) - item.ItemFlags[SpeedCalc] = std::min(distancePerFrame, item.ItemFlags[MovingLaserFlags::SpeedCalc] + ACCELERATION); - else - item.ItemFlags[SpeedCalc] = std::max(MIN_SPEED, item.ItemFlags[MovingLaserFlags::SpeedCalc] - ACCELERATION); - - - if (item.ItemFlags[MovingLaserFlags::DistanceTravelled] >= moveDistance) - { - item.ItemFlags[MovingLaserFlags::PauseCounter] = PAUSE_FRAMES; - } - - if (item.ItemFlags[MovingLaserFlags::PauseCounter] == 0) - { - SoundEffect(SFX_TR5_MOVING_LASER_LOOP, &item.Pose, SoundEnvironment::Always); - } - - // Update room if necessary. - short new_room = item.RoomNumber; - GetPointCollision(item).GetRoomNumber(); - if (new_room != item.RoomNumber) - ItemNewRoom(itemNumber, new_room); - - AnimateItem(&item); - } - - void CollideMovingLaser(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) - { - auto& item = g_Level.Items[itemNumber]; - - // Collide with objects. - if (item.Status == ITEM_ACTIVE) - { - if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) - return; - - HandleItemSphereCollision(item, *playerItem); - } - else if (item.Status != ITEM_INVISIBLE) - { - ObjectCollision(itemNumber, playerItem, coll); - } - - // Damage entity. - if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) - { - DoDamage(playerItem, MOVING_LASER_DAMAGE); - DoLotsOfBlood(playerItem->Pose.Position.x, playerItem->Pose.Position.y + CLICK(3), playerItem->Pose.Position.z, 4, playerItem->Pose.Orientation.y, playerItem->RoomNumber, 3); - playerItem->TouchBits.ClearAll(); - } - } -} diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp index 05921eb01..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" @@ -57,15 +58,15 @@ // Traps #include "Objects/Effects/EmberEmitter.h" -#include "Objects/Effects/tr5_electricity.h" #include "Objects/TR5/Trap/LaserBarrier.h" #include "Objects/TR5/Trap/LaserBeam.h" +#include "Objects/TR5/Trap/MovingLaser.h" #include "Objects/TR5/Trap/ZipLine.h" +#include "Objects/Effects/tr5_electricity.h" #include "Objects/TR5/Object/tr5_rollingball.h" #include "Objects/TR5/Trap/tr5_ventilator.h" #include "Objects/TR5/Trap/tr5_romehammer.h" #include "Objects/TR5/Trap/tr5_fallingceiling.h" -#include "Objects/TR5/Trap/tr5_movinglaser.h" #include "Objects/TR5/Trap/tr5_explosion.h" #include "Objects/TR5/Trap/tr5_wreckingball.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/ConstantBuffers/CameraMatrixBuffer.h b/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h index 9be9b953b..2ededb96b 100644 --- a/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h +++ b/TombEngine/Renderer/ConstantBuffers/CameraMatrixBuffer.h @@ -37,8 +37,8 @@ namespace TEN::Renderer::ConstantBuffers //-- Vector4 FogColor; //-- - int FogMinDistance; - int FogMaxDistance; + float FogMinDistance; + float FogMaxDistance; float NearPlane; float FarPlane; //-- 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 1c7a8d52d..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); @@ -1830,7 +1831,7 @@ namespace TEN::Renderer } else { - cameraConstantBuffer.FogMaxDistance = 0; + cameraConstantBuffer.FogMaxDistance = 0.0f; cameraConstantBuffer.FogColor = Vector4::Zero; } @@ -2571,6 +2572,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); 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/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); 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/Include/ScriptInterfaceLevel.h b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h index e091044b0..67d976b63 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h @@ -38,8 +38,8 @@ public: virtual WeatherType GetWeatherType() const = 0; virtual RGBAColor8Byte GetSkyLayerColor(int index) const = 0; virtual RGBAColor8Byte GetFogColor() const = 0; - virtual short GetFogMinDistance() const = 0; - virtual short GetFogMaxDistance() const = 0; + virtual float GetFogMinDistance() const = 0; + virtual float GetFogMaxDistance() const = 0; virtual short GetFarView() const = 0; virtual int GetSecrets() const = 0; virtual std::string GetAmbientTrack() const = 0; diff --git a/TombEngine/Scripting/Internal/TEN/Collision/Probe.cpp b/TombEngine/Scripting/Internal/TEN/Collision/Probe.cpp index 392410c40..b7295b7b9 100644 --- a/TombEngine/Scripting/Internal/TEN/Collision/Probe.cpp +++ b/TombEngine/Scripting/Internal/TEN/Collision/Probe.cpp @@ -26,6 +26,7 @@ namespace TEN::Scripting::Collision void Probe::Register(sol::table& parent) { using ctors = sol::constructors< + Probe(const Vec3&), Probe(const Vec3&, int), Probe(const Vec3&, int, const Vec3&, float), Probe(const Vec3&, int, const Rotation&, float), @@ -65,13 +66,17 @@ namespace TEN::Scripting::Collision /// Create a Probe at a specified world position in a room. // @function Probe // @tparam Vec3 pos World position. - // @tparam int roomNumber[opt] Room number. Must be used if probing a position in an overlapping room. + // @tparam[opt] int roomNumber Room number. Must be used if probing a position in an overlapping room. // @treturn Probe A new Probe. - Probe::Probe(const Vec3& pos, TypeOrNil roomNumber) + Probe::Probe(const Vec3& pos) { auto convertedPos = pos.ToVector3i(); - int roomNumberValue = ValueOr(roomNumber, FindRoomNumber(convertedPos)); - _pointCollision = GetPointCollision(convertedPos, roomNumberValue); + _pointCollision = GetPointCollision(convertedPos, FindRoomNumber(convertedPos)); + } + + Probe::Probe(const Vec3& pos, int roomNumber) + { + _pointCollision = GetPointCollision(pos.ToVector3i(), roomNumber); } /// Create a Probe that casts from an origin world position in a room in a given direction for a specified distance. @@ -326,9 +331,9 @@ namespace TEN::Scripting::Collision // @function Preview void Probe::Preview() { - constexpr auto TARGET_RADIUS = 100.0f; - constexpr auto SPHERE_RADIUS = TARGET_RADIUS * 0.6f; - constexpr auto COLOR = Color(1.0f, 1.0f, 1.0f, 0.4f); + constexpr auto TARGET_RADIUS = BLOCK(0.08f); + constexpr auto SPHERE_RADIUS = TARGET_RADIUS * 0.4f; + constexpr auto COLOR = Color(1.0f, 1.0f, 0.8f, 0.2f); constexpr auto DEBUG_PAGE = RendererDebugPage::CollisionStats; auto pos = _pointCollision.GetPosition().ToVector3(); diff --git a/TombEngine/Scripting/Internal/TEN/Collision/Probe.h b/TombEngine/Scripting/Internal/TEN/Collision/Probe.h index 86fb90459..d96a78ed8 100644 --- a/TombEngine/Scripting/Internal/TEN/Collision/Probe.h +++ b/TombEngine/Scripting/Internal/TEN/Collision/Probe.h @@ -31,7 +31,8 @@ namespace TEN::Scripting::Collision // Constructors Probe() = default; - Probe(const Vec3& pos, TypeOrNil roomNumber); + Probe(const Vec3& pos); + Probe(const Vec3& pos, int roomNumber); Probe(const Vec3& origin, int roomNumber, const Vec3& dir, float dist); Probe(const Vec3& origin, int roomNumber, const Rotation& rot, float dist); Probe(const Vec3& origin, int roomNumber, const Rotation& rot, const Vec3& relOffset); diff --git a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp index d65853268..ba5dc17e9 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp +++ b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp @@ -551,7 +551,7 @@ namespace TEN::Scripting::Effects // @tparam[opt] float vel Movement velocity in world units per second. __Default: 0__ // @tparam[opt] float expRate Width expansion rate in world units per second. __Default: 0__ // @tparam[opt] float rotRate Rotation rate in degrees per second. __Default: 0__ - // @tparam[opt] Effects.StreamerFeatherMode edgeFeatherMode Edge feather mode. __Default: Effects.FeatherID.NONE__ + // @tparam[opt] Effects.StreamerFeatherMode edgeFeatherMode Edge feather mode. __Default: Effects.StreamerFeatherMode.NONE__ // @tparam[opt] Effects.StreamerFeatherMode lengthFeatherMode Length feather mode. __UNIMPLEMENTED, currently will always leave a fading tail__ // @tparam[opt] Effects.BlendID blendID Renderer blend ID. __Default: Effects.BlendID.ALPHA_BLEND__ static void EmitStreamer(const Moveable& mov, TypeOrNil tag, const Vec3& pos, const Vec3& dir, TypeOrNil rot, TypeOrNil startColor, TypeOrNil endColor, diff --git a/TombEngine/Scripting/Internal/TEN/Effects/FeatherModes.h b/TombEngine/Scripting/Internal/TEN/Effects/FeatherModes.h index f0571f4eb..7c83d80b3 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/FeatherModes.h +++ b/TombEngine/Scripting/Internal/TEN/Effects/FeatherModes.h @@ -3,10 +3,10 @@ #include "Game/effects/Streamer.h" /// Constants for feather modes. -// @enum Effects.FeatherMode +// @enum Effects.StreamerFeatherMode // @pragma nostrip -/// Table of Effects.FeatherMode constants. +/// Table of Effects.StreamerFeatherMode constants. // To be used with @{Effects.EmitStreamer} function. // // - `NONE` @@ -14,7 +14,7 @@ // - `LEFT` // - `RIGHT` // -// @table Effects.FeatherMode +// @table Effects.StreamerFeatherMode using namespace TEN::Effects::Streamer; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp index bb7612114..b269ff2cb 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp @@ -23,13 +23,13 @@ void Fog::Register(sol::table& parent) // @mem color "color", sol::property(&Fog::GetColor, &Fog::SetColor), - /// (int) Minimum distance. - // This is the distance at which the fog starts. + /// (float) Minimum distance. + // This is the distance at which the fog starts (in sectors). // @mem minDistance "minDistance", &Fog::MinDistance, - /// (int) Maximum distance. - // This is the distance at which the fog reaches the maximum strength. + /// (float) Maximum distance. + // This is the distance at which the fog reaches the maximum strength (in sectors). // @mem maxDistance "maxDistance", &Fog::MaxDistance ); @@ -42,7 +42,7 @@ void Fog::Register(sol::table& parent) @treturn Fog A fog object. @function Fog */ -Fog::Fog(ScriptColor const& col, short minDistance, short maxDistance) +Fog::Fog(ScriptColor const& col, float minDistance, float maxDistance) { SetColor(col); MinDistance = minDistance; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.h b/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.h index 6958e3041..dc21d7c97 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.h +++ b/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.h @@ -13,11 +13,11 @@ struct Fog byte R{ 0 }; byte G{ 0 }; byte B{ 0 }; - short MinDistance{ 0 }; - short MaxDistance{ 0 }; + float MinDistance{ 0 }; + float MaxDistance{ 0 }; Fog() = default; - Fog(ScriptColor const& color, short minDistance, short maxDistance); + Fog(ScriptColor const& color, float minDistance, float maxDistance); void SetColor(ScriptColor const& color); ScriptColor GetColor() const; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp index e722650bf..2b5c0aea8 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp @@ -106,7 +106,7 @@ These are: e.g. `myLevel.laraType = LaraType.Divesuit` - __(not yet fully implemented)__ + __Not yet fully implemented.__ Only types `Normal` and `Young` are guaranteed to work. @mem laraType*/ "laraType", &Level::Type, @@ -224,12 +224,12 @@ RGBAColor8Byte Level::GetFogColor() const return Fog.GetColor(); } -short Level::GetFogMinDistance() const +float Level::GetFogMinDistance() const { return Fog.MinDistance; } -short Level::GetFogMaxDistance() const +float Level::GetFogMaxDistance() const { return Fog.MaxDistance; } diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h index 4abfd5c23..dda7e23a1 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h +++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h @@ -64,8 +64,8 @@ struct Level : public ScriptInterfaceLevel void SetLevelFarView(short val); static void Register(sol::table& parent); WeatherType GetWeatherType() const override; - short GetFogMinDistance() const override; - short GetFogMaxDistance() const override; + float GetFogMinDistance() const override; + float GetFogMaxDistance() const override; short GetFarView() const override; void SetSecrets(int secrets); int GetSecrets() const override; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp index ba2cf5e71..51cda08ee 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp @@ -124,7 +124,7 @@ namespace TEN::Scripting "lasersightLightColor", &CameraSettings::LasersightLightColor, /// Specify whether camera can collide with objects. - // @tfield bool objectCollision when enabled, camera will collide with moveables and statics. Disable or TR4-like camera behaviour. + // @tfield bool objectCollision when enabled, camera will collide with moveables and statics. Disable for TR4-like camera behaviour. "objectCollision", &CameraSettings::ObjectCollision); } @@ -325,13 +325,13 @@ namespace TEN::Scripting sol::meta_function::new_index, NewIndexErrorMaker(SystemSettings, ScriptReserved_SystemSettings), /// How should the application respond to script errors? - // @tfield Flow.ErrorMode errorMode error mode to use. */ + // @tfield Flow.ErrorMode errorMode error mode to use. "errorMode", &SystemSettings::ErrorMode, /// Use multithreading in certain calculations.
      // When set to `true`, some performance-critical calculations will be performed in parallel, which can give // a significant performance boost. Don't disable unless you have problems with launching or using TombEngine. - // @tfield bool multithreaded determines whether to use multithreading or not. */ + // @tfield bool multithreaded determines whether to use multithreading or not. "multithreaded", &SystemSettings::Multithreaded, /// Can the game utilize the fast reload feature?
      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..cbc659d14 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -75,11 +75,14 @@ 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 +135,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/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 30fd28657..eb1ef5760 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -244,7 +244,7 @@ void Moveable::Initialize() /// Retrieve the object ID // @function Moveable:GetObjectID -// @treturn Objects.ObjID a number representing the ID of the object +// @treturn Objects.ObjID a number representing the ID of the object. GAME_OBJECT_ID Moveable::GetObjectID() const { return _moveable->ObjectNumber; @@ -252,7 +252,7 @@ GAME_OBJECT_ID Moveable::GetObjectID() const /// Change the object's ID. This will literally change the object. // @function Moveable:SetObjectID -// @tparam Objects.ObjID ID the new ID +// @tparam Objects.ObjID objectID the new ID // @usage // shiva = TEN.Objects.GetMoveableByName("shiva_60") // shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) @@ -432,7 +432,7 @@ void Moveable::SetPosition(const Vec3& pos, sol::optional updateRoom) // @function Moveable:GetJointPosition // @tparam int jointID Joint ID. // @tparam[opt] Vec3 offset Offset relative to the joint. -// @treturn Vec3 pos World position. +// @treturn Vec3 World position. Vec3 Moveable::GetJointPos(int jointID, sol::optional offset) const { auto convertedOffset = offset.has_value() ? offset->ToVector3i() : Vector3i::Zero; @@ -441,7 +441,7 @@ Vec3 Moveable::GetJointPos(int jointID, sol::optional offset) const /// Get the object's joint rotation // @function Moveable:GetJointRotation -// @tparam int index of a joint to get rotation +// @tparam int index Index of a joint to get rotation. // @treturn Rotation a calculated copy of the moveable's joint rotation Rotation Moveable::GetJointRot(int jointIndex) const { @@ -606,9 +606,9 @@ void Moveable::SetEffect(EffectType effectType, sol::optional timeout) /// Set custom colored burn effect to moveable // @function Moveable:SetCustomEffect -// @tparam Color Color1 color the primary color of the effect (also used for lighting). -// @tparam Color Color2 color the secondary color of the effect. -// @tparam[opt] float timeout time (in seconds) after which effect turns off. +// @tparam Color color1 The primary color of the effect (also used for lighting). +// @tparam Color color2 The secondary color of the effect. +// @tparam[opt] float timeout Time (in seconds) after which effect turns off. void Moveable::SetCustomEffect(const ScriptColor& col1, const ScriptColor& col2, sol::optional timeout) { int realTimeout = timeout.has_value() ? int(timeout.value() * FPS) : -1; @@ -619,7 +619,7 @@ void Moveable::SetCustomEffect(const ScriptColor& col1, const ScriptColor& col2, /// Get current moveable effect // @function Moveable:GetEffect -// @treturn Effects.EffectID Sffect type currently assigned. +// @treturn Effects.EffectID Effect type currently assigned. EffectType Moveable::GetEffect() const { return _moveable->Effect.Type; @@ -627,7 +627,7 @@ EffectType Moveable::GetEffect() const /// Get the value stored in ItemFlags[index] // @function Moveable:GetItemFlags -// @tparam int index of the ItemFlags, can be between 0 and 7. +// @tparam int index Index of the ItemFlag, can be between 0 and 7. // @treturn int the value contained in the ItemFlags[index] short Moveable::GetItemFlags(int index) const { @@ -636,8 +636,8 @@ short Moveable::GetItemFlags(int index) const /// Stores a value in ItemFlags[index] // @function Moveable:SetItemFlags -// @tparam short value to store in the moveable's ItemFlags[index] -// @tparam int index of the ItemFlags where store the value. +// @tparam short value Value to store in the moveable's ItemFlags[index]. +// @tparam int index Index of the ItemFlag where to store the value. void Moveable::SetItemFlags(short value, int index) { _moveable->ItemFlags[index] = value; @@ -660,7 +660,7 @@ short Moveable::GetLocationAI() const /// Updates the location in the enemy AI with the given value. // @function Moveable:SetLocationAI -// @tparam short value to store. +// @tparam short value Value to store. void Moveable::SetLocationAI(short value) { if (_moveable->IsCreature()) @@ -696,12 +696,13 @@ void Moveable::SetColor(const ScriptColor& color) // have a *1* in the corresponding cell. Otherwise, the cell will hold // a *0*. // -//
      1 - guard -//
      2 - ambush -//
      3 - patrol 1 -//
      4 - modify -//
      5 - follow -//
      6 - patrol 2 +// 1 - Guard +// 2 - Ambush +// 3 - Patrol 1 +// 4 - Modify +// 5 - Follow +// 6 - Patrol 2 +// // @function Moveable:GetAIBits // @treturn table a table of AI bits aiBitsType Moveable::GetAIBits() const @@ -934,7 +935,7 @@ void Moveable::SetRoomNumber(int roomNumber) } /// Get the moveable's status. -// @function Moveable:GetStatus() +// @function Moveable:GetStatus // @treturn Objects.MoveableStatus Status. short Moveable::GetStatus() const { @@ -942,7 +943,7 @@ short Moveable::GetStatus() const } /// Set the moveable's status. -// @function Moveable:SetStatus() +// @function Moveable:SetStatus // @tparam Objects.MoveableStatus status The new status of the moveable. void Moveable::SetStatus(ItemStatus status) { @@ -1234,9 +1235,9 @@ bool Moveable::MeshExists(int index) const /// Attach camera to an object. // @function Moveable:AttachObjCamera -// @tparam int mesh of a moveable to use as a camera position -// @tparam Moveable target moveable to attach camera to -// @tparam int mesh of a target moveable to use as a camera target +// @tparam int mesh Mesh of a moveable to use as a camera position. +// @tparam Moveable target Target moveable to attach camera to. +// @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())) @@ -1245,9 +1246,9 @@ void Moveable::AttachObjCamera(short camMeshId, Moveable& mov, short targetMeshI /// Borrow animation from an object // @function Moveable:AnimFromObject -// @tparam Objects.ObjID ObjectID to take animation and stateID from, -// @tparam int animNumber animation from object -// @tparam int stateID state from object +// @tparam Objects.ObjID objectID Object ID to take animation and stateID from. +// @tparam int animNumber Animation from object. +// @tparam int stateID state State from object. void Moveable::AnimFromObject(GAME_OBJECT_ID objectID, int animNumber, int stateID) { _moveable->Animation.AnimObjectID = objectID; 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/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); diff --git a/TombEngine/Shaders/CBCamera.hlsli b/TombEngine/Shaders/CBCamera.hlsli index 2c627acb5..34a7709c0 100644 --- a/TombEngine/Shaders/CBCamera.hlsli +++ b/TombEngine/Shaders/CBCamera.hlsli @@ -28,8 +28,8 @@ cbuffer CBCamera : register(b0) //-- float4 FogColor; //-- - int FogMinDistance; - int FogMaxDistance; + float FogMinDistance; + float FogMaxDistance; float NearPlane; float FarPlane; //-- diff --git a/TombEngine/Shaders/InstancedSprites.fx b/TombEngine/Shaders/InstancedSprites.fx index 0e9287137..5320f03d3 100644 --- a/TombEngine/Shaders/InstancedSprites.fx +++ b/TombEngine/Shaders/InstancedSprites.fx @@ -106,7 +106,7 @@ float4 PS(PixelShaderInput input) : SV_TARGET output.w = min(output.w, fade); } - output.xyz -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w); + output.xyz *= 1.0f - Luma(input.FogBulbs.xyz); output.xyz = saturate(output.xyz); output = DoDistanceFogForPixel(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.DistanceFog); diff --git a/TombEngine/Shaders/PostProcess.fx b/TombEngine/Shaders/PostProcess.fx index 79c3ebef2..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); @@ -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 diff --git a/TombEngine/Shaders/Sprites.fx b/TombEngine/Shaders/Sprites.fx index 54433f35e..50fb85b5c 100644 --- a/TombEngine/Shaders/Sprites.fx +++ b/TombEngine/Shaders/Sprites.fx @@ -82,7 +82,7 @@ float4 PS(PixelShaderInput input) : SV_TARGET output = DoLaserBeamEffect(input.Position, output, input.UV, FADE_FACTOR, Frame); } - output.xyz -= float3(input.FogBulbs.w, input.FogBulbs.w, input.FogBulbs.w); + output.xyz *= 1.0f - Luma(input.FogBulbs.xyz); output.xyz = saturate(output.xyz); output = DoDistanceFogForPixel(output, float4(0.0f, 0.0f, 0.0f, 0.0f), input.DistanceFog); diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index e87d162d5..4935ecb0a 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -454,7 +454,6 @@ void LoadObjects() Objects[objNum].animIndex = ReadInt32(); } - TENLog("Initializing objects...", LogLevel::Info); InitializeObjects(); int staticCount = ReadCount(); @@ -1318,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; diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index 6cf572a17..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; @@ -549,8 +553,8 @@ struct LevelDataT : public flatbuffers::NativeTable { int32_t weather_type = 0; float weather_strength = 0.0f; int32_t fog_color = 0; - int32_t fog_min_distance = 0; - int32_t fog_max_distance = 0; + float fog_min_distance = 0.0f; + float fog_max_distance = 0.0f; bool sky_layer_1_enabled = false; int32_t sky_layer_1_color = 0; int32_t sky_layer_1_speed = 0; @@ -633,11 +637,11 @@ struct LevelData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t fog_color() const { return GetField(VT_FOG_COLOR, 0); } - int32_t fog_min_distance() const { - return GetField(VT_FOG_MIN_DISTANCE, 0); + float fog_min_distance() const { + return GetField(VT_FOG_MIN_DISTANCE, 0.0f); } - int32_t fog_max_distance() const { - return GetField(VT_FOG_MAX_DISTANCE, 0); + float fog_max_distance() const { + return GetField(VT_FOG_MAX_DISTANCE, 0.0f); } bool sky_layer_1_enabled() const { return GetField(VT_SKY_LAYER_1_ENABLED, 0) != 0; @@ -719,8 +723,8 @@ struct LevelData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_WEATHER_TYPE) && VerifyField(verifier, VT_WEATHER_STRENGTH) && VerifyField(verifier, VT_FOG_COLOR) && - VerifyField(verifier, VT_FOG_MIN_DISTANCE) && - VerifyField(verifier, VT_FOG_MAX_DISTANCE) && + VerifyField(verifier, VT_FOG_MIN_DISTANCE) && + VerifyField(verifier, VT_FOG_MAX_DISTANCE) && VerifyField(verifier, VT_SKY_LAYER_1_ENABLED) && VerifyField(verifier, VT_SKY_LAYER_1_COLOR) && VerifyField(verifier, VT_SKY_LAYER_1_SPEED) && @@ -774,11 +778,11 @@ struct LevelDataBuilder { void add_fog_color(int32_t fog_color) { fbb_.AddElement(LevelData::VT_FOG_COLOR, fog_color, 0); } - void add_fog_min_distance(int32_t fog_min_distance) { - fbb_.AddElement(LevelData::VT_FOG_MIN_DISTANCE, fog_min_distance, 0); + void add_fog_min_distance(float fog_min_distance) { + fbb_.AddElement(LevelData::VT_FOG_MIN_DISTANCE, fog_min_distance, 0.0f); } - void add_fog_max_distance(int32_t fog_max_distance) { - fbb_.AddElement(LevelData::VT_FOG_MAX_DISTANCE, fog_max_distance, 0); + void add_fog_max_distance(float fog_max_distance) { + fbb_.AddElement(LevelData::VT_FOG_MAX_DISTANCE, fog_max_distance, 0.0f); } void add_sky_layer_1_enabled(bool sky_layer_1_enabled) { fbb_.AddElement(LevelData::VT_SKY_LAYER_1_ENABLED, static_cast(sky_layer_1_enabled), 0); @@ -871,8 +875,8 @@ inline flatbuffers::Offset CreateLevelData( int32_t weather_type = 0, float weather_strength = 0.0f, int32_t fog_color = 0, - int32_t fog_min_distance = 0, - int32_t fog_max_distance = 0, + float fog_min_distance = 0.0f, + float fog_max_distance = 0.0f, bool sky_layer_1_enabled = false, int32_t sky_layer_1_color = 0, int32_t sky_layer_1_speed = 0, @@ -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 647c3246d..bc41d27be 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -15,8 +15,8 @@ table LevelData { weather_strength: float; fog_color: int32; - fog_min_distance: int32; - fog_max_distance: int32; + fog_min_distance: float; + fog_max_distance: float; sky_layer_1_enabled: bool; sky_layer_1_color: int32; @@ -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/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index bd7b2cefa..560073115 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -24,14 +24,10 @@ 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; -uintptr_t ThreadHandle; +unsigned int ThreadID, ConsoleThreadID; +uintptr_t ThreadHandle, ConsoleThreadHandle; HACCEL hAccTable; bool DebugMode = false; HWND WindowsHandle; @@ -242,6 +238,31 @@ bool GenerateDummyLevel(const std::string& levelPath) return true; } +unsigned CALLBACK ConsoleInput(void*) +{ + auto input = std::string(); + while (!ThreadEnded) + { + 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); + continue; + } + else + { + g_GameScript->AddConsoleInput(input); + } + } + + return true; +} + void WinProcMsg() { MSG msg; @@ -405,8 +426,14 @@ 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); + } // Clear application structure. memset(&App, 0, sizeof(WINAPP)); @@ -615,6 +642,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine void WinClose() { + if (ConsoleThreadHandle) + CloseHandle((HANDLE)ConsoleThreadHandle); + WaitForSingleObject((HANDLE)ThreadHandle, 5000); DestroyAcceleratorTable(hAccTable); diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index 0da249555..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. + @@ -742,7 +743,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. + @@ -1268,7 +1270,7 @@ if not exist "%ScriptsDir%\Strings.lua" xcopy /Y "$(SolutionDir)Scripts\Strings. - + diff --git a/TombEngine/version.h b/TombEngine/version.h index 93315b462..be70e36ed 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 7 -#define TEN_BUILD_NUMBER 3 +#define TEN_MINOR_VERSION 8 +#define TEN_BUILD_NUMBER 1 #define TEN_REVISION_NUMBER 0 #define TEST_BUILD 0