diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index 9bf035ec4..1a04f2f02 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -1,24 +1,54 @@ +Version 1.1.1 +============== + +* Fix burning torch not working properly if there is more than 256 objects in a level. + Version 1.1.0 ============== * Fix enemies shooting Lara through static meshes and moveables. -* Fix skeletons and mummies not affected by explosive weapons. +* Fix skeletons and mummies not being affected by explosive weapons. * Fix crash on loading if static meshes with IDs above maximum are present. +* Fix various crashes specific to 64-bit build. * Fix random crashes when playing audio tracks with names longer than 15 symbols. +* Fix crashes when trying to play .wav audio tracks on some Windows 11 systems. +* Fix last selected gun type not preserved after level jump. +* Fix incorrect vertical position after reloading a savegame made while standing on a bridge. * Fix sprint value going below zero. * Fix fog bulb density formula. -* Fix electricity effect crashing 64-bit version of the engine. * Fix clockwork beetle activation crashing the game. * Fix corrupted vehicle positions after savegame reload. * Fix default ambience overlapping current one when loading a savegame. -* Fix doppelganger being limited to be in a single room. -* Add multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger. -* Implement separate audio track channel for playing voiceovers with subtitles. +* Fix doppelganger being limited to a single room. +* Fix bat AI, damage value, and incorrect collision after death. +* Fix regeneration for pickups with OCB 128. +* Fix raising blocks still shaking without OCB. +* Fix spiky ceiling, improve collision, and allow setting velocity via OCB. +* Fix TR1 winged mutant pathfinding and damage issues and add new OCBs. +* Fix TR1 Natla facing angle, bomb and shard projectiles, shooting anim in the second phase. +* Fix last inventory item position not being saved. +* Fix some puzzle hole objects crashing the game on item insertion. +* Fix incorrect harpoon bolt speed and angle when shooting vertically. +* Fix black shatter debris. +* Fix Lara's shadow projecting only her joints on some occasions. +* Fix sun and spot bulbs direction and sheen casts. +* Fix room collector freezing game on some occasions. +* Fix incorrect culling for scaled static meshes. +* Fix normal mapping. +* 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. * Pause all sounds when entering inventory or pause menu. +* Preserve hit points on level jump. * Improve deflection against slopes. -* Move and rotate Lara together with dynamic bridge objects. -* Move and rotate activated pickups together with dynamic bridge objects. +* Move and rotate Lara and activated pickups together with dynamic bridge objects. +* Reduce camera bounce. +* Improve spiky wall collision accuracy. +* Expand control settings page. +* Allow key bindings for previously hardcoded actions (weapon hotkeys, vehicle controls). +* Add input actions for weapon scroll. +* Add splash effect to rockets and grenades when they enter water. +* Allow multiple doppelgangers by using the same OCB for the origin nullmesh and doppelganger. * Add TR1 skateboard kid. * Add TR1 Kold. diff --git a/Documentation/config.ld b/Documentation/config.ld index 9718f9db7..67e60fa70 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.0.9" +local version = "1.1.0" 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 f527987fa..925c60cd3 100644 --- a/Documentation/doc/1 modules/Effects.html +++ b/Documentation/doc/1 modules/Effects.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -506,7 +507,7 @@
  • speed float - (default 1.0). Speed in "amount" per second. A value of 1 will make the flash take one second. Clamped to [0.005, 1.0] + (default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0].
  • @@ -522,7 +523,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index a931c0399..b0d543d3b 100644 --- a/Documentation/doc/1 modules/Flow.html +++ b/Documentation/doc/1 modules/Flow.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -669,7 +670,7 @@ Specify which translations in the strings table correspond to which languages.
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index aca417252..1a86e0e1e 100644 --- a/Documentation/doc/1 modules/Inventory.html +++ b/Documentation/doc/1 modules/Inventory.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -245,7 +246,7 @@ Similar to GiveItem but repla
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index ea0a7ebe8..78b5a39ba 100644 --- a/Documentation/doc/1 modules/Logic.html +++ b/Documentation/doc/1 modules/Logic.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -408,7 +409,7 @@ end
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/1 modules/Misc.html b/Documentation/doc/1 modules/Misc.html index 34ac6f0b5..6eb2168d5 100644 --- a/Documentation/doc/1 modules/Misc.html +++ b/Documentation/doc/1 modules/Misc.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -126,7 +127,7 @@ Shows the mode of the game camera. - PlayAudioTrack(name, loop) + PlayAudioTrack(name, type) Play an audio track @@ -138,10 +139,18 @@ Stop any audio tracks currently playing - StopAudioTrack(looped) + StopAudioTrack(type) Stop audio track that is currently playing + GetAudioTrackLoudness(type) + Get current loudness level for specified track type + + + GetCurrentSubtitle() + Get current subtitle string for a voice track currently playing. + + PlaySound(sound[, position]) Play sound effect @@ -150,6 +159,10 @@ Check if the sound effect is playing + IsAudioTrackPlaying(Track) + Check if the audio track is playing + + FlipMap(flipmap) Do FlipMap with specific ID @@ -410,7 +423,7 @@ eyes of the creatures would be.
    - PlayAudioTrack(name, loop) + PlayAudioTrack(name, type)
    Play an audio track @@ -423,9 +436,9 @@ eyes of the creatures would be. string of track (without file extension) to play -
  • loop - bool - if true, the track will loop; if false, it won't (default: false) +
  • type + SoundTrackType + of the audio track to play
  • @@ -473,7 +486,7 @@ eyes of the creatures would be.
    - StopAudioTrack(looped) + StopAudioTrack(type)
    Stop audio track that is currently playing @@ -482,9 +495,9 @@ eyes of the creatures would be.

    Parameters:

    @@ -492,6 +505,57 @@ eyes of the creatures would be. +
    +
    + + GetAudioTrackLoudness(type) +
    +
    + Get current loudness level for specified track type + + + +

    Parameters:

    + + +

    Returns:

    +
      + + float + current loudness of a specified audio track +
    + + + + +
    +
    + + GetCurrentSubtitle() +
    +
    + Get current subtitle string for a voice track currently playing. +Subtitle file must be in .srt format, have same filename as voice track, and be placed in same directory as voice track. +Returns nil if no voice track is playing or no subtitle present. + + + + +

    Returns:

    +
      + + string + current subtitle string +
    + + + +
    @@ -541,6 +605,28 @@ eyes of the creatures would be. + +
    + + IsAudioTrackPlaying(Track) +
    +
    + Check if the audio track is playing + + + +

    Parameters:

    + + + + + +
    @@ -915,7 +1001,7 @@ PrintLog('test error log', LogLevel.ERROR)
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/1 modules/Objects.html b/Documentation/doc/1 modules/Objects.html index c78b757ea..7e02981ec 100644 --- a/Documentation/doc/1 modules/Objects.html +++ b/Documentation/doc/1 modules/Objects.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -465,7 +466,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html index 8ae751a08..da2b6e541 100644 --- a/Documentation/doc/1 modules/Strings.html +++ b/Documentation/doc/1 modules/Strings.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -205,7 +206,7 @@ with a call to ShowString, or
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.Animations.html b/Documentation/doc/2 classes/Flow.Animations.html index 3a0d1b1a9..f3eb29461 100644 --- a/Documentation/doc/2 classes/Flow.Animations.html +++ b/Documentation/doc/2 classes/Flow.Animations.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -106,7 +107,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.Fog.html b/Documentation/doc/2 classes/Flow.Fog.html index c79aabc7c..90da7e6dd 100644 --- a/Documentation/doc/2 classes/Flow.Fog.html +++ b/Documentation/doc/2 classes/Flow.Fog.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -233,7 +234,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.InventoryItem.html b/Documentation/doc/2 classes/Flow.InventoryItem.html index 3e80d8c8d..9a671a8d6 100644 --- a/Documentation/doc/2 classes/Flow.InventoryItem.html +++ b/Documentation/doc/2 classes/Flow.InventoryItem.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -191,7 +192,7 @@ EXAMINE
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html index 8307ce5ce..73e9e6ac7 100644 --- a/Documentation/doc/2 classes/Flow.Level.html +++ b/Documentation/doc/2 classes/Flow.Level.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -536,7 +537,7 @@ Must be at least 4.

    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.Mirror.html b/Documentation/doc/2 classes/Flow.Mirror.html index e20bbb78d..93d518f27 100644 --- a/Documentation/doc/2 classes/Flow.Mirror.html +++ b/Documentation/doc/2 classes/Flow.Mirror.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -106,7 +107,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index d05eab9ee..e29c5019c 100644 --- a/Documentation/doc/2 classes/Flow.Settings.html +++ b/Documentation/doc/2 classes/Flow.Settings.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -146,7 +147,7 @@ has an unrecoverable error, the game will close.
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Flow.SkyLayer.html b/Documentation/doc/2 classes/Flow.SkyLayer.html index 16ecac2e6..43651ef02 100644 --- a/Documentation/doc/2 classes/Flow.SkyLayer.html +++ b/Documentation/doc/2 classes/Flow.SkyLayer.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -204,7 +205,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.AIObject.html b/Documentation/doc/2 classes/Objects.AIObject.html index 6c3130941..e6b3d0228 100644 --- a/Documentation/doc/2 classes/Objects.AIObject.html +++ b/Documentation/doc/2 classes/Objects.AIObject.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -407,7 +408,7 @@ aiObj:SetObjectID(TEN.Objects.ObjID.AI_PATROL1)
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html index 200a35f97..4f74538f4 100644 --- a/Documentation/doc/2 classes/Objects.Camera.html +++ b/Documentation/doc/2 classes/Objects.Camera.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -320,7 +321,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.LaraObject.html b/Documentation/doc/2 classes/Objects.LaraObject.html index 0a9799d7a..c7979342a 100644 --- a/Documentation/doc/2 classes/Objects.LaraObject.html +++ b/Documentation/doc/2 classes/Objects.LaraObject.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -671,7 +672,7 @@ ROCKETLAUNCHER
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 9af2f1712..c4c683819 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -1859,7 +1860,7 @@ sas:SetPosition(destinationPosition, false)
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.Room.html b/Documentation/doc/2 classes/Objects.Room.html index 7553ecd5e..567ab68ed 100644 --- a/Documentation/doc/2 classes/Objects.Room.html +++ b/Documentation/doc/2 classes/Objects.Room.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -334,7 +335,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.Sink.html b/Documentation/doc/2 classes/Objects.Sink.html index 0523be42b..e3b5b22cb 100644 --- a/Documentation/doc/2 classes/Objects.Sink.html +++ b/Documentation/doc/2 classes/Objects.Sink.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -270,7 +271,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.SoundSource.html b/Documentation/doc/2 classes/Objects.SoundSource.html index 44055bb3a..fc788bb3c 100644 --- a/Documentation/doc/2 classes/Objects.SoundSource.html +++ b/Documentation/doc/2 classes/Objects.SoundSource.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -268,7 +269,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.Static.html b/Documentation/doc/2 classes/Objects.Static.html index 5f3ed86e4..1b84b3d64 100644 --- a/Documentation/doc/2 classes/Objects.Static.html +++ b/Documentation/doc/2 classes/Objects.Static.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -554,7 +555,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Objects.Volume.html b/Documentation/doc/2 classes/Objects.Volume.html index 8d181a562..c74d58b2b 100644 --- a/Documentation/doc/2 classes/Objects.Volume.html +++ b/Documentation/doc/2 classes/Objects.Volume.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -431,7 +432,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html index 97cc432e6..d84db9822 100644 --- a/Documentation/doc/2 classes/Strings.DisplayString.html +++ b/Documentation/doc/2 classes/Strings.DisplayString.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -407,7 +408,7 @@ varDisplayString:SetFlags({ TEN.Strings.DisplayStringOption.SHADOW, TEN.Strings.
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html index ada63f9ed..a8488f84a 100644 --- a/Documentation/doc/3 primitive classes/Color.html +++ b/Documentation/doc/3 primitive classes/Color.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -109,7 +110,7 @@ a - (int) alpha component (255 is opaque, 0 is invisible) + (int) alpha component (255 = opaque, 0 = invisible)

    Functions

    @@ -191,7 +192,7 @@ a
    - (int) alpha component (255 is opaque, 0 is invisible) + (int) alpha component (255 = opaque, 0 = invisible) @@ -322,7 +323,7 @@
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html index c0937c8e9..cdb307faf 100644 --- a/Documentation/doc/3 primitive classes/Rotation.html +++ b/Documentation/doc/3 primitive classes/Rotation.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -257,7 +258,7 @@ All values will be clamped to [0.0f, 360.0f].

    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/3 primitive classes/Vec2.html b/Documentation/doc/3 primitive classes/Vec2.html index 490d84673..72490bf66 100644 --- a/Documentation/doc/3 primitive classes/Vec2.html +++ b/Documentation/doc/3 primitive classes/Vec2.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -259,7 +260,7 @@ numbers, this will be less accurate at smaller lengths.
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/3 primitive classes/Vec3.html b/Documentation/doc/3 primitive classes/Vec3.html index 76832c5d3..b543fca75 100644 --- a/Documentation/doc/3 primitive classes/Vec3.html +++ b/Documentation/doc/3 primitive classes/Vec3.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -285,7 +286,7 @@ However, this function would return it as (0, 1, 1).
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Effects.BlendID.html b/Documentation/doc/4 enums/Effects.BlendID.html index 5a528fde1..0949659b0 100644 --- a/Documentation/doc/4 enums/Effects.BlendID.html +++ b/Documentation/doc/4 enums/Effects.BlendID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -152,7 +153,7 @@ ALPHABLEND
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Effects.EffectID.html b/Documentation/doc/4 enums/Effects.EffectID.html index 094914f87..6f13a9977 100644 --- a/Documentation/doc/4 enums/Effects.EffectID.html +++ b/Documentation/doc/4 enums/Effects.EffectID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -150,7 +151,7 @@ CUSTOM
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Misc.ActionID.html b/Documentation/doc/4 enums/Misc.ActionID.html index 7f5f59152..8bb6b2ee7 100644 --- a/Documentation/doc/4 enums/Misc.ActionID.html +++ b/Documentation/doc/4 enums/Misc.ActionID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -119,19 +120,46 @@ BACK LEFT RIGHT -CROUCH -SPRINT +STEP_LEFT +STEP_RIGHT WALK +SPRINT +CROUCH JUMP +ROLL ACTION DRAW -FLARE LOOK -ROLL -INVENTORY + +ACCELERATE +REVERSE +SPEED +SLOW +BRAKE +FIRE + +FLARE +SMALL_MEDIPACK +LARGE_MEDIPACK +PREVIOUS_WEAPON +NEXT_WEAPON +WEAPON_1 +WEAPON_2 +WEAPON_3 +WEAPON_4 +WEAPON_5 +WEAPON_6 +WEAPON_7 +WEAPON_8 +WEAPON_9 +WEAPON_10 + +SELECT +DESELECT PAUSE -STEPLEFT -STEPRIGHT +INVENTORY +SAVE +LOAD @@ -159,7 +187,7 @@ STEPRIGHT
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-24 14:47:38
    diff --git a/Documentation/doc/4 enums/Misc.CameraType.html b/Documentation/doc/4 enums/Misc.CameraType.html index 82aa48011..b6af41c74 100644 --- a/Documentation/doc/4 enums/Misc.CameraType.html +++ b/Documentation/doc/4 enums/Misc.CameraType.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -148,7 +149,7 @@ OBJECT
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Misc.LogLevel.html b/Documentation/doc/4 enums/Misc.LogLevel.html index 7654435cb..17ccc7312 100644 --- a/Documentation/doc/4 enums/Misc.LogLevel.html +++ b/Documentation/doc/4 enums/Misc.LogLevel.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -144,7 +145,7 @@ ERROR
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Misc.SoundTrackType.html b/Documentation/doc/4 enums/Misc.SoundTrackType.html new file mode 100644 index 000000000..57c9cf075 --- /dev/null +++ b/Documentation/doc/4 enums/Misc.SoundTrackType.html @@ -0,0 +1,153 @@ + + + + + TombEngine 1.1.0 Lua API + + + + +
    + +
    + +
    +
    +
    + + +
    + + + + + + +
    + +

    Enum Misc.SoundTrackType

    +

    Constants for the type of the audio tracks.

    +

    + +

    + + +

    Misc.SoundTrackType constants

    + + + + + +
    CONSTANT_STRING_HERETable of sound track type constants (for use with sound track functions).
    + +
    +
    + + +

    Misc.SoundTrackType constants

    + +
    + + + +

    The following constants are inside SoundTrackType.

    + +
    ONESHOT
    +LOOPED
    +VOICE
    +
    + + +
    +
    +
    + + CONSTANT_STRING_HERE +
    +
    + Table of sound track type constants (for use with sound track functions). + + + + + + + + +
    +
    + + +
    +
    +
    +generated by TEN-LDoc (a fork of LDoc 1.4.6) +Last updated 2023-07-20 12:10:11 +
    +
    + + diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index b1ce82c1c..dcf707669 100644 --- a/Documentation/doc/4 enums/Objects.ObjID.html +++ b/Documentation/doc/4 enums/Objects.ObjID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -275,9 +276,7 @@ WINGED_MUMMY CENTAUR_MUTANT DOPPELGANGER NATLA -WINGED_NATLA GIANT_MUTANT -PROJ_NATLA PROJ_SHARD PROJ_BOMB YETI @@ -345,6 +344,8 @@ BOSS_EXPLOSION_SHOCKWAVE BOSS_EXPLOSION_RING CLAW_MUTANT WASP_MUTANT +SKATEBOARD +SKATEBOARD_KID SPRINGBOARD ROLLING_SPINDLE DISK_SHOOTER @@ -873,7 +874,7 @@ AI_X2 LARA_START_POS TELEPORTER LIFT_TELEPORTER -LASERS +LASER_BARRIER STEAM_LASERS FLOOR_LASERS KILL_ALL_TRIGGERS @@ -907,7 +908,7 @@ WATERFALL6 WATERFALLSS1 WATERFALLSS2 FISHTANK -BACON_REFERENCE +DOPPELGANGER_ORIGIN CORPSE WRAITH_TRAP MESHSWAP1 @@ -1321,7 +1322,7 @@ PC_SAVE_INV_ITEM
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Objects.RoomFlagID.html b/Documentation/doc/4 enums/Objects.RoomFlagID.html index 9fef8d711..52c335653 100644 --- a/Documentation/doc/4 enums/Objects.RoomFlagID.html +++ b/Documentation/doc/4 enums/Objects.RoomFlagID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -149,7 +150,7 @@ NOLENSFLARE
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/4 enums/Objects.RoomReverb.html b/Documentation/doc/4 enums/Objects.RoomReverb.html index 1c18e731f..0a2660ac5 100644 --- a/Documentation/doc/4 enums/Objects.RoomReverb.html +++ b/Documentation/doc/4 enums/Objects.RoomReverb.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -147,7 +148,7 @@ PIPE
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index 191a12e22..9d2c27a53 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.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -347,7 +348,7 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index c991c2a5c..e19b48fa5 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.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -520,7 +521,7 @@ LevelFuncs.TriggerTimer = function(obj)
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html index 94819c3d6..2b463303f 100644 --- a/Documentation/doc/index.html +++ b/Documentation/doc/index.html @@ -3,7 +3,7 @@ - TombEngine 1.0.9 Lua API + TombEngine 1.1.0 Lua API @@ -74,6 +74,7 @@
  • Misc.ActionID
  • Misc.CameraType
  • Misc.LogLevel
  • +
  • Misc.SoundTrackType
  • Objects.ObjID
  • Objects.RoomFlagID
  • Objects.RoomReverb
  • @@ -89,7 +90,7 @@
    -

    TombEngine 1.0.9 scripting interface

    +

    TombEngine 1.1.0 scripting interface

    Welcome to the TombEngine scripting API. This is a work in progress and some information might be wrong or outdated. Please also note that this is primarily a reference document, not a tutorial, so expect descriptions to be fairly sparse.

    At the time of writing, there is a tutorial describing the basics of Lua, as well as a number of example scripts, on the TombEngine website.

    @@ -254,6 +255,10 @@ local door = GetMoveableByName("door_type4_14") Misc.LogLevel Constants for LogLevel IDs. + + Misc.SoundTrackType + Constants for the type of the audio tracks. + Objects.ObjID Constants for object IDs. @@ -283,7 +288,7 @@ local door = GetMoveableByName("door_type4_14")
    generated by TEN-LDoc (a fork of LDoc 1.4.6) -Last updated 2023-06-03 11:42:57 +Last updated 2023-07-20 12:10:11
    diff --git a/Documentation/output.xml b/Documentation/output.xml index da1d3b73a..9bc265b8d 100644 --- a/Documentation/output.xml +++ b/Documentation/output.xml @@ -356,7 +356,7 @@ speed float - (default 1.0). Speed in "amount" per second. A value of 1 will make the flash take one second. Clamped to [0.005, 1.0] + (default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0]. @@ -1013,9 +1013,9 @@ eyes of the creatures would be. of track (without file extension) to play - loop - bool - if true, the track will loop; if false, it won't (default: false) + type + Misc.SoundTrackType + of the audio track to play @@ -1045,13 +1045,46 @@ eyes of the creatures would be. Stop audio track that is currently playing - looped - bool - if set, stop looped audio track, if not, stop one-shot audio track + type + Misc.SoundTrackType + of the audio track + + Misc + GetAudioTrackLoudness + Get current loudness level for specified track type + + + type + Misc.SoundTrackType + of the audio track + + + + + float + current loudness of a specified audio track + + + + + + Misc + GetCurrentSubtitle + Get current subtitle string for a voice track currently playing. + Subtitle file must be in .srt format, have same filename as voice track, and be placed in same directory as voice track. +Returns nil if no voice track is playing or no subtitle present. + + + string + current subtitle string + + + + Misc PlaySound @@ -1083,6 +1116,19 @@ eyes of the creatures would be. + + Misc + IsAudioTrackPlaying + Check if the audio track is playing + + + Track + string + filename to check. Should be without extension and without full directory path. + + + + Misc FlipMap diff --git a/Scripts/Engine/Timer.lua b/Scripts/Engine/Timer.lua index df05d13b0..1f0cb269b 100644 --- a/Scripts/Engine/Timer.lua +++ b/Scripts/Engine/Timer.lua @@ -125,7 +125,10 @@ Timer = { else t.remainingTime = t.remainingTime + t.totalTime end - t.func(table.unpack(t.funcArgs)) + + if (t.func ~= nil) then + t.func(table.unpack(t.funcArgs)) + end end end diff --git a/Scripts/Strings.lua b/Scripts/Strings.lua index ce5d11c32..73db2c480 100644 --- a/Scripts/Strings.lua +++ b/Scripts/Strings.lua @@ -5,6 +5,48 @@ corresponding to languages in the table at the end of this file. local strings = { + actions_accelerate = { "Accelerate" }, + actions_reverse = { "Reverse" }, + actions_speed = { "Speed" }, + actions_slow = { "Slow" }, + actions_brake = { "Brake/Dismount" }, + actions_fire = { "Fire" }, + actions_action = { "Action" }, + actions_sprint = { "Sprint" }, + actions_draw = { "Draw" }, + actions_crouch = { "Crouch" }, + actions_inventory = { "Inventory" }, + actions_jump = { "Jump" }, + actions_look = { "Look" }, + actions_backward = { "Backward" }, + actions_forward = { "Forward" }, + actions_left = { "Left" }, + actions_right = { "Right" }, + actions_roll = { "Roll" }, + actions_step_left = { "Step Left" }, + actions_step_right = { "Step Right" }, + actions_pause = { "Pause" }, + actions_walk = { "Walk" }, + actions_save = { "Save" }, + actions_load = { "Load" }, + actions_select = { "Select" }, + actions_deselect = { "Deselect" }, + actions_large_medipack = { "Large Medipack" }, + actions_flare = { "Flare" }, + actions_next_weapon = { "Next Weapon" }, + actions_previous_weapon = { "Previous Weapon" }, + actions_small_medipack = { "Small Medipack" }, + actions_weapon_1 = { "Weapon 1" }, + actions_weapon_2 = { "Weapon 2" }, + actions_weapon_3 = { "Weapon 3" }, + actions_weapon_4 = { "Weapon 4" }, + actions_weapon_5 = { "Weapon 5" }, + actions_weapon_6 = { "Weapon 6" }, + actions_weapon_7 = { "Weapon 7" }, + actions_weapon_8 = { "Weapon 8" }, + actions_weapon_9 = { "Weapon 9" }, + actions_weapon_10 = { "Weapon 10" }, + window_title = { "TombEngine" }, all = { "All" }, apply = { "Apply" }, automatic_targeting = { "Automatic Targeting" }, @@ -18,24 +60,7 @@ local strings = combine = { "Combine" }, combine_with = { "Combine With" }, controls = { "Controls" }, - controls_action = { "Action" }, - controls_sprint = { "Sprint" }, - controls_draw_weapon = { "Draw Weapon" }, - controls_crouch = { "Crouch" }, - controls_inventory = { "Inventory" }, - controls_jump = { "Jump" }, - controls_look = { "Look" }, - controls_move_backward = { "Move Backward" }, - controls_move_forward = { "Move Forward" }, - controls_move_left = { "Move Left" }, - controls_move_right = { "Move Right" }, - controls_roll = { "Roll" }, - controls_step_left = { "Step Left" }, - controls_step_right = { "Step Right" }, - controls_pause = { "Pause" }, - controls_use_flare = { "Use Flare" }, - controls_walk = { "Walk" }, - controls_defaults = { "Reset to Defaults" }, + reset_to_defaults = { "Reset to Defaults" }, crossbow = { "Crossbow" }, crossbow_normal_ammo = { "Crossbow Normal Ammo" }, crossbow_poison_ammo = { "Crossbow Poison Ammo" }, @@ -54,6 +79,7 @@ local strings = exit_game = { "Exit Game" }, exit_to_title = { "Exit to Title" }, flares = { "Flares" }, + general_actions = { "General Actions"}, grenade_launcher = { "Grenade Launcher" }, grenade_launcher_normal_ammo = { "Grenade Launcher Normal Ammo" }, grenade_launcher_super_ammo = { "Grenade Launcher Super Ammo" }, @@ -70,6 +96,7 @@ local strings = lara_home = { "Lara's Home" }, large_medipack = { "Large Medipack" }, lasersight = { "Lasersight" }, + menu_actions = { "Menu Actions" }, music_volume = { "Music Volume" }, new_game = { "New Game" }, none = { "None" }, @@ -125,6 +152,8 @@ local strings = waiting_for_input = { "Waiting For Input" }, windowed = { "Windowed" }, load_game = { "Load Game" }, + quick_actions = { "Quick Actions" }, + vehicle_actions = { "Vehicle Actions" }, test_level = { "Test Level" }, torch2 = { "Torch 2" }, waterskin_small_empty = { "Small Waterskin (Empty)" }, @@ -141,13 +170,7 @@ local strings = mechanical_scarab = { "Mechanical Scarab With Winding Key" }, mechanical_scarab_1 = { "Mechanical Scarab (No Winding Key)" }, mechanical_scarab_2 = { "Mechanical Scarab Winding Key" }, - title = { "Title" }, - accelerate = { "Accelerate" }, - reverse = { "Reverse" }, - speed = { "Speed" }, - slow = { "Slow" }, - brake = { "Brake" }, - fire = { "Fire" } + title = { "Title" } } TEN.Flow.SetStrings(strings) diff --git a/TombEngine/Game/Hud/PickupSummary.h b/TombEngine/Game/Hud/PickupSummary.h index c2dde5a5c..169adca76 100644 --- a/TombEngine/Game/Hud/PickupSummary.h +++ b/TombEngine/Game/Hud/PickupSummary.h @@ -10,7 +10,7 @@ namespace TEN::Hud { static constexpr auto LIFE_MAX = 3.0f; - GAME_OBJECT_ID ObjectID = ID_NO_OBJECT; + GAME_OBJECT_ID ObjectID = GAME_OBJECT_ID::ID_NO_OBJECT; unsigned int Count = 0; Vector2 Position2D = Vector2::Zero; diff --git a/TombEngine/Game/Lara/lara.cpp b/TombEngine/Game/Lara/lara.cpp index f388b208b..edee58508 100644 --- a/TombEngine/Game/Lara/lara.cpp +++ b/TombEngine/Game/Lara/lara.cpp @@ -38,6 +38,7 @@ #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Scripting/Include/ScriptInterfaceLevel.h" #include "Sound/sound.h" +#include "Specific/winmain.h" using namespace TEN::Control::Volumes; using namespace TEN::Effects::Hair; @@ -491,6 +492,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll) if (lara->Status.Stamina < LARA_STAMINA_MAX && item->Animation.ActiveState != LS_SPRINT) lara->Status.Stamina++; + HandlePlayerQuickActions(*item); RumbleLaraHealthCondition(item); bool isWater = TestEnvironment(ENV_FLAG_WATER, item); @@ -588,7 +590,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll) if (item->Animation.ActiveState == LS_SWAN_DIVE || item->Animation.ActiveState == LS_FREEFALL_DIVE) { - item->Pose.Position.y = waterHeight + (SECTOR(1) - 24); + item->Pose.Position.y = waterHeight + (BLOCK(1) - 24); } SetAnimation(item, LA_WADE); @@ -707,9 +709,7 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll) } if (TestEnvironment(ENV_FLAG_DAMAGE, item) && item->HitPoints > 0) - { item->HitPoints--; - } if (item->HitPoints <= 0) { @@ -861,6 +861,12 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll) } Statistics.Game.Distance += (int)round(Vector3::Distance(prevPos.ToVector3(), item->Pose.Position.ToVector3())); + + if (DebugMode) + { + DrawNearbyPathfinding(GetCollision(item).BottomBlock->Box); + DrawNearbySectorFlags(*item); + } } void LaraAboveWater(ItemInfo* item, CollisionInfo* coll) @@ -931,9 +937,7 @@ void LaraAboveWater(ItemInfo* item, CollisionInfo* coll) // Test for flags and triggers. ProcessSectorFlags(item); TestTriggers(item, false); - TestVolumes(Lara.ItemNumber, &coll->Setup); - - DrawNearbyPathfinding(GetCollision(item).BottomBlock->Box); + TestVolumes(item->Index, &coll->Setup); } void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll) @@ -1005,7 +1009,7 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll) ProcessSectorFlags(item); TestTriggers(item, false); - TestVolumes(Lara.ItemNumber); + TestVolumes(item->Index); } void LaraUnderwater(ItemInfo* item, CollisionInfo* coll) @@ -1094,7 +1098,7 @@ void LaraUnderwater(ItemInfo* item, CollisionInfo* coll) ProcessSectorFlags(item); TestTriggers(item, false); - TestVolumes(Lara.ItemNumber); + TestVolumes(item->Index); } void LaraCheat(ItemInfo* item, CollisionInfo* coll) diff --git a/TombEngine/Game/Lara/lara_basic.cpp b/TombEngine/Game/Lara/lara_basic.cpp index e5f0bcf7b..1b54e3268 100644 --- a/TombEngine/Game/Lara/lara_basic.cpp +++ b/TombEngine/Game/Lara/lara_basic.cpp @@ -103,7 +103,7 @@ void lara_as_vault(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableObjectPush = false; coll->Setup.EnableSpasm = false; - EaseOutLaraHeight(item, lara->Context.ProjectedFloorHeight - item->Pose.Position.y); + EasePlayerVerticalPosition(item, lara->Context.ProjectedFloorHeight - item->Pose.Position.y); item->Pose.Orientation.Lerp(lara->Context.TargetOrientation, 0.4f); item->Animation.TargetState = LS_IDLE; @@ -252,13 +252,13 @@ void lara_as_run_forward(ItemInfo* item, CollisionInfo* coll) return; } - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_FAST_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX); } - if (TrInput & IN_JUMP || lara->Control.RunJumpQueued) + if (IsHeld(In::Jump) || lara->Control.RunJumpQueued) { if (!(TrInput & IN_SPRINT) && lara->Control.Count.Run >= LARA_RUN_JUMP_TIME && TestLaraRunJumpForward(item, coll)) @@ -418,8 +418,8 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll) if (!IsHeld(In::Jump) || isSwamp) // JUMP locks orientation outside swamps. { // Sidestep locks orientation. - if ((IsHeld(In::LeftStep) || (IsHeld(In::Walk) && IsHeld(In::Left))) || - (IsHeld(In::RightStep) || (IsHeld(In::Walk) && IsHeld(In::Right)))) + if ((IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left))) || + (IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right)))) { ModulateLaraTurnRateY(item, 0, 0, 0); } @@ -508,7 +508,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll) } } - if (IsHeld(In::LeftStep) || (IsHeld(In::Walk) && IsHeld(In::Left))) + if (IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left))) { if (TestLaraStepLeft(item, coll)) item->Animation.TargetState = LS_STEP_LEFT; @@ -517,7 +517,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll) return; } - else if (IsHeld(In::RightStep) || (IsHeld(In::Walk) && IsHeld(In::Right))) + else if (IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right))) { if (TestLaraStepRight(item, coll)) item->Animation.TargetState = LS_STEP_RIGHT; @@ -571,7 +571,7 @@ void PseudoLaraAsWadeIdle(ItemInfo* item, CollisionInfo* coll) { auto* lara = GetLaraInfo(item); - if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll)) + if (IsHeld(In::Jump) && TestLaraJumpUp(item, coll)) { item->Animation.TargetState = LS_JUMP_PREPARE; lara->Control.JumpDirection = JumpDirection::Up; @@ -798,7 +798,7 @@ void lara_as_run_back(ItemInfo* item, CollisionInfo* coll) { auto* lara = GetLaraInfo(item); - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3); @@ -822,7 +822,6 @@ void lara_col_run_back(ItemInfo* item, CollisionInfo* coll) lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(180.0f); item->Animation.Velocity.y = 0; item->Animation.IsAirborne = false; - coll->Setup.BlockFloorSlopeDown = true; coll->Setup.LowerFloorBound = NO_LOWER_BOUND; coll->Setup.UpperFloorBound = -STEPUP_HEIGHT; coll->Setup.LowerCeilingBound = 0; @@ -885,7 +884,7 @@ void lara_as_turn_right_slow(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { SetLaraJumpDirection(item, coll); if (lara->Control.JumpDirection != JumpDirection::None) @@ -994,7 +993,7 @@ void PsuedoLaraAsWadeTurnRightSlow(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX); - if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll)) + if (IsHeld(In::Jump) && TestLaraJumpUp(item, coll)) { item->Animation.TargetState = LS_JUMP_PREPARE; lara->Control.JumpDirection = JumpDirection::Up; @@ -1131,7 +1130,7 @@ void lara_as_turn_left_slow(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { SetLaraJumpDirection(item, coll); if (lara->Control.JumpDirection != JumpDirection::None) @@ -1240,7 +1239,7 @@ void PsuedoLaraAsWadeTurnLeftSlow(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX); - if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll)) + if (IsHeld(In::Jump) && TestLaraJumpUp(item, coll)) { item->Animation.TargetState = LS_JUMP_PREPARE; lara->Control.JumpDirection = JumpDirection::Up; @@ -1465,7 +1464,7 @@ void lara_as_walk_back(ItemInfo* item, CollisionInfo* coll) return; } - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3); @@ -1486,7 +1485,7 @@ void PseudoLaraAsSwampWalkBack(ItemInfo* item, CollisionInfo* coll) { auto* lara = GetLaraInfo(item); - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX / 3); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX / 3); @@ -1563,7 +1562,7 @@ void lara_as_turn_right_fast(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { SetLaraJumpDirection(item, coll); if (lara->Control.JumpDirection != JumpDirection::None) @@ -1690,7 +1689,7 @@ void lara_as_turn_left_fast(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { SetLaraJumpDirection(item, coll); if (lara->Control.JumpDirection != JumpDirection::None) @@ -1826,7 +1825,7 @@ void lara_as_step_right(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, 0, 0, 0); else { - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); } @@ -1920,7 +1919,7 @@ void lara_as_step_left(ItemInfo* item, CollisionInfo* coll) ModulateLaraTurnRateY(item, 0, 0, 0); else { - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); } @@ -2143,7 +2142,7 @@ void lara_as_wade_forward(ItemInfo* item, CollisionInfo* coll) return; } - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 2, LARA_LEAN_MAX); @@ -2175,7 +2174,7 @@ void PseudoLaraAsSwampWadeForward(ItemInfo* item, CollisionInfo* coll) { auto* lara = GetLaraInfo(item); - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX * 0.6f); @@ -2264,13 +2263,13 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll) return; } - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX); } - if (TrInput & IN_JUMP || lara->Control.RunJumpQueued) + if (IsHeld(In::Jump) || lara->Control.RunJumpQueued) { if (TrInput & IN_WALK || !g_GameFlow->HasSprintJump()) { @@ -2400,7 +2399,7 @@ void lara_as_sprint_dive(ItemInfo* item, CollisionInfo* coll) if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME) lara->Control.Count.Run = LARA_RUN_JUMP_TIME; - if (TrInput & (IN_LEFT | IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX); ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX * 0.6f); diff --git a/TombEngine/Game/Lara/lara_cheat.cpp b/TombEngine/Game/Lara/lara_cheat.cpp index f858e6c96..f014708ef 100644 --- a/TombEngine/Game/Lara/lara_cheat.cpp +++ b/TombEngine/Game/Lara/lara_cheat.cpp @@ -35,10 +35,7 @@ void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_ACTION) TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150); - if (TrInput & IN_OPTION) - lara->Control.TurnRate = -ANGLE(12.0f); - - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL * 2; if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX * 2) diff --git a/TombEngine/Game/Lara/lara_climb.cpp b/TombEngine/Game/Lara/lara_climb.cpp index 4db8ce34b..c4f8d050b 100644 --- a/TombEngine/Game/Lara/lara_climb.cpp +++ b/TombEngine/Game/Lara/lara_climb.cpp @@ -378,7 +378,7 @@ void lara_as_climb_idle(ItemInfo* item, CollisionInfo* coll) item->Animation.TargetState = LS_LADDER_RIGHT; lara->Control.MoveAngle = item->Pose.Orientation.y + ANGLE(90.0f); } - else if (TrInput & IN_JUMP) + else if (IsHeld(In::Jump)) { if (item->Animation.AnimNumber == LA_LADDER_IDLE) { @@ -619,8 +619,8 @@ int LaraClimbRightCornerTest(ItemInfo* item, CollisionInfo* coll) if (angle && angle != SOUTH) { - x = (item->Pose.Position.x & -SECTOR(1)) - (item->Pose.Position.z % SECTOR(1)) + SECTOR(1); - z = (item->Pose.Position.z & -SECTOR(1)) - (item->Pose.Position.x % SECTOR(1)) + SECTOR(1); + x = (item->Pose.Position.x & -BLOCK(1)) - (item->Pose.Position.z % BLOCK(1)) + BLOCK(1); + z = (item->Pose.Position.z & -BLOCK(1)) - (item->Pose.Position.x % BLOCK(1)) + BLOCK(1); } else { @@ -649,24 +649,24 @@ int LaraClimbRightCornerTest(ItemInfo* item, CollisionInfo* coll) switch (angle) { case NORTH: - x = ((item->Pose.Position.x + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.z % SECTOR(1)) + SECTOR(1); - z = ((item->Pose.Position.z + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.x % SECTOR(1)) + SECTOR(1); + x = ((item->Pose.Position.x + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.z % BLOCK(1)) + BLOCK(1); + z = ((item->Pose.Position.z + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.x % BLOCK(1)) + BLOCK(1); break; case SOUTH: - x = ((item->Pose.Position.x - SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.z % SECTOR(1)) + SECTOR(1); - z = ((item->Pose.Position.z - SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.x % SECTOR(1)) + SECTOR(1); + x = ((item->Pose.Position.x - BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.z % BLOCK(1)) + BLOCK(1); + z = ((item->Pose.Position.z - BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.x % BLOCK(1)) + BLOCK(1); break; case EAST: - x = ((item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1)) ^ (item->Pose.Position.x + SECTOR(1)); - z = (item->Pose.Position.z ^ ((item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1))) - SECTOR(1); + x = ((item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1)) ^ (item->Pose.Position.x + BLOCK(1)); + z = (item->Pose.Position.z ^ ((item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1))) - BLOCK(1); break; case WEST: default: - x = (item->Pose.Position.x ^ (item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1)) - SECTOR(1); - z = ((item->Pose.Position.z ^ item->Pose.Position.x) % SECTOR(1)) ^ (item->Pose.Position.z + SECTOR(1)); + x = (item->Pose.Position.x ^ (item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1)) - BLOCK(1); + z = ((item->Pose.Position.z ^ item->Pose.Position.x) % BLOCK(1)) ^ (item->Pose.Position.z + BLOCK(1)); break; } @@ -713,8 +713,8 @@ int LaraClimbLeftCornerTest(ItemInfo* item, CollisionInfo* coll) } else { - x = (item->Pose.Position.x & -SECTOR(1)) - (item->Pose.Position.z & WALL_MASK) + SECTOR(1); - z = (item->Pose.Position.z & -SECTOR(1)) - (item->Pose.Position.x & WALL_MASK) + SECTOR(1); + x = (item->Pose.Position.x & -BLOCK(1)) - (item->Pose.Position.z & WALL_MASK) + BLOCK(1); + z = (item->Pose.Position.z & -BLOCK(1)) - (item->Pose.Position.x & WALL_MASK) + BLOCK(1); } int shift = 0; @@ -738,24 +738,24 @@ int LaraClimbLeftCornerTest(ItemInfo* item, CollisionInfo* coll) switch (angle) { case NORTH: - x = (item->Pose.Position.x ^ ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK)) - SECTOR(1); - z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z + SECTOR(1)); + x = (item->Pose.Position.x ^ ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK)) - BLOCK(1); + z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z + BLOCK(1)); break; case SOUTH: - x = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.x + SECTOR(1)); - z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z - SECTOR(1)); + x = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.x + BLOCK(1)); + z = ((item->Pose.Position.z ^ item->Pose.Position.x) & WALL_MASK) ^ (item->Pose.Position.z - BLOCK(1)); break; case EAST: - x = ((item->Pose.Position.x + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.z & WALL_MASK) + SECTOR(1); - z = ((item->Pose.Position.z + SECTOR(1)) & -SECTOR(1)) - (item->Pose.Position.x & WALL_MASK) + SECTOR(1); + x = ((item->Pose.Position.x + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.z & WALL_MASK) + BLOCK(1); + z = ((item->Pose.Position.z + BLOCK(1)) & -BLOCK(1)) - (item->Pose.Position.x & WALL_MASK) + BLOCK(1); break; case WEST: default: - x = (item->Pose.Position.x & -SECTOR(1)) - (item->Pose.Position.z & WALL_MASK); - z = (item->Pose.Position.z & -SECTOR(1)) - (item->Pose.Position.x & WALL_MASK); + x = (item->Pose.Position.x & -BLOCK(1)) - (item->Pose.Position.z & WALL_MASK); + z = (item->Pose.Position.z & -BLOCK(1)) - (item->Pose.Position.x & WALL_MASK); break; } diff --git a/TombEngine/Game/Lara/lara_collide.cpp b/TombEngine/Game/Lara/lara_collide.cpp index 378914128..4969d72c2 100644 --- a/TombEngine/Game/Lara/lara_collide.cpp +++ b/TombEngine/Game/Lara/lara_collide.cpp @@ -633,8 +633,8 @@ void LaraWaterCurrent(ItemInfo* item, CollisionInfo* coll) const auto& sink = g_Level.Sinks[lara->Context.WaterCurrentActive - 1]; short headingAngle = Geometry::GetOrientToPoint(item->Pose.Position.ToVector3(), sink.Position).y; - lara->Context.WaterCurrentPull.x += ((sink.Strength * SECTOR(1) * phd_sin(headingAngle)) - lara->Context.WaterCurrentPull.x) / 16; - lara->Context.WaterCurrentPull.z += ((sink.Strength * SECTOR(1) * phd_cos(headingAngle)) - lara->Context.WaterCurrentPull.z) / 16; + lara->Context.WaterCurrentPull.x += ((sink.Strength * BLOCK(1) * phd_sin(headingAngle)) - lara->Context.WaterCurrentPull.x) / 16; + lara->Context.WaterCurrentPull.z += ((sink.Strength * BLOCK(1) * phd_cos(headingAngle)) - lara->Context.WaterCurrentPull.z) / 16; item->Pose.Position.y += (sink.Position.y - item->Pose.Position.y) / 16; } diff --git a/TombEngine/Game/Lara/lara_crawl.cpp b/TombEngine/Game/Lara/lara_crawl.cpp index dfbe187ff..c1796da68 100644 --- a/TombEngine/Game/Lara/lara_crawl.cpp +++ b/TombEngine/Game/Lara/lara_crawl.cpp @@ -40,7 +40,7 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -65,7 +65,7 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll) if (TrInput & (IN_LEFT | IN_RIGHT)) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX); - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK)) @@ -157,7 +157,7 @@ void lara_as_crouch_roll(ItemInfo* item, CollisionInfo* coll) lara->Control.CanLook = false; coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -230,7 +230,7 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll) auto* lara = GetLaraInfo(item); coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -243,7 +243,7 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_LOOK) LookUpDown(item); - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) && @@ -287,7 +287,7 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll) auto* lara = GetLaraInfo(item); coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -300,7 +300,7 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_LOOK) LookUpDown(item); - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll) && @@ -344,11 +344,11 @@ void lara_as_crouch_turn_180(ItemInfo* item, CollisionInfo* coll) auto* lara = GetLaraInfo(item); coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & (IN_FORWARD | IN_BACK) && TestLaraCrouchToCrawl(item)) @@ -381,7 +381,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll) { coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -409,7 +409,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll) if (TrInput & (IN_LEFT | IN_RIGHT)) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX); - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK)) @@ -419,7 +419,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll) } if ((TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) || - (TrInput & (IN_DRAW | IN_FLARE) && + ((IsHeld(In::Draw) || IsHeld(In::Flare)) && !IsStandingWeapon(item, lara->Control.Weapon.GunType) && HasStateDispatch(item, LS_CROUCH_IDLE))) { item->Animation.TargetState = LS_CROUCH_IDLE; @@ -431,7 +431,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll) { auto crawlVaultResult = TestLaraCrawlVault(item, coll); - if (TrInput & (IN_ACTION | IN_JUMP) && crawlVaultResult.Success && + if ((IsHeld(In::Action) || IsHeld(In::Jump)) && crawlVaultResult.Success && g_GameFlow->HasCrawlExtended()) { item->Animation.TargetState = crawlVaultResult.TargetState; @@ -447,7 +447,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll) } else if (TrInput & IN_BACK) { - if (TrInput & (IN_ACTION | IN_JUMP) && TestLaraCrawlToHang(item, coll)) + if ((IsHeld(In::Action) || IsHeld(In::Jump)) && TestLaraCrawlToHang(item, coll)) { item->Animation.TargetState = LS_CRAWL_TO_HANG; DoLaraCrawlToHangSnap(item, coll); @@ -532,7 +532,7 @@ void lara_as_crawl_forward(ItemInfo* item, CollisionInfo* coll) lara->Control.HandStatus = HandStatus::Busy; coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -548,7 +548,7 @@ void lara_as_crawl_forward(ItemInfo* item, CollisionInfo* coll) ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX); } - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) @@ -628,7 +628,7 @@ void lara_as_crawl_back(ItemInfo* item, CollisionInfo* coll) lara->Control.HandStatus = HandStatus::Busy; coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -644,7 +644,7 @@ void lara_as_crawl_back(ItemInfo* item, CollisionInfo* coll) ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX); } - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_BACK) @@ -715,7 +715,7 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll) lara->Control.HandStatus = HandStatus::Busy; coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -725,7 +725,7 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll) return; } - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) @@ -776,7 +776,7 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll) lara->Control.HandStatus = HandStatus::Busy; coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); @@ -786,7 +786,7 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll) return; } - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { if (TrInput & IN_SPRINT && TestLaraCrouchRoll(item, coll)) @@ -835,11 +835,11 @@ void lara_as_crawl_turn_180(ItemInfo* item, CollisionInfo* coll) auto* lara = GetLaraInfo(item); coll->Setup.EnableSpasm = false; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); AlignLaraToSurface(item); - if ((TrInput & IN_CROUCH || lara->Control.KeepLow) && + if ((IsHeld(In::Crouch) || lara->Control.KeepLow) && lara->Control.WaterStatus != WaterStatus::Wade) { item->Animation.TargetState = LS_CRAWL_IDLE; @@ -864,7 +864,7 @@ void lara_col_crawl_to_hang(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableObjectPush = true; coll->Setup.EnableSpasm = false; Camera.targetAngle = 0; - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); ResetPlayerLean(item, 1 / 6.0f); diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp index 650caca11..81bfb894f 100644 --- a/TombEngine/Game/Lara/lara_fire.cpp +++ b/TombEngine/Game/Lara/lara_fire.cpp @@ -519,7 +519,7 @@ void HandleWeapon(ItemInfo& laraItem) else if (player.Control.HandStatus == HandStatus::Free) { // Draw weapon. - if (IsHeld(In::DrawWeapon)) + if (IsHeld(In::Draw)) { // No weapon - no any actions. if (player.Control.Weapon.LastGunType != LaraWeaponType::None) @@ -547,7 +547,7 @@ void HandleWeapon(ItemInfo& laraItem) } } - if ((IsHeld(In::DrawWeapon) && player.Control.Weapon.LastGunType != LaraWeaponType::None) || + if ((IsHeld(In::Draw) && player.Control.Weapon.LastGunType != LaraWeaponType::None) || player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType) { if (player.Control.IsLow && @@ -596,7 +596,7 @@ void HandleWeapon(ItemInfo& laraItem) } else if (player.Control.HandStatus == HandStatus::WeaponReady) { - if (IsHeld(In::DrawWeapon) || + if (IsHeld(In::Draw) || player.Control.Weapon.RequestGunType != player.Control.Weapon.GunType) { player.Control.HandStatus = HandStatus::WeaponUndraw; diff --git a/TombEngine/Game/Lara/lara_hang.cpp b/TombEngine/Game/Lara/lara_hang.cpp index affb268c9..cb61bf2c3 100644 --- a/TombEngine/Game/Lara/lara_hang.cpp +++ b/TombEngine/Game/Lara/lara_hang.cpp @@ -130,7 +130,7 @@ void lara_col_hang(ItemInfo* item, CollisionInfo* coll) } // TODO: Allow direction locking just like with standing jumps. Needs new ledge jump prepare state? -- Sezz 24.10.2022 - if (TrInput & IN_JUMP && TestLaraLedgeJump(item, coll)) + if (IsHeld(In::Jump) && TestLaraLedgeJump(item, coll)) { if (TrInput & IN_BACK) item->Animation.TargetState = LS_JUMP_FORWARD; diff --git a/TombEngine/Game/Lara/lara_helpers.cpp b/TombEngine/Game/Lara/lara_helpers.cpp index d6458d541..8d3b09d6c 100644 --- a/TombEngine/Game/Lara/lara_helpers.cpp +++ b/TombEngine/Game/Lara/lara_helpers.cpp @@ -13,6 +13,7 @@ #include "Game/Lara/lara_collide.h" #include "Game/Lara/lara_fire.h" #include "Game/Lara/lara_tests.h" +#include "Game/savegame.h" #include "Game/Setup.h" #include "Math/Math.h" #include "Renderer/Renderer11.h" @@ -68,7 +69,7 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll) lara->Control.RunJumpQueued = false; // Reset lean. - if ((!lara->Control.IsMoving || (lara->Control.IsMoving && !(TrInput & (IN_LEFT | IN_RIGHT)))) && + if ((!lara->Control.IsMoving || (lara->Control.IsMoving && !(IsHeld(In::Left) || IsHeld(In::Right)))) && (!lara->Control.IsLow && item->Animation.ActiveState != LS_DEATH)) // HACK: Don't interfere with surface alignment in crouch, crawl, and death states. { ResetPlayerLean(item, 1 / 6.0f); @@ -76,20 +77,186 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll) // Reset crawl flex. if (!(TrInput & IN_LOOK) && coll->Setup.Height > LARA_HEIGHT - LARA_HEADROOM && // HACK - (!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(TrInput & (IN_LEFT | IN_RIGHT))))) + (!item->Animation.Velocity.z || (item->Animation.Velocity.z && !(IsHeld(In::Left) || IsHeld(In::Right))))) { ResetPlayerFlex(item, 0.1f); } // Apply and reset turn rate. item->Pose.Orientation.y += lara->Control.TurnRate; - if (!(TrInput & (IN_LEFT | IN_RIGHT))) + if (!(IsHeld(In::Left) || IsHeld(In::Right))) lara->Control.TurnRate = 0; lara->Control.IsLow = false; lara->Control.IsMonkeySwinging = false; } +static void UsePlayerMedipack(ItemInfo& item) +{ + auto& player = GetLaraInfo(item); + + // Can't use medipack; return early. + if (item.HitPoints <= 0 || + (item.HitPoints >= LARA_HEALTH_MAX && player.Status.Poison == 0)) + { + return; + } + + bool hasUsedMedipack = false; + + if (IsClicked(In::SmallMedipack) && + player.Inventory.TotalSmallMedipacks != 0) + { + hasUsedMedipack = true; + + item.HitPoints += LARA_HEALTH_MAX / 2; + if (item.HitPoints > LARA_HEALTH_MAX) + item.HitPoints = LARA_HEALTH_MAX; + + if (player.Inventory.TotalSmallMedipacks != -1) + player.Inventory.TotalSmallMedipacks--; + } + else if (IsClicked(In::LargeMedipack) && + player.Inventory.TotalLargeMedipacks != 0) + { + hasUsedMedipack = true; + item.HitPoints = LARA_HEALTH_MAX; + + if (player.Inventory.TotalLargeMedipacks != -1) + player.Inventory.TotalLargeMedipacks--; + } + + if (hasUsedMedipack) + { + player.Status.Poison = 0; + Statistics.Game.HealthUsed++; + SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always); + } +} + +static std::optional GetPlayerScrolledWeaponType(const ItemInfo& item, LaraWeaponType currentWeaponType, bool getPrev) +{ + static const auto SCROLL_WEAPON_TYPES = std::vector + { + LaraWeaponType::Pistol, + LaraWeaponType::Shotgun, + LaraWeaponType::Uzi, + LaraWeaponType::Revolver, + LaraWeaponType::GrenadeLauncher, + LaraWeaponType::Crossbow, + LaraWeaponType::HarpoonGun, + LaraWeaponType::HK, + LaraWeaponType::RocketLauncher + }; + + auto& player = GetLaraInfo(item); + + // Get vector index for current weapon type. + auto currentIndex = std::optional(std::nullopt); + for (int i = 0; i < SCROLL_WEAPON_TYPES.size(); i++) + { + if (SCROLL_WEAPON_TYPES[i] == currentWeaponType) + { + currentIndex = i; + break; + } + } + + // Invalid current weapon type; return nullopt. + if (!currentIndex.has_value()) + return std::nullopt; + + // Getter for next index. + auto getNextIndex = [getPrev](unsigned int index) + { + return (index + (getPrev ? ((unsigned int)SCROLL_WEAPON_TYPES.size() - 1) : 1)) % (unsigned int)SCROLL_WEAPON_TYPES.size(); + }; + + // Get next valid weapon type in sequence. + unsigned int nextIndex = getNextIndex(*currentIndex); + while (nextIndex != *currentIndex) + { + auto nextWeaponType = SCROLL_WEAPON_TYPES[nextIndex]; + if (player.Weapons[(int)nextWeaponType].Present) + return nextWeaponType; + + nextIndex = getNextIndex(nextIndex); + } + + // No valid weapon type; return nullopt. + return std::nullopt; +} + +void HandlePlayerQuickActions(ItemInfo& item) +{ + auto& player = GetLaraInfo(item); + + // Handle medipacks. + if (IsClicked(In::SmallMedipack) || IsClicked(In::LargeMedipack)) + UsePlayerMedipack(item); + + // Handle weapon scroll requests. + if (IsClicked(In::PreviousWeapon) || IsClicked(In::NextWeapon)) + { + bool getPrev = IsClicked(In::PreviousWeapon); + auto weaponType = GetPlayerScrolledWeaponType(item, player.Control.Weapon.GunType, getPrev); + + if (weaponType.has_value()) + player.Control.Weapon.RequestGunType = *weaponType; + } + + // Handle weapon requests. + if (IsClicked(In::Weapon1) && player.Weapons[(int)LaraWeaponType::Pistol].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::Pistol; + + if (IsClicked(In::Weapon2) && player.Weapons[(int)LaraWeaponType::Shotgun].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::Shotgun; + + if (IsClicked(In::Weapon3) && player.Weapons[(int)LaraWeaponType::Uzi].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::Uzi; + + if (IsClicked(In::Weapon4) && player.Weapons[(int)LaraWeaponType::Revolver].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::Revolver; + + if (IsClicked(In::Weapon5) && player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher; + + if (IsClicked(In::Weapon6) && player.Weapons[(int)LaraWeaponType::Crossbow].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::Crossbow; + + if (IsClicked(In::Weapon7) && player.Weapons[(int)LaraWeaponType::HarpoonGun].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun; + + if (IsClicked(In::Weapon8) && player.Weapons[(int)LaraWeaponType::HK].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::HK; + + if (IsClicked(In::Weapon9) && player.Weapons[(int)LaraWeaponType::RocketLauncher].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher; + + // TODO: 10th possible weapon, probably grapple gun. + /*if (IsClicked(In::Weapon10) && player.Weapons[(int)LaraWeaponType::].Present) + player.Control.Weapon.RequestGunType = LaraWeaponType::;*/ + + // TODO: Could theoretically remove SwitchTarget and instead do unique behaviour handling using only Look. -- Sezz 2023.07.08 + // HACK: Handle target switch when locked on to an entity. + if (player.Control.HandStatus == HandStatus::WeaponReady && + player.TargetEntity != nullptr) + { + if (IsClicked(In::Look)) + { + ActionMap[(int)In::SwitchTarget].Update(true); + } + else + { + ClearAction(In::SwitchTarget); + } + } + else + { + ClearAction(In::SwitchTarget); + } +} + bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll) { auto* lara = GetLaraInfo(item); @@ -229,7 +396,7 @@ void HandlePlayerAirBubbles(ItemInfo* item) SoundEffect(SFX_TR4_LARA_BUBBLES, &item->Pose, SoundEnvironment::Water); const auto& level = *g_GameFlow->GetLevel(CurrentLevel); - + auto pos = (level.GetLaraType() == LaraType::Divesuit) ? GetJointPosition(item, LM_TORSO, Vector3i(0, -192, -160)).ToVector3() : GetJointPosition(item, LM_HEAD, Vector3i(0, -4, -64)).ToVector3(); @@ -243,12 +410,9 @@ void HandlePlayerAirBubbles(ItemInfo* item) // Potential solutions: // 1. Consider floor tilt when translating objects. // 2. Object parenting. -- Sezz 2022.10.28 -void EaseOutLaraHeight(ItemInfo* item, int height) +void EasePlayerVerticalPosition(ItemInfo* item, int height) { - constexpr auto LINEAR_THRESHOLD = STEPUP_HEIGHT / 2; - constexpr auto EASING_THRESHOLD_MIN = BLOCK(1.0f / 64); - constexpr auto LINEAR_RATE = 50; - constexpr auto EASING_ALPHA = 0.35f; + constexpr auto LINEAR_RATE_MIN = 50.0f; // Check for wall. if (height == NO_HEIGHT) @@ -261,18 +425,12 @@ void EaseOutLaraHeight(ItemInfo* item, int height) return; } - int easingThreshold = std::max(abs(item->Animation.Velocity.z), EASING_THRESHOLD_MIN); - // Handle regular case. - if (abs(height) > LINEAR_THRESHOLD) + float linearRate = std::max(LINEAR_RATE_MIN, abs(item->Animation.Velocity.z)); + if (abs(height) > linearRate) { int sign = std::copysign(1, height); - item->Pose.Position.y += LINEAR_RATE * sign; - } - else if (abs(height) > easingThreshold) - { - int vPos = item->Pose.Position.y; - item->Pose.Position.y = (int)round(Lerp(vPos, vPos + height, EASING_ALPHA)); + item->Pose.Position.y += linearRate * sign; } else { @@ -306,12 +464,12 @@ void DoLaraStep(ItemInfo* item, CollisionInfo* coll) } } - EaseOutLaraHeight(item, coll->Middle.Floor); + EasePlayerVerticalPosition(item, coll->Middle.Floor); } void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll) { - EaseOutLaraHeight(item, coll->Middle.Ceiling); + EasePlayerVerticalPosition(item, coll->Middle.Ceiling); } void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll) @@ -513,7 +671,7 @@ void ModulateLaraSwimTurnRates(ItemInfo* item, CollisionInfo* coll) auto* lara = GetLaraInfo(item); /*if (TrInput & (IN_FORWARD | IN_BACK)) - ModulateLaraTurnRateX(item, 0, 0, 0);*/ + ModulateLaraTurnRateX(item, 0, 0, 0);*/ if (TrInput & IN_FORWARD) item->Pose.Orientation.x -= ANGLE(3.0f); @@ -609,16 +767,16 @@ void UpdateLaraSubsuitAngles(ItemInfo* item) else if (lara->Control.TurnRate < 0) lara->Control.Subsuit.Velocity[1] += 2 * abs(lara->Control.TurnRate); - if (lara->Control.Subsuit.Velocity[0] > SECTOR(1.5f)) - lara->Control.Subsuit.Velocity[0] = SECTOR(1.5f); + if (lara->Control.Subsuit.Velocity[0] > BLOCK(1.5f)) + lara->Control.Subsuit.Velocity[0] = BLOCK(1.5f); - if (lara->Control.Subsuit.Velocity[1] > SECTOR(1.5f)) - lara->Control.Subsuit.Velocity[1] = SECTOR(1.5f); + if (lara->Control.Subsuit.Velocity[1] > BLOCK(1.5f)) + lara->Control.Subsuit.Velocity[1] = BLOCK(1.5f); if (lara->Control.Subsuit.Velocity[0] != 0 || lara->Control.Subsuit.Velocity[1] != 0) { - auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / SECTOR(8); - auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / SECTOR(8); + auto mul1 = (float)abs(lara->Control.Subsuit.Velocity[0]) / BLOCK(8); + auto mul2 = (float)abs(lara->Control.Subsuit.Velocity[1]) / BLOCK(8); auto vol = ((mul1 + mul2) * 5.0f) + 0.5f; SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_ENGINE, &item->Pose, SoundEnvironment::Water, 1.0f + (mul1 + mul2), vol); } @@ -686,7 +844,7 @@ void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll) //lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness); } //else - //lara->ExtraVelocity.x += minVelocity; + //lara->ExtraVelocity.x += minVelocity; } void AlignLaraToSurface(ItemInfo* item, float alpha) @@ -737,7 +895,7 @@ void SetLaraRunJumpQueue(ItemInfo* item, CollisionInfo* coll) auto* lara = GetLaraInfo(item); int y = item->Pose.Position.y; - int distance = SECTOR(1); + int distance = BLOCK(1); auto probe = GetCollision(item, item->Pose.Orientation.y, distance, -coll->Setup.Height); if ((TestLaraRunJumpForward(item, coll) || // Area close ahead is permissive... diff --git a/TombEngine/Game/Lara/lara_helpers.h b/TombEngine/Game/Lara/lara_helpers.h index 35d3cdd6d..24e5d9384 100644 --- a/TombEngine/Game/Lara/lara_helpers.h +++ b/TombEngine/Game/Lara/lara_helpers.h @@ -12,12 +12,13 @@ struct VaultTestResult; // ----------------------------- void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll); +void HandlePlayerQuickActions(ItemInfo& item); bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll); void HandlePlayerWetnessDrips(ItemInfo& item); void HandlePlayerDiveBubbles(ItemInfo& item); void HandlePlayerAirBubbles(ItemInfo* item); -void EaseOutLaraHeight(ItemInfo* item, int height); +void EasePlayerVerticalPosition(ItemInfo* item, int height); void DoLaraStep(ItemInfo* item, CollisionInfo* coll); void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll); void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll); diff --git a/TombEngine/Game/Lara/lara_initialise.cpp b/TombEngine/Game/Lara/lara_initialise.cpp index e89d81697..08cb427d9 100644 --- a/TombEngine/Game/Lara/lara_initialise.cpp +++ b/TombEngine/Game/Lara/lara_initialise.cpp @@ -12,31 +12,36 @@ using namespace TEN::Hud; -void InitializeLara(bool restore) +LaraInfo lBackup = {}; +int lHitPoints = 0; + +void BackupLara() { - if (Lara.ItemNumber == NO_ITEM) + if (LaraItem == nullptr || LaraItem->Index == NO_ITEM) return; - LaraInfo lBackup = {}; - if (restore) - memcpy(&lBackup, &Lara, sizeof(LaraInfo)); + memcpy(&lBackup, &Lara, sizeof(LaraInfo)); + lHitPoints = LaraItem->HitPoints; +} - short itemNumber = Lara.ItemNumber; +void InitializeLara(bool restore) +{ + if (LaraItem == nullptr || LaraItem->Index == NO_ITEM) + return; + + ZeroMemory(&Lara, sizeof(LaraInfo)); LaraItem->Data = &Lara; LaraItem->Collidable = false; LaraItem->Location.roomNumber = LaraItem->RoomNumber; LaraItem->Location.yNumber = LaraItem->Pose.Position.y; - ZeroMemory(&Lara, sizeof(LaraInfo)); - Lara.Status.Air = LARA_AIR_MAX; Lara.Status.Exposure = LARA_EXPOSURE_MAX; Lara.Status.Poison = 0; Lara.Status.Stamina = LARA_STAMINA_MAX; Lara.Control.CanLook = true; - Lara.ItemNumber = itemNumber; Lara.HitDirection = -1; Lara.Control.Weapon.WeaponItem = NO_ITEM; Lara.Context.WaterSurfaceDist = 100; @@ -46,13 +51,18 @@ void InitializeLara(bool restore) Lara.Location = -1; Lara.HighestLocation = -1; Lara.Control.Rope.Ptr = -1; - LaraItem->HitPoints = LARA_HEALTH_MAX; Lara.Control.HandStatus = HandStatus::Free; if (restore) - InitializeLaraLevelJump(itemNumber, &lBackup); + { + InitializeLaraLevelJump(LaraItem->Index, &lBackup); + LaraItem->HitPoints = lHitPoints; + } else + { InitializeLaraDefaultInventory(); + LaraItem->HitPoints = LARA_HEALTH_MAX; + } InitializeLaraMeshes(LaraItem); InitializeLaraAnims(LaraItem); @@ -143,10 +153,9 @@ void InitializeLaraAnims(ItemInfo* item) } } -void InitializeLaraLoad(short itemNum) +void InitializeLaraLoad(short itemNumber) { - Lara.ItemNumber = itemNum; - LaraItem = &g_Level.Items[itemNum]; + LaraItem = &g_Level.Items[itemNumber]; } void InitializeLaraLevelJump(short itemNum, LaraInfo* lBackup) @@ -157,6 +166,7 @@ void InitializeLaraLevelJump(short itemNum, LaraInfo* lBackup) // Restore inventory. // It restores even puzzle/key items, to reset them, a ResetHub analog must be made. lara->Inventory = lBackup->Inventory; + lara->Control.Weapon.LastGunType = lBackup->Control.Weapon.LastGunType; memcpy(&lara->Weapons, &lBackup->Weapons, sizeof(CarriedWeaponInfo) * int(LaraWeaponType::NumWeapons)); // If no flare present, quit diff --git a/TombEngine/Game/Lara/lara_initialise.h b/TombEngine/Game/Lara/lara_initialise.h index 2cb022644..3469f9d1e 100644 --- a/TombEngine/Game/Lara/lara_initialise.h +++ b/TombEngine/Game/Lara/lara_initialise.h @@ -1,6 +1,7 @@ #pragma once #include "Game/Lara/lara_struct.h" +void BackupLara(); void InitializeLara(bool restore); void InitializeLaraMeshes(ItemInfo* item); void InitializeLaraAnims(ItemInfo* item); diff --git a/TombEngine/Game/Lara/lara_jump.cpp b/TombEngine/Game/Lara/lara_jump.cpp index 4e0446150..87a280cc0 100644 --- a/TombEngine/Game/Lara/lara_jump.cpp +++ b/TombEngine/Game/Lara/lara_jump.cpp @@ -265,12 +265,12 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll) } // JUMP key repressed without directional key; cancel directional jump lock. - if (DbInput & IN_JUMP && !IsDirectionActionHeld()) + if (IsClicked(In::Jump) && !IsDirectionalActionHeld()) lara->Control.JumpDirection = JumpDirection::None; if (((TrInput & IN_FORWARD && !(TrInput & IN_BACK && lara->Control.JumpDirection == JumpDirection::Back)) || // Back jump takes priority in this exception. - !IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Forward) && + !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Forward) && TestLaraJumpForward(item, coll)) { item->Animation.TargetState = LS_JUMP_FORWARD; @@ -278,7 +278,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll) return; } else if ((TrInput & IN_BACK || - !IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Back) && + !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Back) && TestLaraJumpBack(item, coll)) { item->Animation.TargetState = LS_JUMP_BACK; @@ -287,7 +287,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll) } if ((TrInput & IN_LEFT || - !IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Left) && + !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Left) && TestLaraJumpLeft(item, coll)) { item->Animation.TargetState = LS_JUMP_LEFT; @@ -295,7 +295,7 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll) return; } else if ((TrInput & IN_RIGHT || - !IsDirectionActionHeld() && lara->Control.JumpDirection == JumpDirection::Right) && + !IsDirectionalActionHeld() && lara->Control.JumpDirection == JumpDirection::Right) && TestLaraJumpRight(item, coll)) { item->Animation.TargetState = LS_JUMP_RIGHT; diff --git a/TombEngine/Game/Lara/lara_monkey.cpp b/TombEngine/Game/Lara/lara_monkey.cpp index f7f453f76..b1b359943 100644 --- a/TombEngine/Game/Lara/lara_monkey.cpp +++ b/TombEngine/Game/Lara/lara_monkey.cpp @@ -57,7 +57,7 @@ void lara_as_monkey_idle(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing) { - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.TargetState = LS_JUMP_FORWARD; lara->Control.HandStatus = HandStatus::Free; @@ -497,7 +497,7 @@ void lara_as_monkey_turn_left(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing) { - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.TargetState = LS_JUMP_FORWARD; lara->Control.HandStatus = HandStatus::Free; @@ -576,7 +576,7 @@ void lara_as_monkey_turn_right(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing) { - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.TargetState = LS_JUMP_FORWARD; lara->Control.HandStatus = HandStatus::Free; diff --git a/TombEngine/Game/Lara/lara_objects.cpp b/TombEngine/Game/Lara/lara_objects.cpp index e1fc79b76..9d2550f6e 100644 --- a/TombEngine/Game/Lara/lara_objects.cpp +++ b/TombEngine/Game/Lara/lara_objects.cpp @@ -37,7 +37,7 @@ void lara_as_pickup(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableSpasm = false; Camera.targetAngle = -ANGLE(130.0f); Camera.targetElevation = -ANGLE(15.0f); - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); if (TestLastFrame(item)) item->Animation.TargetState = GetNextAnimState(item); @@ -54,7 +54,7 @@ void lara_as_pickup_flare(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableSpasm = false; Camera.targetAngle = ANGLE(130.0f); Camera.targetElevation = -ANGLE(15.0f); - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); if (item->Animation.FrameNumber == (GetAnimData(*item).frameEnd - 1)) lara->Control.HandStatus = HandStatus::Free; @@ -75,7 +75,7 @@ void lara_as_switch_on(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableSpasm = false; Camera.targetAngle = ANGLE(80.0f); Camera.targetElevation = -ANGLE(25.0f); - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); Camera.speed = 6; } @@ -90,7 +90,7 @@ void lara_as_switch_off(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableSpasm = false; Camera.targetAngle = ANGLE(80.0f); Camera.targetElevation = -ANGLE(25.0f); - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); Camera.speed = 6; } @@ -129,7 +129,7 @@ void lara_as_use_key(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableSpasm = false; Camera.targetAngle = -ANGLE(80.0f); Camera.targetElevation = -ANGLE(25.0f); - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); } // State: LS_USE_PUZZLE (43) @@ -143,7 +143,7 @@ void lara_as_use_puzzle(ItemInfo* item, CollisionInfo* coll) coll->Setup.EnableSpasm = false; Camera.targetAngle = -ANGLE(80.0f); Camera.targetElevation = -ANGLE(25.0f); - Camera.targetDistance = SECTOR(1); + Camera.targetDistance = BLOCK(1); if (TestLastFrame(item) && item->ItemFlags[0]) { @@ -266,7 +266,7 @@ void lara_as_horizontal_bar_swing(ItemInfo* item, CollisionInfo* coll) if (TrInput & IN_ACTION) { - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) item->Animation.TargetState = LS_HORIZONTAL_BAR_LEAP; item->Animation.TargetState = LS_HORIZONTAL_BAR_SWING; @@ -502,7 +502,7 @@ void lara_col_rope_swing(ItemInfo* item, CollisionInfo* coll) { auto* lara = GetLaraInfo(item); - Camera.targetDistance = SECTOR(2); + Camera.targetDistance = BLOCK(2); UpdateRopeSwing(item); RopeSwingCollision(item, coll, true); @@ -550,7 +550,7 @@ void lara_col_rope_swing(ItemInfo* item, CollisionInfo* coll) item->Animation.FrameNumber = GetAnimData(item).frameBase; } - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) JumpOffRope(item); } else if (item->Animation.FrameNumber == GetAnimData(LA_ROPE_IDLE_TO_SWING).frameBase + 15) @@ -618,7 +618,7 @@ void lara_as_pole_idle(ItemInfo* item, CollisionInfo* coll) } // TODO: Add forward jump. - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.TargetState = LS_JUMP_BACK; return; @@ -707,7 +707,7 @@ void lara_as_pole_up(ItemInfo* item, CollisionInfo* coll) if (TrInput & (IN_LEFT | IN_RIGHT)) ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.TargetState = LS_POLE_IDLE; return; @@ -756,7 +756,7 @@ void lara_as_pole_down(ItemInfo* item, CollisionInfo* coll) if (TrInput & (IN_LEFT | IN_RIGHT)) ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX, true); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) { item->Animation.TargetState = LS_POLE_IDLE; return; diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index 15a2e96f3..1e6eddf9c 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -9,6 +9,7 @@ #include "Game/control/los.h" #include "Game/effects/Bubble.h" #include "Game/effects/debris.h" +#include "Game/effects/Drip.h" #include "Game/effects/effects.h" #include "Game/effects/item_fx.h" #include "Game/effects/Ripple.h" @@ -31,6 +32,7 @@ #include "Specific/level.h" using namespace TEN::Effects::Bubble; +using namespace TEN::Effects::Drip; using namespace TEN::Effects::Environment; using namespace TEN::Effects::Items; using namespace TEN::Effects::Ripple; @@ -44,6 +46,9 @@ constexpr auto GRENADE_FLASH_TIMEOUT = 4; constexpr auto HARPOON_VELOCITY = BLOCK(0.25f); constexpr auto HARPOON_TIME = 10 * FPS; +constexpr auto BOLT_VELOCITY = BLOCK(0.25f); +constexpr auto BOLT_TIME = 10 * FPS; +constexpr auto BOLT_STUCK_LIFE = 5 * FPS; constexpr auto ROCKET_VELOCITY = CLICK(2); constexpr auto ROCKET_TIME = 4.5f * FPS; constexpr auto GRENADE_VELOCITY = BLOCK(1 / 8.0f); @@ -204,7 +209,7 @@ void AnimateShotgun(ItemInfo& laraItem, LaraWeaponType weaponType) break; case LaraWeaponType::Crossbow: - FireCrossbow(laraItem, nullptr); + FireCrossbow(laraItem); break; case LaraWeaponType::HK: @@ -556,109 +561,112 @@ void UndrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType) } } -ItemInfo* FireHarpoon(ItemInfo& laraItem) +bool FireHarpoon(ItemInfo& laraItem, const std::optional& pose) { auto& player = *GetLaraInfo(&laraItem); auto& ammo = GetAmmo(player, LaraWeaponType::HarpoonGun); if (!ammo) - return nullptr; + return false; player.Control.Weapon.HasFired = true; - // Create a new item for harpoon. - short itemNumber = CreateItem(); + int itemNumber = CreateItem(); if (itemNumber == NO_ITEM) - return nullptr; + return false; + + auto& harpoonItem = g_Level.Items[itemNumber]; + + harpoonItem.ObjectNumber = ID_HARPOON; + harpoonItem.Model.Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f); if (!ammo.HasInfinite()) ammo--; - auto& item = g_Level.Items[itemNumber]; - - item.Model.Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f); - item.ObjectNumber = ID_HARPOON; - item.RoomNumber = laraItem.RoomNumber; - - auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77)); - int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, item.RoomNumber).Position.Floor; - - if (floorHeight >= jointPos.y) + if (pose.has_value()) { - item.Pose.Position = jointPos; + harpoonItem.Pose.Position = pose->Position; + harpoonItem.RoomNumber = laraItem.RoomNumber; + + InitializeItem(itemNumber); + + harpoonItem.Pose.Orientation = EulerAngles( + player.LeftArm.Orientation.x + laraItem.Pose.Orientation.x, + player.LeftArm.Orientation.y + laraItem.Pose.Orientation.y, + 0); } else { - item.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z); - item.RoomNumber = laraItem.RoomNumber; + auto jointPos = GetJointPosition(&laraItem, LM_RHAND, Vector3i(-2, 373, 77)); + harpoonItem.RoomNumber = laraItem.RoomNumber; + + int floorHeight = GetCollision(jointPos.x, jointPos.y, jointPos.z, harpoonItem.RoomNumber).Position.Floor; + if (floorHeight >= jointPos.y) + { + harpoonItem.Pose.Position = jointPos; + } + else + { + harpoonItem.Pose.Position = Vector3i(laraItem.Pose.Position.x, jointPos.y, laraItem.Pose.Position.z); + harpoonItem.RoomNumber = laraItem.RoomNumber; + } + + InitializeItem(itemNumber); + + harpoonItem.Pose.Orientation.x = player.LeftArm.Orientation.x + laraItem.Pose.Orientation.x; + harpoonItem.Pose.Orientation.z = 0; + harpoonItem.Pose.Orientation.y = player.LeftArm.Orientation.y + laraItem.Pose.Orientation.y; + + if (!player.LeftArm.Locked) + harpoonItem.Pose.Orientation += player.ExtraTorsoRot; } - InitializeItem(itemNumber); + harpoonItem.Animation.Velocity.z = HARPOON_VELOCITY; + harpoonItem.HitPoints = HARPOON_TIME; - item.Pose.Orientation = EulerAngles( - player.LeftArm.Orientation.x + laraItem.Pose.Orientation.x, - player.LeftArm.Orientation.y + laraItem.Pose.Orientation.y, - 0); + AddActiveItem(itemNumber); - if (!player.LeftArm.Locked) - item.Pose.Orientation += player.ExtraTorsoRot; - - item.Pose.Orientation.z = 0; - item.Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(item.Pose.Orientation.x); - item.Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(item.Pose.Orientation.x); - item.HitPoints = HARPOON_TIME; + harpoonItem.ItemFlags[0] = (int)ProjectileType::Harpoon; Rumble(0.2f, 0.1f); - AddActiveItem(itemNumber); Statistics.Level.AmmoUsed++; Statistics.Game.AmmoUsed++; - return &item; + return true; } - + void HarpoonBoltControl(short itemNumber) { auto& harpoonItem = g_Level.Items[itemNumber]; if (harpoonItem.HitPoints < HARPOON_TIME) { - if (harpoonItem.HitPoints > 0) + harpoonItem.HitPoints--; + + if (harpoonItem.HitPoints == 0) { - harpoonItem.HitPoints--; - } - else - { - ExplodeItemNode(&harpoonItem, 0, 0, BODY_EXPLODE); + ExplodeItemNode(&harpoonItem, 0, 0, BODY_DO_EXPLOSION); KillItem(itemNumber); } return; } - harpoonItem.Pose.Orientation.z += ANGLE(35.0f); - - if (!TestEnvironment(ENV_FLAG_WATER, harpoonItem.RoomNumber)) + if (TestEnvironment(ENV_FLAG_WATER, &harpoonItem)) { - harpoonItem.Pose.Orientation.x -= ANGLE(1.0f); + if (harpoonItem.Animation.Velocity.z > 64.0f) + harpoonItem.Animation.Velocity.z -= harpoonItem.Animation.Velocity.z / 16; - if (harpoonItem.Pose.Orientation.x < ANGLE(-90.0f)) - harpoonItem.Pose.Orientation.x = ANGLE(-90.0f); - - harpoonItem.Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(harpoonItem.Pose.Orientation.x); - harpoonItem.Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(harpoonItem.Pose.Orientation.x); - } - else - { - if (Wibble & 4) - SpawnBubble(harpoonItem.Pose.Position.ToVector3(), harpoonItem.RoomNumber, (int)BubbleFlags::HighAmplitude); - - harpoonItem.Animation.Velocity.y = -HARPOON_VELOCITY * phd_sin(harpoonItem.Pose.Orientation.x) / 2; - harpoonItem.Animation.Velocity.z = HARPOON_VELOCITY * phd_cos(harpoonItem.Pose.Orientation.x) / 2; + if (GlobalCounter & 1) + SpawnBubble(harpoonItem.Pose.Position.ToVector3(), harpoonItem.RoomNumber); } + auto prevPos = harpoonItem.Pose.Position; TranslateItem(&harpoonItem, harpoonItem.Pose.Orientation, harpoonItem.Animation.Velocity.z); - HandleProjectile(harpoonItem, *LaraItem, harpoonItem.Pose.Position, ProjectileType::Harpoon, Weapons[(int)LaraWeaponType::HarpoonGun].Damage); + + int damage = Weapons[(int)LaraWeaponType::HarpoonGun].Damage; + HandleProjectile(harpoonItem, *LaraItem, prevPos, (ProjectileType)harpoonItem.ItemFlags[0], damage); } void FireGrenade(ItemInfo& laraItem) @@ -983,7 +991,7 @@ void RocketControl(short itemNumber) HandleProjectile(rocketItem, *LaraItem, prevPos, ProjectileType::Explosive, Weapons[(int)LaraWeaponType::RocketLauncher].ExplosiveDamage); } -void FireCrossbow(ItemInfo& laraItem, Pose* pos) +void FireCrossbow(ItemInfo& laraItem, const std::optional& pose) { auto& player = *GetLaraInfo(&laraItem); auto& ammo = GetAmmo(player, LaraWeaponType::Crossbow); @@ -1004,14 +1012,14 @@ void FireCrossbow(ItemInfo& laraItem, Pose* pos) if (!ammo.HasInfinite()) ammo--; - if (pos) + if (pose.has_value()) { - boltItem.Pose.Position = pos->Position; + boltItem.Pose.Position = pose->Position; boltItem.RoomNumber = laraItem.RoomNumber; InitializeItem(itemNumber); - boltItem.Pose.Orientation = pos->Orientation; + boltItem.Pose.Orientation = pose->Orientation; } else { @@ -1040,8 +1048,8 @@ void FireCrossbow(ItemInfo& laraItem, Pose* pos) } } - boltItem.Animation.Velocity.z = 512.0f; - boltItem.HitPoints = HARPOON_TIME; + boltItem.Animation.Velocity.z = BOLT_VELOCITY; + boltItem.HitPoints = BOLT_TIME; AddActiveItem(itemNumber); @@ -1074,7 +1082,7 @@ void FireCrossBowFromLaserSight(ItemInfo& laraItem, GameVector* origin, GameVect { auto orient = Geometry::GetOrientToPoint(origin->ToVector3(), target->ToVector3()); auto boltPose = Pose(origin->x, origin->y, origin->z, orient); - FireCrossbow(laraItem, &boltPose); + FireCrossbow(laraItem, boltPose); } void CrossbowBoltControl(short itemNumber) @@ -1412,18 +1420,31 @@ bool EmitFromProjectile(ItemInfo& projectile, ProjectileType type) bool TestProjectileNewRoom(ItemInfo& item, const CollisionResult& coll) { - // Has projectile changed room? + // Check if projectile changed room. if (item.RoomNumber == coll.RoomNumber) return false; - // If currently in water and previously on land, add a ripple. + // If currently in water and previously on land, spawn ripple. if (TestEnvironment(ENV_FLAG_WATER, item.RoomNumber) != TestEnvironment(ENV_FLAG_WATER, coll.RoomNumber)) { + const auto& player = GetLaraInfo(item); + int floorDiff = abs(coll.Position.Floor - item.Pose.Position.y); int ceilingDiff = abs(coll.Position.Ceiling - item.Pose.Position.y); int yPoint = (floorDiff > ceilingDiff) ? coll.Position.Ceiling : coll.Position.Floor; - SpawnRipple(Vector3(item.Pose.Position.x, yPoint, item.Pose.Position.z), item.RoomNumber, Random::GenerateInt(8, 16)); + if (player.Control.Weapon.GunType != LaraWeaponType::GrenadeLauncher && player.Control.Weapon.GunType != LaraWeaponType::RocketLauncher) + { + SpawnSplashDrips( + Vector3(item.Pose.Position.x, yPoint, item.Pose.Position.z), + item.RoomNumber, 3, false); + + SpawnRipple(Vector3(item.Pose.Position.x, yPoint, item.Pose.Position.z), item.RoomNumber, Random::GenerateInt(8, 16)); + } + else + { + Splash(&item); + } } ItemNewRoom(item.Index, coll.RoomNumber); @@ -1458,8 +1479,8 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p bool hasHit = false; bool hasHitNotByEmitter = false; - bool isExplosive = type >= ProjectileType::Explosive; - bool isShatterable = type != ProjectileType::Harpoon; + bool isExplosive = (type >= ProjectileType::Explosive); + bool isShatterable = (type != ProjectileType::Harpoon); // For non-grenade projectiles, check for room collision. if (type < ProjectileType::Grenade) @@ -1467,7 +1488,6 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p if (pointColl.Position.Floor < projectile.Pose.Position.y || pointColl.Position.Ceiling > projectile.Pose.Position.y) { - projectile.Pose.Position = prevPos; hasHit = hasHitNotByEmitter = true; } @@ -1620,18 +1640,16 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p DoDamage(itemPtr, damage); } } - } else if (itemPtr->ObjectNumber >= ID_SMASH_OBJECT1 && itemPtr->ObjectNumber <= ID_SMASH_OBJECT8) { doShatter = hasHit = true; - // Smash objects are legacy objects from TRC. Let's make them explode in the legacy way. + // Smash objects are legacy objects from TRC. Make them explode in legacy way. ExplodeItemNode(itemPtr, 0, 0, 128); - short currentItemNumber = (itemPtr - CollidedItems[0]); - SmashObject(currentItemNumber); - KillItem(currentItemNumber); + SmashObject(itemPtr->Index); + KillItem(itemPtr->Index); } } @@ -1651,7 +1669,7 @@ void HandleProjectile(ItemInfo& projectile, ItemInfo& emitter, const Vector3i& p } else if (doShatter) { - ExplodeItemNode(&projectile, 0, 0, BODY_EXPLODE); + ExplodeItemNode(&projectile, 0, 0, BODY_DO_EXPLOSION); } switch (type) diff --git a/TombEngine/Game/Lara/lara_one_gun.h b/TombEngine/Game/Lara/lara_one_gun.h index 003bac6e6..382d76567 100644 --- a/TombEngine/Game/Lara/lara_one_gun.h +++ b/TombEngine/Game/Lara/lara_one_gun.h @@ -1,9 +1,9 @@ #pragma once +#include "Math/Math.h" + +using namespace TEN::Math; enum class LaraWeaponType; -class GameVector; -class Pose; -class Vector3i; struct ItemInfo; enum class GrenadeType @@ -34,13 +34,13 @@ void UndrawShotgun(ItemInfo& laraItem, LaraWeaponType weaponType); void DrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType); void UndrawShotgunMeshes(ItemInfo& laraItem, LaraWeaponType weaponType); -ItemInfo* FireHarpoon(ItemInfo& laraItem); +bool FireHarpoon(ItemInfo& laraItem, const std::optional& pose = std::nullopt); void HarpoonBoltControl(short itemNumber); void FireGrenade(ItemInfo& laraItem); void GrenadeControl(short itemNumber); void FireRocket(ItemInfo& laraItem); void RocketControl(short itemNumber); -void FireCrossbow(ItemInfo& laraItem, Pose* pos); +void FireCrossbow(ItemInfo& laraItem, const std::optional& pose = std::nullopt); void FireCrossBowFromLaserSight(ItemInfo& laraItem, GameVector* origin, GameVector* target); void CrossbowBoltControl(short itemNumber); diff --git a/TombEngine/Game/Lara/lara_overhang.cpp b/TombEngine/Game/Lara/lara_overhang.cpp index e62d84b4e..d30eac91e 100644 --- a/TombEngine/Game/Lara/lara_overhang.cpp +++ b/TombEngine/Game/Lara/lara_overhang.cpp @@ -361,7 +361,7 @@ void lara_col_slopeclimb(ItemInfo* item, CollisionInfo* coll) if (GetClimbFlags(probeUp.BottomBlock) & slopeData.ClimbOrient && InStrip(item->Pose.Position.x, item->Pose.Position.z, item->Pose.Orientation.y, CLICK(3), CLICK(4))) { - if (GetCollision(probeUp.Block, up.x, up.y, up.z).Position.Ceiling - item->Pose.Position.y <= (SECTOR(1.5f) - 80)) // Check if a wall is actually there. + if (GetCollision(probeUp.Block, up.x, up.y, up.z).Position.Ceiling - item->Pose.Position.y <= (BLOCK(1.5f) - 80)) // Check if a wall is actually there. { AlignToEdge(item, FORWARD_ALIGNMENT); SetAnimation(item, LA_OVERHANG_SLOPE_LADDER_CONVEX_START); @@ -451,7 +451,7 @@ void lara_as_slopeclimb(ItemInfo* item, CollisionInfo* coll) return; Camera.targetElevation = -ANGLE(16.75f); - Camera.targetDistance = SECTOR(1.75f); + Camera.targetDistance = BLOCK(1.75f); Camera.speed = 15; } @@ -470,7 +470,7 @@ void lara_as_slopefall(ItemInfo* item, CollisionInfo* coll) return; Camera.targetElevation = -ANGLE(16.75f); - Camera.targetDistance = SECTOR(1.75f); + Camera.targetDistance = BLOCK(1.75f); Camera.speed = 15; } @@ -547,7 +547,7 @@ void lara_as_slopehang(ItemInfo* item, CollisionInfo* coll) if (Camera.type != CameraType::Chase) return; - Camera.targetElevation = -SECTOR(1); + Camera.targetElevation = -BLOCK(1); Camera.targetDistance = CLICK(6.5f); Camera.speed = 15; } @@ -604,7 +604,7 @@ void lara_as_slopeshimmy(ItemInfo* item, CollisionInfo* coll) if (Camera.type != CameraType::Chase) return; - Camera.targetElevation = -SECTOR(1); + Camera.targetElevation = -BLOCK(1); Camera.targetDistance = CLICK(6.5f); Camera.speed = 15; @@ -634,7 +634,7 @@ void lara_as_slopeclimbup(ItemInfo* item, CollisionInfo* coll) if (Camera.type != CameraType::Chase) return; // If camera mode isn't chase (0) then don't change camera angles. - Camera.targetElevation = SECTOR(2); + Camera.targetElevation = BLOCK(2); Camera.targetDistance = CLICK(7); Camera.speed = 15; @@ -697,12 +697,12 @@ void lara_as_sclimbstart(ItemInfo* item, CollisionInfo* coll) Camera.flags = CF_FOLLOW_CENTER; - int distance = TestLaraWall(item, 0, SECTOR(1.5f), 0) ? SECTOR(1) : CLICK(6.5f); + int distance = TestLaraWall(item, 0, BLOCK(1.5f)) ? BLOCK(1) : CLICK(6.5f); if (item->Animation.FrameNumber < GetAnimData(item).frameEnd) { Camera.targetDistance = distance; - Camera.targetElevation = int(SECTOR(3) * frac); + Camera.targetElevation = int(BLOCK(3) * frac); Camera.targetAngle = int(-ANGLE(180.0f) * frac); Camera.targetspeed = 15; } @@ -710,7 +710,7 @@ void lara_as_sclimbstart(ItemInfo* item, CollisionInfo* coll) { Camera.targetDistance = distance; - Camera.targetElevation = SECTOR(3); + Camera.targetElevation = BLOCK(3); Camera.targetAngle = 0; Camera.targetspeed = 15; } @@ -757,13 +757,13 @@ void lara_as_sclimbstop(ItemInfo* item, CollisionInfo* coll) { Camera.targetAngle = (short)(-ANGLE(90.0f) * frac); - Camera.targetDistance = SECTOR(1.75f) - int(CLICK(2) * frac); + Camera.targetDistance = BLOCK(1.75f) - int(CLICK(2) * frac); Camera.targetspeed = 15; } else { Camera.targetAngle = ANGLE(90.0f); - Camera.targetDistance = SECTOR(1.25f); + Camera.targetDistance = BLOCK(1.25f); Camera.targetspeed = 15; } } diff --git a/TombEngine/Game/Lara/lara_slide.cpp b/TombEngine/Game/Lara/lara_slide.cpp index cd92300bc..878023427 100644 --- a/TombEngine/Game/Lara/lara_slide.cpp +++ b/TombEngine/Game/Lara/lara_slide.cpp @@ -66,7 +66,7 @@ void lara_as_slide_forward(ItemInfo* item, CollisionInfo* coll) else ApproachLaraTargetOrientation(item, direction);*/ - if (TrInput & IN_JUMP && TestLaraSlideJump(item, coll)) + if (IsHeld(In::Jump) && TestLaraSlideJump(item, coll)) { item->Animation.TargetState = LS_JUMP_FORWARD; StopSoundEffect(SFX_TR4_LARA_SLIPPING); @@ -175,7 +175,7 @@ void lara_as_slide_back(ItemInfo* item, CollisionInfo* coll) else ApproachLaraTargetOrientation(item, direction);*/ - if (TrInput & IN_JUMP && TestLaraSlideJump(item, coll)) + if (IsHeld(In::Jump) && TestLaraSlideJump(item, coll)) { item->Animation.TargetState = LS_JUMP_BACK; StopSoundEffect(SFX_TR4_LARA_SLIPPING); diff --git a/TombEngine/Game/Lara/lara_struct.h b/TombEngine/Game/Lara/lara_struct.h index 773fd9102..3cfb03399 100644 --- a/TombEngine/Game/Lara/lara_struct.h +++ b/TombEngine/Game/Lara/lara_struct.h @@ -1280,7 +1280,7 @@ struct PlayerContextData int ProjectedFloorHeight = 0; float CalcJumpVelocity = 0; Pose NextCornerPos = Pose::Zero; - EulerAngles TargetOrientation = EulerAngles::Zero; + EulerAngles TargetOrientation = EulerAngles::Zero; // TargetOrient int WaterSurfaceDist = 0; short WaterCurrentActive = 0; // Sink number? Often used as bool. @@ -1300,8 +1300,6 @@ struct LaraInfo { static constexpr auto TARGET_COUNT_MAX = 8; - int ItemNumber = 0; // TODO: Remove. No longer necessary since ItemInfo already has it. -- Sezz 2023.04.09 - LaraControlData Control = {}; PlayerContextData Context = {}; PlayerStatusData Status = {}; @@ -1319,13 +1317,12 @@ struct LaraInfo ArmInfo RightArm = {}; ItemInfo* TargetEntity = nullptr; // TargetEntityPtr. Should use item number instead? - std::array TargetList = {}; - std::array LastTargets = {}; + std::array TargetList = {}; + std::array LastTargets = {}; // TODO: Rewrite and restore spasm effect. Also move to PlayerEffectData? - int HitFrame = 0; // Frame index. - int HitDirection = 0; // Cardinal direction. - FX_INFO* SpasmEffect = nullptr; // Not saved. + int HitFrame = 0; // Frame index. + int HitDirection = 0; // Cardinal direction. int ExtraAnim = 0; // Item number? Only ever set to NO_ITEM or 1. diff --git a/TombEngine/Game/Lara/lara_surface.cpp b/TombEngine/Game/Lara/lara_surface.cpp index ad3404a93..b22e81b92 100644 --- a/TombEngine/Game/Lara/lara_surface.cpp +++ b/TombEngine/Game/Lara/lara_surface.cpp @@ -60,7 +60,7 @@ void lara_as_surface_idle(ItemInfo* item, CollisionInfo* coll) if (TrInput & (IN_LEFT | IN_RIGHT)) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_MED_TURN_RATE_MAX); - if (DbInput & IN_JUMP) + if (IsClicked(In::Jump)) { SetLaraSwimDiveAnimation(item); return; @@ -125,7 +125,7 @@ void lara_as_surface_swim_forward(ItemInfo* item, CollisionInfo* coll) if (!(TrInput & IN_FORWARD)) item->Animation.TargetState = LS_ONWATER_IDLE; - if (DbInput & IN_JUMP) + if (IsClicked(In::Jump)) SetLaraSwimDiveAnimation(item); item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL; @@ -167,7 +167,7 @@ void lara_as_surface_swim_left(ItemInfo* item, CollisionInfo* coll) if (!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))) item->Animation.TargetState = LS_ONWATER_IDLE; - if (DbInput & IN_JUMP) + if (IsClicked(In::Jump)) SetLaraSwimDiveAnimation(item); item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL; @@ -206,7 +206,7 @@ void lara_as_surface_swim_right(ItemInfo* item, CollisionInfo* coll) if (!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT))) item->Animation.TargetState = LS_ONWATER_IDLE; - if (DbInput & IN_JUMP) + if (IsClicked(In::Jump)) SetLaraSwimDiveAnimation(item); item->Animation.Velocity.y += LARA_SWIM_VELOCITY_ACCEL; @@ -239,7 +239,7 @@ void lara_as_surface_swim_back(ItemInfo* item, CollisionInfo* coll) if (TrInput & (IN_LEFT | IN_RIGHT)) ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_SLOW_MED_TURN_RATE_MAX); - if (DbInput & IN_JUMP) + if (IsClicked(In::Jump)) SetLaraSwimDiveAnimation(item); if (!(TrInput & IN_BACK)) diff --git a/TombEngine/Game/Lara/lara_swim.cpp b/TombEngine/Game/Lara/lara_swim.cpp index 0bdf94215..6af906db7 100644 --- a/TombEngine/Game/Lara/lara_swim.cpp +++ b/TombEngine/Game/Lara/lara_swim.cpp @@ -51,7 +51,7 @@ void lara_as_underwater_idle(ItemInfo* item, CollisionInfo* coll) else ModulateLaraSwimTurnRates(item, coll); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD; item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL; @@ -96,7 +96,7 @@ void lara_as_underwater_swim_forward(ItemInfo* item, CollisionInfo* coll) if (item->Animation.Velocity.y > LARA_SWIM_VELOCITY_MAX) item->Animation.Velocity.y = LARA_SWIM_VELOCITY_MAX; - if (!(TrInput & IN_JUMP)) + if (!(IsHeld(In::Jump))) item->Animation.TargetState = LS_UNDERWATER_INERTIA; } @@ -130,7 +130,7 @@ void lara_as_underwater_inertia(ItemInfo* item, CollisionInfo* coll) else ModulateLaraSubsuitSwimTurnRates(item); - if (TrInput & IN_JUMP) + if (IsHeld(In::Jump)) item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD; item->Animation.Velocity.y -= LARA_SWIM_VELOCITY_DECEL; diff --git a/TombEngine/Game/Lara/lara_tests.cpp b/TombEngine/Game/Lara/lara_tests.cpp index acc0effee..e75075589 100644 --- a/TombEngine/Game/Lara/lara_tests.cpp +++ b/TombEngine/Game/Lara/lara_tests.cpp @@ -53,8 +53,8 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo if (frontLeft.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height) || frontRight.Position.Ceiling > (item->Pose.Position.y - coll->Setup.Height)) return false; - //g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RENDERER_DEBUG_PAGE::LARA_STATS); - //g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xr, right, item->pos.Position.z + zr), 64, Vector4::One, RENDERER_DEBUG_PAGE::LARA_STATS); + //g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xl, left, item->pos.Position.z + zl), 64, Vector4::One, RendererDebugPage::CollisionStats); + //g_Renderer.AddDebugSphere(Vector3(item->pos.Position.x + xr, right, item->pos.Position.z + zr), 64, Vector4::One, RendererDebugPage::CollisionStats); // Determine ledge probe embed offset. // We use 0.2f radius extents here for two purposes. First - we can't guarantee that shifts weren't already applied @@ -71,7 +71,7 @@ bool TestValidLedge(ItemInfo* item, CollisionInfo* coll, bool ignoreHeadroom, bo return false; // Determine allowed slope difference for a given collision radius - auto slopeDelta = ((float)STEPUP_HEIGHT / (float)SECTOR(1)) * (coll->Setup.Radius * 2); + auto slopeDelta = ((float)STEPUP_HEIGHT / (float)BLOCK(1)) * (coll->Setup.Radius * 2); // Discard if there is a slope beyond tolerance delta if (abs(left - right) >= slopeDelta) @@ -773,24 +773,16 @@ bool TestLaraHangSideways(ItemInfo* item, CollisionInfo* coll, short angle) return !res; } -bool TestLaraWall(ItemInfo* item, int distance, int height, int side) +bool TestLaraWall(ItemInfo* item, float dist, float height) { - float s = phd_sin(item->Pose.Orientation.y); - float c = phd_cos(item->Pose.Orientation.y); - - auto start = GameVector( - item->Pose.Position.x + (side * c), - item->Pose.Position.y + height, - item->Pose.Position.z + (-side * s), + auto origin = GameVector( + Geometry::TranslatePoint(item->Pose.Position, item->Pose.Orientation.y, 0.0f, height), + item->RoomNumber); + auto target = GameVector( + Geometry::TranslatePoint(item->Pose.Position, item->Pose.Orientation.y, dist, height), item->RoomNumber); - auto end = GameVector( - item->Pose.Position.x + (distance * s) + (side * c), - item->Pose.Position.y + height, - item->Pose.Position.z + (distance * c) + (-side * s), - item->RoomNumber); - - return !LOS(&start, &end); + return !LOS(&origin, &target); } bool TestLaraFacingCorner(ItemInfo* item, short angle, int distance) @@ -1046,11 +1038,11 @@ bool TestLaraLadderClimbOut(ItemInfo* item, CollisionInfo* coll) // NEW function break; case SOUTH: - item->Pose.Position.z = (item->Pose.Position.z & -SECTOR(1)) + LARA_RADIUS + 1; + item->Pose.Position.z = (item->Pose.Position.z & -BLOCK(1)) + LARA_RADIUS + 1; break; case WEST: - item->Pose.Position.x = (item->Pose.Position.x & -SECTOR(1)) + LARA_RADIUS + 1; + item->Pose.Position.x = (item->Pose.Position.x & -BLOCK(1)) + LARA_RADIUS + 1; break; } @@ -1202,11 +1194,11 @@ bool TestLaraPose(ItemInfo* item, CollisionInfo* coll) if (TestEnvironment(ENV_FLAG_SWAMP, item)) return false; - if (!(TrInput & (IN_FLARE | IN_DRAW)) && // Avoid unsightly concurrent actions. + if (!IsHeld(In::Draw) && !IsHeld(In::Flare) && // Avoid unsightly concurrent actions. lara->Control.HandStatus == HandStatus::Free && // Hands are free. (lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Flare is not being handled. lara->Flare.Life) && - lara->Context.Vehicle == NO_ITEM) // Not in a vehicle. + lara->Context.Vehicle == NO_ITEM) // Not in a vehicle. { return true; } @@ -1638,7 +1630,7 @@ bool TestLaraCrouchRoll(ItemInfo* item, CollisionInfo* coll) // Assess continuity of path. int distance = 0; auto probeA = GetCollision(item); - while (distance < SECTOR(1)) + while (distance < BLOCK(1)) { distance += CLICK(1); auto probeB = GetCollision(item, item->Pose.Orientation.y, distance, -LARA_HEIGHT_CRAWL); @@ -1673,7 +1665,7 @@ bool TestLaraCrouchToCrawl(ItemInfo* item) { auto* lara = GetLaraInfo(item); - if (!(TrInput & (IN_FLARE | IN_DRAW)) && // Avoid unsightly concurrent actions. + if (!IsHeld(In::Draw) && !IsHeld(In::Flare) && // Avoid unsightly concurrent actions. lara->Control.HandStatus == HandStatus::Free && // Hands are free. (lara->Control.Weapon.GunType != LaraWeaponType::Flare || // Not handling flare. TODO: Should be allowed, but the flare animation bugs out right now. @Sezz 2022.03.18 lara->Flare.Life)) @@ -2292,7 +2284,7 @@ CrawlVaultTestResult TestLaraCrawlExitJump(ItemInfo* item, CollisionInfo* coll) CrawlVaultTestResult TestLaraCrawlVault(ItemInfo* item, CollisionInfo* coll) { - if (!(TrInput & (IN_ACTION | IN_JUMP))) + if (!(IsHeld(In::Action) || IsHeld(In::Jump))) return CrawlVaultTestResult{ false }; // Crawl vault exit down 1 step. @@ -2538,7 +2530,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl bool atLeastOnePoleCollided = false; - if (GetCollidedObjects(item, SECTOR(1), true, CollidedItems, nullptr, false) && + if (GetCollidedObjects(item, BLOCK(1), true, CollidedItems, nullptr, false) && CollidedItems[0] != nullptr) { auto laraBox = GameBoundingBox(item).ToBoundingOrientedBox(item->Pose); @@ -2555,7 +2547,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl auto sphere = BoundingSphere(spherePos, poleProbeCollRadius); auto offsetSphere = BoundingSphere(spherePos + sphereOffset2D, poleProbeCollRadius); - //g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + //g_Renderer.AddDebugSphere(sphere.Center, 16.0f, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats); int i = 0; while (CollidedItems[i] != nullptr) @@ -2569,7 +2561,7 @@ bool TestLaraPoleCollision(ItemInfo* item, CollisionInfo* coll, bool goingUp, fl auto poleBox = GameBoundingBox(object).ToBoundingOrientedBox(object->Pose); poleBox.Extents = poleBox.Extents + Vector3(coll->Setup.Radius, 0.0f, coll->Setup.Radius); - //g_Renderer.AddDebugBox(poleBox, Vector4(0, 0, 1, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + //g_Renderer.AddDebugBox(poleBox, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats); if (poleBox.Intersects(sphere) || poleBox.Intersects(offsetSphere)) { diff --git a/TombEngine/Game/Lara/lara_tests.h b/TombEngine/Game/Lara/lara_tests.h index e6f83ba30..72bd7d42c 100644 --- a/TombEngine/Game/Lara/lara_tests.h +++ b/TombEngine/Game/Lara/lara_tests.h @@ -29,7 +29,7 @@ CornerTestResult TestItemAtNextCornerPosition(ItemInfo* item, CollisionInfo* col bool TestHangSwingIn(ItemInfo* item, CollisionInfo* coll); bool TestLaraHangSideways(ItemInfo* item, CollisionInfo* coll, short angle); -bool TestLaraWall(ItemInfo* item, int distance, int height, int side = 0); +bool TestLaraWall(ItemInfo* item, float dist, float height); bool TestLaraFacingCorner(ItemInfo* item, short angle, int distance); bool LaraPositionOnLOS(ItemInfo* item, short angle, int distance); int LaraFloorFront(ItemInfo* item, short angle, int distance); diff --git a/TombEngine/Game/Setup.cpp b/TombEngine/Game/Setup.cpp index 5e259fd78..7cc80311f 100644 --- a/TombEngine/Game/Setup.cpp +++ b/TombEngine/Game/Setup.cpp @@ -31,8 +31,9 @@ using namespace TEN::Effects::Hair; using namespace TEN::Entities; using namespace TEN::Entities::Switches; -ObjectInfo Objects[ID_NUMBER_OBJECTS]; -STATIC_INFO StaticObjects[MAX_STATICS]; +ObjectHandler Objects; +StaticInfo StaticObjects[MAX_STATICS]; + void InitializeGameFlags() { @@ -49,7 +50,6 @@ void InitializeSpecialEffects() memset(&FireSparks, 0, MAX_SPARKS_FIRE * sizeof(FIRE_SPARKS)); memset(&SmokeSparks, 0, MAX_SPARKS_SMOKE * sizeof(SMOKE_SPARKS)); memset(&Gunshells, 0, MAX_GUNSHELL * sizeof(GUNSHELL_STRUCT)); - memset(&Gunflashes, 0, (MAX_GUNFLASH * sizeof(GUNFLASH_STRUCT))); memset(&Blood, 0, MAX_SPARKS_BLOOD * sizeof(BLOOD_STRUCT)); memset(&Splashes, 0, MAX_SPLASHES * sizeof(SPLASH_STRUCT)); memset(&ShockWaves, 0, MAX_SHOCKWAVE * sizeof(SHOCKWAVE_STRUCT)); diff --git a/TombEngine/Game/Setup.h b/TombEngine/Game/Setup.h index 19c69e7da..1441ee2b1 100644 --- a/TombEngine/Game/Setup.h +++ b/TombEngine/Game/Setup.h @@ -142,7 +142,58 @@ struct ObjectInfo } }; -struct STATIC_INFO +class ObjectHandler +{ + private: + ObjectInfo Objects[ID_NUMBER_OBJECTS]; + + ObjectInfo& GetFirstAvailableObject() + { + for (int i = 0; i < ID_NUMBER_OBJECTS; i++) + { + if (Objects[i].loaded) + return Objects[i]; + } + + return Objects[0]; + } + + public: + void Initialize() + { + std::memset(Objects, 0, sizeof(ObjectInfo) * GAME_OBJECT_ID::ID_NUMBER_OBJECTS); + } + + bool CheckID(int index, bool isSilent = false) + { + if (index == GAME_OBJECT_ID::ID_NO_OBJECT || index >= GAME_OBJECT_ID::ID_NUMBER_OBJECTS) + { + if (!isSilent) + { + TENLog("Attempted to access unavailable slot ID (" + std::to_string(index) + "). " + + "Check if last accessed item exists in level.", LogLevel::Warning, LogConfig::Debug); + } + + return false; + } + + return true; + } + + ObjectInfo& operator[](int index) + { + if (CheckID(index)) + { + return Objects[index]; + } + else + { + return GetFirstAvailableObject(); + } + } +}; + +struct StaticInfo { int meshNumber; int flags; @@ -158,8 +209,8 @@ constexpr auto SF_SHATTERABLE = 0x02; constexpr auto GRAVITY = 6.0f; constexpr auto SWAMP_GRAVITY = GRAVITY / 3.0f; -extern ObjectInfo Objects[ID_NUMBER_OBJECTS]; -extern STATIC_INFO StaticObjects[MAX_STATICS]; +extern ObjectHandler Objects; +extern StaticInfo StaticObjects[MAX_STATICS]; void InitializeGameFlags(); void InitializeSpecialEffects(); diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp index 3b211ec2b..fe107924a 100644 --- a/TombEngine/Game/animation.cpp +++ b/TombEngine/Game/animation.cpp @@ -234,6 +234,9 @@ void AnimateItem(ItemInfo* item) unsigned int frameCount = GetNonZeroFrameCount(*animPtr); int currentFrame = item->Animation.FrameNumber - animPtr->frameBase; + auto animAccel = (animPtr->VelocityEnd - animPtr->VelocityStart) / frameCount; + auto animVel = animPtr->VelocityStart + (animAccel * currentFrame); + if (item->Animation.IsAirborne) { if (item->IsLara()) @@ -258,7 +261,7 @@ void AnimateItem(ItemInfo* item) else { item->Animation.Velocity.y += (item->Animation.Velocity.y >= 128.0f) ? 1.0f : GRAVITY; - item->Animation.Velocity.z += (animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount; + item->Animation.Velocity.z += animAccel.z; item->Pose.Position.y += item->Animation.Velocity.y; } @@ -273,25 +276,23 @@ void AnimateItem(ItemInfo* item) { if (item->IsLara()) { - const auto& player = *GetLaraInfo(item); + const auto& player = GetLaraInfo(*item); - if (player.Control.WaterStatus == WaterStatus::Wade && TestEnvironment(ENV_FLAG_SWAMP, item)) - item->Animation.Velocity.z = (animPtr->VelocityStart.z / 2) + ((((animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount) * currentFrame) / 4); - else - item->Animation.Velocity.z = animPtr->VelocityStart.z + (((animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount) * currentFrame); + bool isInSwamp = (player.Control.WaterStatus == WaterStatus::Wade && TestEnvironment(ENV_FLAG_SWAMP, item)); + item->Animation.Velocity.z = isInSwamp ? (animVel.z / 2) : animVel.z; } else { - item->Animation.Velocity.x = animPtr->VelocityStart.x + (((animPtr->VelocityEnd.x - animPtr->VelocityStart.x) / frameCount) * currentFrame); - item->Animation.Velocity.z = animPtr->VelocityStart.z + (((animPtr->VelocityEnd.z - animPtr->VelocityStart.z) / frameCount) * currentFrame); + item->Animation.Velocity.x = animVel.x; + item->Animation.Velocity.z = animVel.z; } } if (item->IsLara()) { - const auto& player = *GetLaraInfo(item); + const auto& player = GetLaraInfo(*item); - item->Animation.Velocity.x = animPtr->VelocityStart.x + (((animPtr->VelocityEnd.x - animPtr->VelocityStart.x) / frameCount) * currentFrame); + item->Animation.Velocity.x = animVel.x; if (player.Control.Rope.Ptr != -1) DelAlignLaraToRope(item); diff --git a/TombEngine/Game/camera.cpp b/TombEngine/Game/camera.cpp index 9eb457a52..2111bd118 100644 --- a/TombEngine/Game/camera.cpp +++ b/TombEngine/Game/camera.cpp @@ -26,9 +26,9 @@ using namespace TEN::Effects::Environment; using namespace TEN::Entities::Generic; using namespace TEN::Input; -constexpr auto PARTICLE_FADE_THRESHOLD = SECTOR(14); -constexpr auto COLL_CHECK_THRESHOLD = SECTOR(4); -constexpr auto COLL_CANCEL_THRESHOLD = SECTOR(2); +constexpr auto PARTICLE_FADE_THRESHOLD = BLOCK(14); +constexpr auto COLL_CHECK_THRESHOLD = BLOCK(4); +constexpr auto COLL_CANCEL_THRESHOLD = BLOCK(2); constexpr auto COLL_DISCARD_THRESHOLD = CLICK(0.5f); constexpr auto CAMERA_RADIUS = CLICK(1); @@ -93,7 +93,7 @@ void LookAt(CAMERA_INFO* cam, short roll) float fov = TO_RAD(CurrentFOV / 1.333333f); float r = TO_RAD(roll); - float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(SECTOR(1)); + float levelFarView = g_GameFlow->GetLevel(CurrentLevel)->GetFarView() * float(BLOCK(1)); g_Renderer.UpdateCameraMatrices(cam, r, fov, levelFarView); } @@ -119,7 +119,7 @@ inline void RumbleFromBounce() void InitializeCamera() { - Camera.shift = LaraItem->Pose.Position.y - SECTOR(1); + Camera.shift = LaraItem->Pose.Position.y - BLOCK(1); LastTarget.x = LaraItem->Pose.Position.x; LastTarget.y = Camera.shift; @@ -136,7 +136,7 @@ void InitializeCamera() Camera.pos.z = LastTarget.z - 100; Camera.pos.RoomNumber = LaraItem->RoomNumber; - Camera.targetDistance = SECTOR(1.5f); + Camera.targetDistance = BLOCK(1.5f); Camera.item = NULL; Camera.numberFrames = 1; Camera.type = CameraType::Chase; @@ -218,7 +218,7 @@ void MoveCamera(GameVector* ideal, int speed) if (Camera.bounce <= 0) { int bounce = -Camera.bounce; - int bounce2 = -Camera.bounce >> 2; + int bounce2 = bounce / 2; Camera.target.x += GetRandomControl() % bounce - bounce2; Camera.target.y += GetRandomControl() % bounce - bounce2; Camera.target.z += GetRandomControl() % bounce - bounce2; @@ -243,9 +243,9 @@ void MoveCamera(GameVector* ideal, int speed) { LOSAndReturnTarget(&Camera.target, &Camera.pos, 0); - if (abs(Camera.pos.x - ideal->x) < SECTOR(0.5f) && - abs(Camera.pos.y - ideal->y) < SECTOR(0.5f) && - abs(Camera.pos.z - ideal->z) < SECTOR(0.5f)) + if (abs(Camera.pos.x - ideal->x) < BLOCK(0.5f) && + abs(Camera.pos.y - ideal->y) < BLOCK(0.5f) && + abs(Camera.pos.z - ideal->z) < BLOCK(0.5f)) { to.x = Camera.pos.x; to.y = Camera.pos.y; @@ -538,7 +538,7 @@ void ChaseCamera(ItemInfo* item) void DoThumbstickCamera() { - if (!g_Configuration.EnableThumbstickCameraControl) + if (!g_Configuration.EnableThumbstickCamera) return; if (Camera.laraNode == -1 && (Camera.target.x == OldCam.target.x && @@ -560,7 +560,7 @@ void UpdateCameraElevation() if (Camera.laraNode != -1) { auto pos = GetJointPosition(LaraItem, Camera.laraNode, Vector3i::Zero); - auto pos1 = GetJointPosition(LaraItem, Camera.laraNode, Vector3i(0, -CLICK(1), SECTOR(2))); + auto pos1 = GetJointPosition(LaraItem, Camera.laraNode, Vector3i(0, -CLICK(1), BLOCK(2))); pos = pos1 - pos; Camera.actualAngle = Camera.targetAngle + phd_atan(pos.z, pos.x); } @@ -637,7 +637,7 @@ void CombatCamera(ItemInfo* item) UpdateCameraElevation(); - Camera.targetDistance = SECTOR(1.5f); + Camera.targetDistance = BLOCK(1.5f); int distance = Camera.targetDistance * phd_cos(Camera.actualElevation); for (int i = 0; i < 5; i++) @@ -955,7 +955,7 @@ void LookCamera(ItemInfo* item) } } - auto pos2 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, -SECTOR(1))); + auto pos2 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, -BLOCK(1))); auto pos3 = GetJointPosition(item, LM_HEAD, Vector3i(0, 0, CLICK(8))); int dx = (pos2.x - pos.x) >> 3; @@ -1171,7 +1171,7 @@ void BinocularCamera(ItemInfo* item) if (!LaserSight) { if (IsClicked(In::Deselect) || - IsClicked(In::DrawWeapon) || + IsClicked(In::Draw) || IsClicked(In::Look) || IsHeld(In::Flare)) { @@ -1216,10 +1216,10 @@ void BinocularCamera(ItemInfo* item) Camera.pos.z = z; Camera.pos.RoomNumber = probe.RoomNumber; - int l = SECTOR(20.25f) * phd_cos(headXRot); + int l = BLOCK(20.25f) * phd_cos(headXRot); int tx = x + l * phd_sin(item->Pose.Orientation.y + headYRot); - int ty = y - SECTOR(20.25f) * phd_sin(headXRot); + int ty = y - BLOCK(20.25f) * phd_sin(headXRot); int tz = z + l * phd_cos(item->Pose.Orientation.y + headYRot); if (Camera.oldType == CameraType::Fixed) @@ -1289,7 +1289,10 @@ void BinocularCamera(ItemInfo* item) void ConfirmCameraTargetPos() { - auto pos = GetJointPosition(LaraItem, LM_TORSO); + auto pos = Vector3i( + LaraItem->Pose.Position.x, + LaraItem->Pose.Position.y - (LaraCollision.Setup.Height / 2), + LaraItem->Pose.Position.z); if (Camera.laraNode != -1) { @@ -1529,7 +1532,7 @@ void CalculateCamera() Camera.item = NULL; Camera.targetElevation = 0; Camera.targetAngle = 0; - Camera.targetDistance = SECTOR(1.5f); + Camera.targetDistance = BLOCK(1.5f); Camera.flags = 0; Camera.laraNode = -1; } @@ -1847,8 +1850,9 @@ void ItemsCollideCamera() if (TestBoundsCollideCamera(bounds, item->Pose, CAMERA_RADIUS)) ItemPushCamera(&bounds, &item->Pose, rad); - TEN::Renderer::g_Renderer.AddDebugBox(bounds.ToBoundingOrientedBox(item->Pose), - Vector4(1.0f, 0.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); + TEN::Renderer::g_Renderer.AddDebugBox( + bounds.ToBoundingOrientedBox(item->Pose), + Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats); } itemList.clear(); // Done @@ -1874,8 +1878,9 @@ void ItemsCollideCamera() if (TestBoundsCollideCamera(bounds, mesh->pos, CAMERA_RADIUS)) ItemPushCamera(&bounds, &mesh->pos, rad); - TEN::Renderer::g_Renderer.AddDebugBox(bounds.ToBoundingOrientedBox(mesh->pos), - Vector4(1.0f, 0.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); + TEN::Renderer::g_Renderer.AddDebugBox( + bounds.ToBoundingOrientedBox(mesh->pos), + Vector4(1.0f, 0.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats); } staticList.clear(); // Done @@ -1896,7 +1901,7 @@ void UpdateMikePos(ItemInfo* item) } else { - int phdPerspective = g_Configuration.Width / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2); + int phdPerspective = g_Configuration.ScreenWidth / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2); Camera.actualAngle = phd_atan(Camera.target.z - Camera.pos.z, Camera.target.x - Camera.pos.x); Camera.mikePos.x = Camera.pos.x + phdPerspective * phd_sin(Camera.actualAngle); diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 57354027e..d870b14cc 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -312,19 +312,18 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) auto origin = Vector3( item->Pose.Position.x + (sinHeading * (coll->Setup.Radius)), item->Pose.Position.y - (height + CLICK(1)), - item->Pose.Position.z + (cosHeading * (coll->Setup.Radius)) - ); + item->Pose.Position.z + (cosHeading * (coll->Setup.Radius))); auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(coll->Setup.ForwardAngle), 0.0f, 0.0f); auto direction = (Matrix::CreateTranslation(Vector3::UnitZ) * mxR).Translation(); - // g_Renderer.AddDebugSphere(origin, 16, Vector4::One, RENDERER_DEBUG_PAGE::DIMENSION_STATS); + // g_Renderer.AddDebugSphere(origin, 16, Vector4::One, RendererDebugPage::CollisionStats); for (auto i : g_Level.Rooms[item->RoomNumber].neighbors) { if (!g_Level.Rooms[i].Active()) continue; - short itemNumber = g_Level.Rooms[i].itemNumber; + int itemNumber = g_Level.Rooms[i].itemNumber; while (itemNumber != NO_ITEM) { auto* item2 = &g_Level.Items[itemNumber]; @@ -979,7 +978,7 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose& itemBounds.Extents = itemBounds.Extents - Vector3(BLOCK(1)); // Draw static bounds. - g_Renderer.AddDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RENDERER_DEBUG_PAGE::DIMENSION_STATS); + g_Renderer.AddDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RendererDebugPage::CollisionStats); // Calculate horizontal item collision bounds according to radius. GameBoundingBox collBox; @@ -1010,7 +1009,7 @@ bool CollideSolidBounds(ItemInfo* item, const GameBoundingBox& box, const Pose& bool prevHorIntersects = staticBounds.Intersects(prevCollBounds); // Draw item coll bounds. - g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::DIMENSION_STATS); + g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats); // Decompose static bounds into top/bottom plane vertices. Vector3 corners[8]; @@ -1990,17 +1989,19 @@ void CreatureCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll } } -void TrapCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) +void TrapCollision(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) { - auto* item = &g_Level.Items[itemNumber]; + auto& item = g_Level.Items[itemNumber]; - if (item->Status == ITEM_ACTIVE) + if (item.Status == ITEM_ACTIVE) { - if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) + if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) return; - TestCollision(item, laraItem); + TestCollision(&item, playerItem); + } + else if (item.Status != ITEM_INVISIBLE) + { + ObjectCollision(itemNumber, playerItem, coll); } - else if (item->Status != ITEM_INVISIBLE) - ObjectCollision(itemNumber, laraItem, coll); } diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index c7e93cc6b..7d74906e3 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -8,7 +8,7 @@ struct ItemInfo; struct MESH_INFO; constexpr auto MAX_COLLIDED_OBJECTS = 1024; -constexpr auto ITEM_RADIUS_YMAX = SECTOR(3); +constexpr auto ITEM_RADIUS_YMAX = BLOCK(3); constexpr auto VEHICLE_COLLISION_TERMINAL_VELOCITY = 30.0f; diff --git a/TombEngine/Game/collision/collide_room.cpp b/TombEngine/Game/collision/collide_room.cpp index 39befcdf5..48b40a662 100644 --- a/TombEngine/Game/collision/collide_room.cpp +++ b/TombEngine/Game/collision/collide_room.cpp @@ -74,13 +74,13 @@ void SnapItemToGrid(ItemInfo* item, CollisionInfo* coll) int FindGridShift(int x, int z) { - if ((x / SECTOR(1)) == (z / SECTOR(1))) + if ((x / BLOCK(1)) == (z / BLOCK(1))) return 0; - if ((z / SECTOR(1)) <= (x / SECTOR(1))) + if ((z / BLOCK(1)) <= (x / BLOCK(1))) return (-1 - (x & WALL_MASK)); else - return ((SECTOR(1) + 1) - (x & WALL_MASK)); + return ((BLOCK(1) + 1) - (x & WALL_MASK)); } // Test if the axis-aligned bounding box collides with geometry at all. @@ -114,18 +114,24 @@ bool TestItemRoomCollisionAABB(ItemInfo* item) return collided; } -// Overload used to quickly get point/room collision parameters at a given item's position. -CollisionResult GetCollision(ItemInfo* item) +// Overload used to quickly get point collision parameters at a given item's position. +CollisionResult GetCollision(const ItemInfo& item) { - auto newRoomNumber = item->RoomNumber; - auto floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &newRoomNumber); - auto probe = GetCollision(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); + auto newRoomNumber = item.RoomNumber; + auto floor = GetFloor(item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z, &newRoomNumber); + auto probe = GetCollision(floor, item.Pose.Position.x, item.Pose.Position.y, item.Pose.Position.z); probe.RoomNumber = newRoomNumber; return probe; } -// Overload used to probe point/room collision parameters from a given item's position. +// Deprecated. +CollisionResult GetCollision(ItemInfo* item) +{ + return GetCollision(*item); +} + +// Overload used to probe point collision parameters from a given item's position. CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down, float right) { short tempRoomNumber = item->RoomNumber; @@ -140,8 +146,8 @@ CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, return GetCollision(point.x, point.y, point.z, adjacentRoomNumber); } -// Overload used to probe point/room collision parameters from a given position. -CollisionResult GetCollision(Vector3i pos, int roomNumber, short headingAngle, float forward, float down, float right) +// Overload used to probe point collision parameters from a given position. +CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down, float right) { short tempRoomNumber = roomNumber; auto location = ROOM_VECTOR{ GetFloor(pos.x, pos.y, pos.z, &tempRoomNumber)->Room, pos.y }; @@ -151,11 +157,17 @@ CollisionResult GetCollision(Vector3i pos, int roomNumber, short headingAngle, f return GetCollision(point.x, point.y, point.z, adjacentRoomNumber); } -// Overload used as a universal wrapper across collisional code to replace -// triads of roomNumber-GetFloor()-GetFloorHeight() operations. -// The advantage is that it does NOT modify the incoming roomNumber argument, -// instead storing one modified by GetFloor() within the returned CollisionResult struct. +// Overload used as universal wrapper across collisional code replacing +// triads of roomNumber-GetFloor()-GetFloorHeight() calls. +// Advantage is that it does NOT modify incoming roomNumber argument, +// instead storing one modified by GetFloor() within a returned CollisionResult struct. // This way, no external variables are modified as output arguments. +CollisionResult GetCollision(const Vector3i& pos, int roomNumber) +{ + return GetCollision(pos.x, pos.y, pos.z, roomNumber); +} + +// Deprecated. CollisionResult GetCollision(int x, int y, int z, short roomNumber) { auto room = roomNumber; @@ -166,9 +178,10 @@ CollisionResult GetCollision(int x, int y, int z, short roomNumber) return result; } -CollisionResult GetCollision(const GameVector& point) +// NOTE: To be used only when absolutely necessary. +CollisionResult GetCollision(const GameVector& pos) { - return GetCollision(point.x, point.y, point.z, point.RoomNumber); + return GetCollision(pos.x, pos.y, pos.z, pos.RoomNumber); } // A reworked legacy GetFloorHeight() function which writes data @@ -218,10 +231,52 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, bool resetRoom) GetCollisionInfo(coll, item, Vector3i::Zero, resetRoom); } -void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom) +static void SetSectorAttribs(CollisionPosition& sectorAttribs, const CollisionSetup& collSetup, const CollisionResult& pointColl, + const Vector3i& probePos, int realRoomNumber) { constexpr auto ASPECT_ANGLE_DELTA_MAX = ANGLE(90.0f); + auto floorNormal = GetSurfaceNormal(pointColl.FloorTilt, true); + short aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal); + short aspectAngleDelta = Geometry::GetShortestAngle(collSetup.ForwardAngle, aspectAngle); + + if (collSetup.BlockFloorSlopeUp && + sectorAttribs.FloorSlope && + sectorAttribs.Floor <= STEPUP_HEIGHT && + sectorAttribs.Floor >= -STEPUP_HEIGHT && + abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX) + { + sectorAttribs.Floor = MAX_HEIGHT; + } + else if (collSetup.BlockFloorSlopeDown && + sectorAttribs.FloorSlope && + sectorAttribs.Floor <= STEPUP_HEIGHT && + sectorAttribs.Floor >= -STEPUP_HEIGHT && + abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX) + { + sectorAttribs.Floor = MAX_HEIGHT; + } + else if (collSetup.BlockCeilingSlope && + sectorAttribs.CeilingSlope) + { + sectorAttribs.Floor = MAX_HEIGHT; + } + else if (collSetup.BlockDeathFloorDown && + sectorAttribs.Floor >= CLICK(0.5f) && + pointColl.BottomBlock->Flags.Death) + { + sectorAttribs.Floor = MAX_HEIGHT; + } + else if (collSetup.BlockMonkeySwingEdge) + { + auto monkeyPointColl = GetCollision(probePos.x, probePos.y + collSetup.Height, probePos.z, realRoomNumber); + if (!monkeyPointColl.BottomBlock->Flags.Monkeyswing) + sectorAttribs.Floor = MAX_HEIGHT; + } +} + +void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom) +{ // Player collision has several more precise checks for bridge collisions. // Therefore, we should differentiate these code paths. bool doPlayerCollision = item->IsLara(); @@ -357,7 +412,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse probePos.x = entityPos.x + xFront; probePos.z = entityPos.z + zFront; - g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(1, 0, 0, 1), RendererDebugPage::CollisionStats); collResult = GetCollision(probePos.x, probePos.y, probePos.z, topRoomNumber); @@ -405,46 +460,14 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse if (height != NO_HEIGHT) height -= (doPlayerCollision ? entityPos.y : probePos.y); - auto floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); - short aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal); - short aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle); - - if (coll->Setup.BlockFloorSlopeUp && - coll->Front.FloorSlope && - abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX) - { - coll->Front.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockFloorSlopeDown && - coll->Front.FloorSlope && - abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX) - { - coll->Front.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockCeilingSlope && - coll->Front.CeilingSlope) - { - coll->Front.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockDeathFloorDown && - coll->Front.Floor >= CLICK(0.5f) && - collResult.BottomBlock->Flags.Death) - { - coll->Front.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockMonkeySwingEdge) - { - auto monkeyProbe = GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, realRoomNumber); - if (!monkeyProbe.BottomBlock->Flags.Monkeyswing) - coll->Front.Floor = MAX_HEIGHT; - } + SetSectorAttribs(coll->Front, coll->Setup, collResult, probePos, realRoomNumber); // TEST 4: MIDDLE-LEFT PROBE probePos.x = entityPos.x + xLeft; probePos.z = entityPos.z + zLeft; - g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 0, 1, 1), RendererDebugPage::CollisionStats); collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber); @@ -472,38 +495,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse coll->MiddleLeft.Floor = height; coll->MiddleLeft.Ceiling = ceiling; - floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); - aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal); - aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle); - - if (coll->Setup.BlockFloorSlopeUp && - coll->MiddleLeft.FloorSlope && - abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX) - { - coll->MiddleLeft.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockFloorSlopeDown && - coll->MiddleLeft.FloorSlope && - abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX) - { - coll->MiddleLeft.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockCeilingSlope && - coll->MiddleLeft.CeilingSlope) - { - coll->MiddleLeft.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockDeathFloorDown && - coll->MiddleLeft.Floor >= CLICK(0.5f) && - collResult.BottomBlock->Flags.Death) - { - coll->MiddleLeft.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockMonkeySwingEdge && - !GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing) - { - coll->MiddleLeft.Floor = MAX_HEIGHT; - } + SetSectorAttribs(coll->MiddleLeft, coll->Setup, collResult, probePos, realRoomNumber); // TEST 5: FRONT-LEFT PROBE @@ -533,45 +525,14 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse coll->FrontLeft.Floor = height; coll->FrontLeft.Ceiling = ceiling; - floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); - aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal); - aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle); - - if (coll->Setup.BlockFloorSlopeUp && - coll->FrontLeft.FloorSlope && - abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX) - { - coll->FrontLeft.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockFloorSlopeDown && - coll->FrontLeft.FloorSlope && - abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX) - { - coll->FrontLeft.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockCeilingSlope && - coll->FrontLeft.CeilingSlope) - { - coll->FrontLeft.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockDeathFloorDown && - coll->FrontLeft.Floor >= CLICK(0.5f) && - collResult.BottomBlock->Flags.Death) - { - coll->FrontLeft.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockMonkeySwingEdge && - !GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing) - { - coll->FrontLeft.Floor = MAX_HEIGHT; - } + SetSectorAttribs(coll->FrontLeft, coll->Setup, collResult, probePos, realRoomNumber); // TEST 6: MIDDLE-RIGHT PROBE probePos.x = entityPos.x + xRight; probePos.z = entityPos.z + zRight; - g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + g_Renderer.AddDebugSphere(probePos.ToVector3(), 32, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats); collResult = GetCollision(probePos.x, probePos.y, probePos.z, item->RoomNumber); @@ -599,38 +560,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse coll->MiddleRight.Floor = height; coll->MiddleRight.Ceiling = ceiling; - floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); - aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal); - aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle); - - if (coll->Setup.BlockFloorSlopeUp && - coll->MiddleRight.FloorSlope && - abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX) - { - coll->MiddleRight.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockFloorSlopeDown && - coll->MiddleRight.FloorSlope && - abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX) - { - coll->MiddleRight.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockCeilingSlope && - coll->MiddleRight.CeilingSlope) - { - coll->MiddleRight.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockDeathFloorDown && - coll->MiddleRight.Floor >= CLICK(0.5f) && - collResult.BottomBlock->Flags.Death) - { - coll->MiddleRight.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockMonkeySwingEdge && - !GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing) - { - coll->MiddleRight.Floor = MAX_HEIGHT; - } + SetSectorAttribs(coll->MiddleRight, coll->Setup, collResult, probePos, realRoomNumber); // TEST 7: FRONT-RIGHT PROBE @@ -660,38 +590,7 @@ void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offse coll->FrontRight.Floor = height; coll->FrontRight.Ceiling = ceiling; - floorNormal = GetSurfaceNormal(collResult.FloorTilt, true); - aspectAngle = Geometry::GetSurfaceAspectAngle(floorNormal); - aspectAngleDelta = Geometry::GetShortestAngle(coll->Setup.ForwardAngle, aspectAngle); - - if (coll->Setup.BlockFloorSlopeUp && - coll->FrontRight.FloorSlope && - abs(aspectAngleDelta) >= ASPECT_ANGLE_DELTA_MAX) - { - coll->FrontRight.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockFloorSlopeDown && - coll->FrontRight.FloorSlope && - abs(aspectAngleDelta) <= ASPECT_ANGLE_DELTA_MAX) - { - coll->FrontRight.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockCeilingSlope && - coll->FrontRight.CeilingSlope) - { - coll->FrontRight.Floor = MAX_HEIGHT; - } - else if (coll->Setup.BlockDeathFloorDown && - coll->FrontRight.Floor >= CLICK(0.5f) && - collResult.BottomBlock->Flags.Death) - { - coll->FrontRight.Floor = STOP_SIZE; - } - else if (coll->Setup.BlockMonkeySwingEdge && - !GetCollision(probePos.x, probePos.y + coll->Setup.Height, probePos.z, item->RoomNumber).BottomBlock->Flags.Monkeyswing) - { - coll->FrontRight.Floor = MAX_HEIGHT; - } + SetSectorAttribs(coll->FrontRight, coll->Setup, collResult, probePos, realRoomNumber); // TEST 8: SOLID STATIC MESHES @@ -979,7 +878,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance) } // Debug probe point - // g_Renderer.AddDebugSphere(Vector3(eX, y, eZ), 16, Vector4(1, 1, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + // g_Renderer.AddDebugSphere(Vector3(eX, y, eZ), 16, Vector4(1, 1, 0, 1), RendererDebugPage::CollisionStats); // Determine front floor probe offset. // It is needed to identify if there is bridge or ceiling split in front. @@ -1021,7 +920,7 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance) auto fpZ = eZ + floorProbeOffset * cosForwardAngle; // Debug probe point. - // g_Renderer.AddDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + // g_Renderer.AddDebugSphere(Vector3(fpX, y, fpZ), 16, Vector4(0, 1, 0, 1), RendererDebugPage::CollisionStats); // Get true room number and block, based on derived height room = GetRoom(item->Location, fpX, height, fpZ).roomNumber; @@ -1086,17 +985,17 @@ short GetNearestLedgeAngle(ItemInfo* item, CollisionInfo* coll, float& distance) auto splitAngle = (useCeilingLedge ? block->CeilingCollision.SplitAngle : block->FloorCollision.SplitAngle); // Get horizontal block corner coordinates. - auto fX = floor(eX / SECTOR(1)) * SECTOR(1) - 1; - auto fZ = floor(eZ / SECTOR(1)) * SECTOR(1) - 1; - auto cX = fX + SECTOR(1) + 1; - auto cZ = fZ + SECTOR(1) + 1; + auto fX = floor(eX / BLOCK(1)) * BLOCK(1) - 1; + auto fZ = floor(eZ / BLOCK(1)) * BLOCK(1) - 1; + auto cX = fX + BLOCK(1) + 1; + auto cZ = fZ + BLOCK(1) + 1; // Debug used block - // g_Renderer.AddDebugSphere(Vector3(round(eX / WALL_SIZE) * WALL_SIZE + 512, y, round(eZ / WALL_SIZE) * WALL_SIZE + 512), 16, Vector4(1, 1, 1, 1), RENDERER_DEBUG_PAGE::LARA_STATS); + // g_Renderer.AddDebugSphere(Vector3(round(eX / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f), y, round(eZ / BLOCK(1)) * BLOCK(1) + BLOCK(0.5f)), 16, Vector4::One, RendererDebugPage::CollisionStats); // Get split angle coordinates. - auto sX = fX + 1 + SECTOR(0.5f); - auto sZ = fZ + 1 + SECTOR(0.5f); + auto sX = fX + 1 + BLOCK(0.5f); + auto sZ = fZ + 1 + BLOCK(0.5f); auto sShiftX = coll->Setup.Radius * sin(splitAngle); auto sShiftZ = coll->Setup.Radius * cos(splitAngle); @@ -1267,7 +1166,7 @@ void AlterFloorHeight(ItemInfo* item, int height) short roomNumber = item->RoomNumber; FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); - FloorInfo* ceiling = GetFloor(item->Pose.Position.x, height + item->Pose.Position.y - SECTOR(1), item->Pose.Position.z, &roomNumber); + FloorInfo* ceiling = GetFloor(item->Pose.Position.x, height + item->Pose.Position.y - BLOCK(1), item->Pose.Position.z, &roomNumber); floor->FloorCollision.Planes[0].z += height; floor->FloorCollision.Planes[1].z += height; @@ -1328,8 +1227,8 @@ int GetWaterDepth(int x, int y, int z, short roomNumber) short roomIndex = NO_ROOM; do { - int zFloor = (z - room->z) / SECTOR(1); - int xFloor = (x - room->x) / SECTOR(1); + int zFloor = (z - room->z) / BLOCK(1); + int xFloor = (x - room->x) / BLOCK(1); if (zFloor <= 0) { @@ -1416,8 +1315,8 @@ int GetWaterHeight(int x, int y, int z, short roomNumber) short adjoiningRoom = NO_ROOM; do { - int xBlock = (x - room->x) / SECTOR(1); - int zBlock = (z - room->z) / SECTOR(1); + int xBlock = (x - room->x) / BLOCK(1); + int zBlock = (z - room->z) / BLOCK(1); if (zBlock <= 0) { diff --git a/TombEngine/Game/collision/collide_room.h b/TombEngine/Game/collision/collide_room.h index 62087bd2a..49a6d350f 100644 --- a/TombEngine/Game/collision/collide_room.h +++ b/TombEngine/Game/collision/collide_room.h @@ -11,7 +11,7 @@ enum RoomEnvFlags; constexpr auto NO_LOWER_BOUND = -NO_HEIGHT; // Used by coll->Setup.LowerFloorBound. constexpr auto NO_UPPER_BOUND = NO_HEIGHT; // Used by coll->Setup.UpperFloorBound. -constexpr auto COLLISION_CHECK_DISTANCE = SECTOR(8); +constexpr auto COLLISION_CHECK_DISTANCE = BLOCK(8); enum CollisionType { @@ -126,11 +126,13 @@ struct CollisionInfo [[nodiscard]] bool TestItemRoomCollisionAABB(ItemInfo* item); +CollisionResult GetCollision(const ItemInfo& item); CollisionResult GetCollision(ItemInfo* item); CollisionResult GetCollision(ItemInfo* item, short headingAngle, float forward, float down = 0.0f, float right = 0.0f); -CollisionResult GetCollision(Vector3i pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f); +CollisionResult GetCollision(const Vector3i& pos, int roomNumber, short headingAngle, float forward, float down = 0.0f, float right = 0.0f); +CollisionResult GetCollision(const Vector3i& pos, int roomNumber); CollisionResult GetCollision(int x, int y, int z, short roomNumber); -CollisionResult GetCollision(const GameVector& point); +CollisionResult GetCollision(const GameVector& pos); CollisionResult GetCollision(FloorInfo* floor, int x, int y, int z); void GetCollisionInfo(CollisionInfo* coll, ItemInfo* item, const Vector3i& offset, bool resetRoom = false); diff --git a/TombEngine/Game/collision/floordata.cpp b/TombEngine/Game/collision/floordata.cpp index 86b6c2ea1..9d26cda94 100644 --- a/TombEngine/Game/collision/floordata.cpp +++ b/TombEngine/Game/collision/floordata.cpp @@ -1,10 +1,12 @@ #include "framework.h" #include "Game/collision/floordata.h" +#include "Game/collision/collide_room.h" #include "Game/items.h" #include "Game/room.h" #include "Game/Setup.h" #include "Math/Math.h" +#include "Renderer/Renderer11.h" #include "Specific/level.h" using namespace TEN::Collision::Floordata; @@ -750,6 +752,10 @@ namespace TEN::Collision::Floordata void AddBridge(int itemNumber, int x, int z) { const auto& item = g_Level.Items[itemNumber]; + + if (!Objects.CheckID(item.ObjectNumber)) + return; + x += item.Pose.Position.x; z += item.Pose.Position.z; @@ -788,6 +794,10 @@ namespace TEN::Collision::Floordata void RemoveBridge(int itemNumber, int x, int z) { const auto& item = g_Level.Items[itemNumber]; + + if (!Objects.CheckID(item.ObjectNumber)) + return; + x += item.Pose.Position.x; z += item.Pose.Position.z; @@ -862,7 +872,12 @@ namespace TEN::Collision::Floordata void UpdateBridgeItem(int itemNumber, bool forceRemoval) { auto item = &g_Level.Items[itemNumber]; - if (!Objects[item->ObjectNumber].loaded) return; + + if (!Objects.CheckID(item->ObjectNumber)) + return; + + if (!Objects[item->ObjectNumber].loaded) + return; // Force removal if object was killed if (item->Flags & IFLAG_KILLED) @@ -924,4 +939,103 @@ namespace TEN::Collision::Floordata return false; } + + static void DrawSectorFlagLabel(const Vector3& pos, const std::string& string, const Vector4& color, float verticalOffset) + { + constexpr auto LABEL_SCALE = 0.8f; + constexpr auto HALF_BLOCK = BLOCK(0.5f); + + // Get 2D label position. + auto labelPos = pos + Vector3(HALF_BLOCK, 0.0f, HALF_BLOCK); + auto labelPos2D = g_Renderer.Get2DPosition(labelPos); + + // Draw label. + if (labelPos2D.has_value()) + { + *labelPos2D += Vector2(0.0f, verticalOffset); + g_Renderer.AddDebugString(string, *labelPos2D, color, LABEL_SCALE, 0, RendererDebugPage::CollisionStats); + } + } + + void DrawNearbySectorFlags(const ItemInfo& item) + { + constexpr auto DRAW_RANGE = BLOCK(3); + constexpr auto STRING_SPACING = -20.0f; + + constexpr auto STOPPER_COLOR = Vector4(1.0f, 0.4f, 0.4f, 1.0f); + constexpr auto DEATH_COLOR = Vector4(0.4f, 1.0f, 0.4f, 1.0f); + constexpr auto MONKEY_SWING_COLOR = Vector4(1.0f, 0.4f, 0.4f, 1.0f); + constexpr auto BEETLE_MINECART_RIGHT_COLOR = Vector4(0.4f, 0.4f, 1.0f, 1.0f); + constexpr auto ACTIVATOR_MINECART_LEFT_COLOR = Vector4(1.0f, 0.4f, 1.0f, 1.0f); + constexpr auto MINECART_STOP_COLOR = Vector4(0.4f, 1.0f, 1.0f, 1.0f); + + // Only check sectors in player vicinity. + const auto& room = g_Level.Rooms[item.RoomNumber]; + int minX = std::max(item.Pose.Position.x - DRAW_RANGE, room.x) / BLOCK(1); + int maxX = std::min(item.Pose.Position.x + DRAW_RANGE, room.x + (room.xSize * BLOCK(1))) / BLOCK(1); + int minZ = std::max(item.Pose.Position.z - DRAW_RANGE, room.z) / BLOCK(1); + int maxZ = std::min(item.Pose.Position.z + DRAW_RANGE, room.z + (room.zSize * BLOCK(1))) / BLOCK(1); + + auto pointColl = GetCollision(item); + auto pos = item.Pose.Position.ToVector3(); + + // Draw sector flag labels. + for (int x = minX; x < maxX; x++) + { + for (int z = minZ; z < maxZ; z++) + { + pos.x = BLOCK(x); + pos.z = BLOCK(z); + + pointColl = GetCollision(pos, item.RoomNumber); + pos.y = pointColl.Position.Floor; + + float verticalOffset = STRING_SPACING; + + // Stopper + if (pointColl.Block->Stopper) + { + DrawSectorFlagLabel(pos, "Stopper", STOPPER_COLOR, verticalOffset); + verticalOffset += STRING_SPACING; + } + + // Death + if (pointColl.Block->Flags.Death) + { + DrawSectorFlagLabel(pos, "Death", DEATH_COLOR, verticalOffset); + verticalOffset += STRING_SPACING; + } + + // Monkey Swing + if (pointColl.Block->Flags.Monkeyswing) + { + DrawSectorFlagLabel(pos, "Monkey Swing", MONKEY_SWING_COLOR, verticalOffset); + verticalOffset += STRING_SPACING; + } + + // Beetle / Minecart Right + if (pointColl.Block->Flags.MarkBeetle) + { + auto labelString = std::string("Beetle") + (!pointColl.Block->Flags.MinecartStop() ? " / Minecart Right" : ""); + DrawSectorFlagLabel(pos, labelString, BEETLE_MINECART_RIGHT_COLOR, verticalOffset); + verticalOffset += STRING_SPACING; + } + + // Activator / Minecart Left + if (pointColl.Block->Flags.MarkTriggerer) + { + auto labelString = std::string("Activator") + (!pointColl.Block->Flags.MinecartStop() ? " / Minecart Left" : ""); + DrawSectorFlagLabel(pos, labelString, ACTIVATOR_MINECART_LEFT_COLOR, verticalOffset); + verticalOffset += STRING_SPACING; + } + + // Minecart Stop + if (pointColl.Block->Flags.MinecartStop()) + { + DrawSectorFlagLabel(pos, "Minecart Stop", MINECART_STOP_COLOR, verticalOffset); + verticalOffset += STRING_SPACING; + } + } + } + } } diff --git a/TombEngine/Game/collision/floordata.h b/TombEngine/Game/collision/floordata.h index 59cc4be66..0692dbaaf 100644 --- a/TombEngine/Game/collision/floordata.h +++ b/TombEngine/Game/collision/floordata.h @@ -189,4 +189,6 @@ namespace TEN::Collision::Floordata void UpdateBridgeItem(int itemNumber, bool forceRemoval = false); bool TestMaterial(MaterialType refMaterial, const std::vector& materialList); + + void DrawNearbySectorFlags(const ItemInfo& item); } diff --git a/TombEngine/Game/collision/sphere.cpp b/TombEngine/Game/collision/sphere.cpp index 0c4026b2f..6db6de0d4 100644 --- a/TombEngine/Game/collision/sphere.cpp +++ b/TombEngine/Game/collision/sphere.cpp @@ -19,9 +19,7 @@ int GetSpheres(ItemInfo* item, SPHERE* ptr, int worldSpace, Matrix local) return 0; BoundingSphere spheres[MAX_SPHERES]; - short itemNumber = (item - g_Level.Items.data()); - - int num = g_Renderer.GetSpheres(itemNumber, spheres, worldSpace, local); + int num = g_Renderer.GetSpheres(item->Index, spheres, worldSpace, local); for (int i = 0; i < MAX_SPHERES; i++) { diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index c58e0f070..37b44690d 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -24,10 +24,10 @@ using namespace TEN::Effects::Smoke; -constexpr auto ESCAPE_DIST = SECTOR(5); -constexpr auto STALK_DIST = SECTOR(3); +constexpr auto ESCAPE_DIST = BLOCK(5); +constexpr auto STALK_DIST = BLOCK(3); constexpr auto REACHED_GOAL_RADIUS = 640; -constexpr auto ATTACK_RANGE = SQUARE(SECTOR(3)); +constexpr auto ATTACK_RANGE = SQUARE(BLOCK(3)); constexpr auto ESCAPE_CHANCE = 0x800; constexpr auto RECOVER_CHANCE = 0x100; constexpr auto BIFF_AVOID_TURN = ANGLE(11.25f); @@ -59,14 +59,14 @@ void DrawBox(int boxIndex, Vector3 color) float z = ((float)currBox.top + (float)(currBox.bottom - currBox.top) / 2.0f) * 1024.0f; auto center = Vector3(z, y, x); - auto corner = Vector3(currBox.bottom * SECTOR(1), currBox.height + CLICK(1), currBox.right * SECTOR(1)); + auto corner = Vector3(currBox.bottom * BLOCK(1), currBox.height + CLICK(1), currBox.right * BLOCK(1)); auto extents = (corner - center) * 0.9f; auto dBox = BoundingOrientedBox(center, extents, Vector4::UnitY); for (int i = 0; i <= 10; i++) { dBox.Extents = extents + Vector3(i); - TEN::Renderer::g_Renderer.AddDebugBox(dBox, Vector4(color.x, color.y, color.z, 1), RENDERER_DEBUG_PAGE::LOGIC_STATS); + TEN::Renderer::g_Renderer.AddDebugBox(dBox, Vector4(color.x, color.y, color.z, 1), RendererDebugPage::PathfindingStats); } } @@ -75,11 +75,16 @@ void DrawNearbyPathfinding(int boxIndex) if (boxIndex == NO_BOX) return; - DrawBox(boxIndex, Vector3(0, 1, 1)); - auto& currBox = g_Level.Boxes[boxIndex]; auto index = currBox.overlapIndex; + // Grey flag box. + auto currentBoxColor = Vector3(0.0f, 1.0f, 1.0f); + if (currBox.flags & BLOCKABLE) + currentBoxColor = (currBox.flags & BLOCKED) ? Vector3(1.0f, 0.0f, 0.0f) : Vector3(0.0f, 1.0f, 0.0f); + + DrawBox(boxIndex, currentBoxColor); + while (true) { if (index >= g_Level.Overlaps.size()) @@ -287,10 +292,10 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt) boxHeight - height > LOT->Step || boxHeight - height < LOT->Drop)) { - xPos = item->Pose.Position.x / SECTOR(1); - zPos = item->Pose.Position.z / SECTOR(1); - shiftX = prevPos.x / SECTOR(1); - shiftZ = prevPos.z / SECTOR(1); + xPos = item->Pose.Position.x / BLOCK(1); + zPos = item->Pose.Position.z / BLOCK(1); + shiftX = prevPos.x / BLOCK(1); + shiftZ = prevPos.z / BLOCK(1); if (xPos < shiftX) item->Pose.Position.x = prevPos.x & (~WALL_MASK); @@ -346,23 +351,23 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt) shiftX = radius - xPos; } } - else if (xPos > SECTOR(1) - radius) + else if (xPos > BLOCK(1) - radius) { if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT)) - shiftX = SECTOR(1) - radius - xPos; + shiftX = BLOCK(1) - radius - xPos; else if (!shiftZ && BadFloor(x + radius, y, z - radius, height, nextHeight, roomNumber, LOT)) { if (item->Pose.Orientation.y > -ANGLE(45.0f) && item->Pose.Orientation.y < ANGLE(135.0f)) shiftZ = radius - zPos; else - shiftX = SECTOR(1) - radius - xPos; + shiftX = BLOCK(1) - radius - xPos; } } } - else if (zPos > SECTOR(1) - radius) + else if (zPos > BLOCK(1) - radius) { if (BadFloor(x, y, z + radius, height, nextHeight, roomNumber, LOT)) - shiftZ = SECTOR(1) - radius - zPos; + shiftZ = BLOCK(1) - radius - zPos; if (xPos < radius) { @@ -373,19 +378,19 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt) if (item->Pose.Orientation.y > -ANGLE(45.0f) && item->Pose.Orientation.y < ANGLE(135.0f)) shiftX = radius - xPos; else - shiftZ = SECTOR(1) - radius - zPos; + shiftZ = BLOCK(1) - radius - zPos; } } - else if (xPos > SECTOR(1) - radius) + else if (xPos > BLOCK(1) - radius) { if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT)) - shiftX = SECTOR(1) - radius - xPos; + shiftX = BLOCK(1) - radius - xPos; else if (!shiftZ && BadFloor(x + radius, y, z + radius, height, nextHeight, roomNumber, LOT)) { if (item->Pose.Orientation.y > -ANGLE(135.0f) && item->Pose.Orientation.y < ANGLE(45.0f)) - shiftX = SECTOR(1) - radius - xPos; + shiftX = BLOCK(1) - radius - xPos; else - shiftZ = SECTOR(1) - radius - zPos; + shiftZ = BLOCK(1) - radius - zPos; } } } @@ -394,10 +399,10 @@ bool CreaturePathfind(ItemInfo* item, Vector3i prevPos, short angle, short tilt) if (BadFloor(x - radius, y, z, height, nextHeight, roomNumber, LOT)) shiftX = radius - xPos; } - else if (xPos > SECTOR(1) - radius) + else if (xPos > BLOCK(1) - radius) { if (BadFloor(x + radius, y, z, height, nextHeight, roomNumber, LOT)) - shiftX = SECTOR(1) - radius - xPos; + shiftX = BLOCK(1) - radius - xPos; } item->Pose.Position.x += shiftX; @@ -566,7 +571,7 @@ void CreatureKill(ItemInfo* creatureItem, int creatureAnimNumber, int playerAnim playerItem.Animation.Velocity = Vector3::Zero; if (creatureItem->RoomNumber != playerItem.RoomNumber) - ItemNewRoom(player.ItemNumber, creatureItem->RoomNumber); + ItemNewRoom(playerItem.Index, creatureItem->RoomNumber); AnimateItem(&playerItem); @@ -788,39 +793,53 @@ void CreatureHealth(ItemInfo* item) } } -void CreatureDie(short itemNumber, bool explode) +void CreatureDie(int itemNumber, bool doExplosion) { - auto* item = &g_Level.Items[itemNumber]; - auto* object = &Objects[item->ObjectNumber]; - - item->HitPoints = NOT_TARGETABLE; - item->Collidable = false; - - if (explode) + int flags = 0; + if (doExplosion) { - switch (object->hitEffect) + const auto& item = g_Level.Items[itemNumber]; + const auto& object = Objects[item.ObjectNumber]; + + switch (object.hitEffect) { case HitEffect::Blood: - ExplodingDeath(itemNumber, BODY_EXPLODE | BODY_GIBS); + flags |= BODY_DO_EXPLOSION | BODY_GIBS; break; case HitEffect::Smoke: - ExplodingDeath(itemNumber, BODY_EXPLODE | BODY_NO_BOUNCE); + flags |= BODY_DO_EXPLOSION | BODY_NO_BOUNCE; break; default: - ExplodingDeath(itemNumber, BODY_EXPLODE); + flags |= BODY_DO_EXPLOSION; break; } + } + CreatureDie(itemNumber, doExplosion, flags); +} + +void CreatureDie(int itemNumber, bool doExplosion, int flags) +{ + auto& item = g_Level.Items[itemNumber]; + + item.HitPoints = NOT_TARGETABLE; + item.Collidable = false; + + if (doExplosion) + { + ExplodingDeath(itemNumber, flags); KillItem(itemNumber); } else + { RemoveActiveItem(itemNumber); + } DisableEntityAI(itemNumber); - item->Flags |= IFLAG_KILLED | IFLAG_INVISIBLE; - DropPickups(item); + item.Flags |= IFLAG_KILLED | IFLAG_INVISIBLE; + DropPickups(&item); } bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT) @@ -938,8 +957,8 @@ void TargetBox(LOTInfo* LOT, int boxNumber) auto* box = &g_Level.Boxes[boxNumber]; // Maximize target precision. DO NOT change bracket precedence! - LOT->Target.x = (int)((box->top * SECTOR(1)) + (float)GetRandomControl() * (((float)(box->bottom - box->top) - 1.0f) / 32.0f) + CLICK(2.0f)); - LOT->Target.z = (int)((box->left * SECTOR(1)) + (float)GetRandomControl() * (((float)(box->right - box->left) - 1.0f) / 32.0f) + CLICK(2.0f)); + LOT->Target.x = (int)((box->top * BLOCK(1)) + (float)GetRandomControl() * (((float)(box->bottom - box->top) - 1.0f) / 32.0f) + CLICK(2.0f)); + LOT->Target.z = (int)((box->left * BLOCK(1)) + (float)GetRandomControl() * (((float)(box->right - box->left) - 1.0f) / 32.0f) + CLICK(2.0f)); LOT->RequiredBox = boxNumber; if (LOT->Fly == NO_FLYING) @@ -1116,10 +1135,10 @@ bool StalkBox(ItemInfo* item, ItemInfo* enemy, int boxNumber) return false; auto* box = &g_Level.Boxes[boxNumber]; - int xRange = STALK_DIST + ((box->bottom - box->top) * SECTOR(1)); - int zRange = STALK_DIST + ((box->right - box->left) * SECTOR(1)); - int x = (box->top + box->bottom) * SECTOR(1) / 2 - enemy->Pose.Position.x; - int z = (box->left + box->right) * SECTOR(1) / 2 - enemy->Pose.Position.z; + int xRange = STALK_DIST + ((box->bottom - box->top) * BLOCK(1)); + int zRange = STALK_DIST + ((box->right - box->left) * BLOCK(1)); + int x = (box->top + box->bottom) * BLOCK(1) / 2 - enemy->Pose.Position.x; + int z = (box->left + box->right) * BLOCK(1) / 2 - enemy->Pose.Position.z; if (x > xRange || x < -xRange || z > zRange || z < -zRange) return false; @@ -1183,8 +1202,8 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift) auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - int xBlock = item->Pose.Position.x / SECTOR(1); - int zBlock = item->Pose.Position.z / SECTOR(1); + int xBlock = item->Pose.Position.x / BLOCK(1); + int zBlock = item->Pose.Position.z / BLOCK(1); int y = item->Pose.Position.y; short roomNumber = item->RoomNumber; @@ -1224,8 +1243,8 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift) } // Jump - int newXblock = item->Pose.Position.x / SECTOR(1); - int newZblock = item->Pose.Position.z / SECTOR(1); + int newXblock = item->Pose.Position.x / BLOCK(1); + int newZblock = item->Pose.Position.z / BLOCK(1); if (zBlock == newZblock) { @@ -1234,12 +1253,12 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift) if (xBlock < newXblock) { - item->Pose.Position.x = (newXblock * SECTOR(1)) - shift; + item->Pose.Position.x = (newXblock * BLOCK(1)) - shift; item->Pose.Orientation.y = ANGLE(90.0f); } else { - item->Pose.Position.x = (xBlock * SECTOR(1)) + shift; + item->Pose.Position.x = (xBlock * BLOCK(1)) + shift; item->Pose.Orientation.y = -ANGLE(90.0f); } } @@ -1247,12 +1266,12 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift) { if (zBlock < newZblock) { - item->Pose.Position.z = (newZblock * SECTOR(1)) - shift; + item->Pose.Position.z = (newZblock * BLOCK(1)) - shift; item->Pose.Orientation.y = 0; } else { - item->Pose.Position.z = (zBlock * SECTOR(1)) + shift; + item->Pose.Position.z = (zBlock * BLOCK(1)) + shift; item->Pose.Orientation.y = -ANGLE(180.0f); } } @@ -1550,8 +1569,8 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI) vector.y = item->Pose.Position.y - enemy->Pose.Position.y; short angle = phd_atan(vector.z, vector.x); - if (vector.x > SECTOR(31.25f) || vector.x < -SECTOR(31.25f) || - vector.z > SECTOR(31.25f) || vector.z < -SECTOR(31.25f)) + if (vector.x > BLOCK(31.25f) || vector.x < -BLOCK(31.25f) || + vector.z > BLOCK(31.25f) || vector.z < -BLOCK(31.25f)) { AI->distance = INT_MAX; AI->verticalDistance = INT_MAX; @@ -1809,7 +1828,7 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent) case MoodType::Stalk: if (creature->Alerted && AI->zoneNumber != AI->enemyZone) { - if (AI->distance > SECTOR(3)) + if (AI->distance > BLOCK(3)) creature->Mood = MoodType::Stalk; else creature->Mood = MoodType::Bored; @@ -1830,7 +1849,7 @@ void GetCreatureMood(ItemInfo* item, AI_INFO* AI, bool isViolent) (GetRandomControl() < ESCAPE_CHANCE || AI->zoneNumber != AI->enemyZone)) creature->Mood = MoodType::Stalk; - else if (AI->zoneNumber != AI->enemyZone && AI->distance > SECTOR(6)) + else if (AI->zoneNumber != AI->enemyZone && AI->distance > BLOCK(6)) creature->Mood = MoodType::Bored; break; @@ -1872,10 +1891,10 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT) auto* box = &g_Level.Boxes[boxNumber]; - int boxLeft = ((int)box->left * SECTOR(1)); - int boxRight = ((int)box->right * SECTOR(1)) - 1; - int boxTop = ((int)box->top * SECTOR(1)); - int boxBottom = ((int)box->bottom * SECTOR(1)) - 1; + int boxLeft = ((int)box->left * BLOCK(1)); + int boxRight = ((int)box->right * BLOCK(1)) - 1; + int boxTop = ((int)box->top * BLOCK(1)); + int boxBottom = ((int)box->bottom * BLOCK(1)) - 1; int left = boxLeft; int right = boxRight; int top = boxTop; @@ -1888,26 +1907,26 @@ TARGET_TYPE CalculateTarget(Vector3i* target, ItemInfo* item, LOTInfo* LOT) if (LOT->Fly != NO_FLYING) { - if (target->y > box->height - SECTOR(1)) - target->y = box->height - SECTOR(1); + if (target->y > box->height - BLOCK(1)) + target->y = box->height - BLOCK(1); } else if(target->y > box->height) target->y = box->height; - boxLeft = ((int)box->left * SECTOR(1)); - boxRight = ((int)box->right * SECTOR(1)) - 1; - boxTop = ((int)box->top * SECTOR(1)); - boxBottom = ((int)box->bottom * SECTOR(1)) - 1; + boxLeft = ((int)box->left * BLOCK(1)); + boxRight = ((int)box->right * BLOCK(1)) - 1; + boxTop = ((int)box->top * BLOCK(1)); + boxBottom = ((int)box->bottom * BLOCK(1)) - 1; if (item->Pose.Position.z >= boxLeft && item->Pose.Position.z <= boxRight && item->Pose.Position.x >= boxTop && item->Pose.Position.x <= boxBottom) { - left = ((int)box->left * SECTOR(1)); - right = ((int)box->right * SECTOR(1)) - 1; - top = ((int)box->top * SECTOR(1)); - bottom = ((int)box->bottom * SECTOR(1)) - 1; + left = ((int)box->left * BLOCK(1)); + right = ((int)box->right * BLOCK(1)) - 1; + top = ((int)box->top * BLOCK(1)); + bottom = ((int)box->bottom * BLOCK(1)) - 1; } else { @@ -2102,8 +2121,8 @@ void AdjustStopperFlag(ItemInfo* item, int direction) auto* floor = GetSector(room, x - room->x, z - room->z); floor->Stopper = !floor->Stopper; - x = item->Pose.Position.x + SECTOR(1) * phd_sin(direction); - z = item->Pose.Position.z + SECTOR(1) * phd_cos(direction); + x = item->Pose.Position.x + BLOCK(1) * phd_sin(direction); + z = item->Pose.Position.z + BLOCK(1) * phd_cos(direction); room = &g_Level.Rooms[GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).RoomNumber]; floor = GetSector(room, x - room->x, z - room->z); @@ -2124,7 +2143,7 @@ void InitializeItemBoxData() { for (const auto& mesh : room.mesh) { - long index = ((mesh.pos.Position.z - room.z) / SECTOR(1)) + room.zSize * ((mesh.pos.Position.x - room.x) / SECTOR(1)); + long index = ((mesh.pos.Position.z - room.z) / BLOCK(1)) + room.zSize * ((mesh.pos.Position.x - room.x) / BLOCK(1)); if (index > room.floor.size()) continue; diff --git a/TombEngine/Game/control/box.h b/TombEngine/Game/control/box.h index b5358eed5..98e26ca1e 100644 --- a/TombEngine/Game/control/box.h +++ b/TombEngine/Game/control/box.h @@ -98,7 +98,8 @@ void CreatureFloat(short itemNumber); void CreatureJoint(ItemInfo* item, short joint, short required, short maxAngle = ANGLE(70.0f)); void CreatureTilt(ItemInfo* item, short angle); short CreatureTurn(ItemInfo* item, short maxTurn); -void CreatureDie(short itemNumber, bool explode); +void CreatureDie(int itemNumber, bool doExplosion); +void CreatureDie(int itemNumber, bool doExplosion, int flags); bool BadFloor(int x, int y, int z, int boxHeight, int nextHeight, short roomNumber, LOTInfo* LOT); int CreatureCreature(short itemNumber); bool ValidBox(ItemInfo* item, short zoneNumber, short boxNumber); diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index 9b8d7eafe..88b337b10 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -218,7 +218,6 @@ GameStatus ControlPhase(int numFrames) UpdateSparkParticles(); UpdateSmokeParticles(); UpdateSimpleParticles(); - UpdateDrips(); UpdateExplosionParticles(); UpdateShockwaves(); UpdateBeetleSwarm(); @@ -305,16 +304,12 @@ GameStatus DoLevel(int levelIndex, bool loadGame) InitializeScripting(levelIndex, loadGame); InitializeNodeScripts(); + // Initialize menu and inventory state. + g_Gui.Initialize(); + // Initialize game variables and optionally load game. InitializeOrLoadGame(loadGame); - // Prepare title menu, if necessary. - if (isTitle) - { - g_Gui.SetMenuToDisplay(Menu::Title); - g_Gui.SetSelectedOption(0); - } - // DoGameLoop() returns only when level has ended. return DoGameLoop(levelIndex); } @@ -457,8 +452,8 @@ void InitializeScripting(int levelIndex, bool loadGame) g_GameStringsHandler->SetCallbackDrawString([](std::string const key, D3DCOLOR col, int x, int y, int flags) { g_Renderer.AddString( - float(x) / float(g_Configuration.Width) * SCREEN_SPACE_RES.x, - float(y) / float(g_Configuration.Height) * SCREEN_SPACE_RES.y, + float(x) / float(g_Configuration.ScreenWidth) * SCREEN_SPACE_RES.x, + float(y) / float(g_Configuration.ScreenHeight) * SCREEN_SPACE_RES.y, key.c_str(), col, flags); }); } @@ -638,7 +633,7 @@ GameStatus HandleMenuCalls(bool isTitle) if (g_Gui.CallPause()) result = GameStatus::ExitToTitle; } - else if ((IsClicked(In::Option) || g_Gui.GetEnterInventory() != NO_ITEM) && + else if ((IsClicked(In::Inventory) || g_Gui.GetEnterInventory() != NO_ITEM) && LaraItem->HitPoints > 0 && !BinocularOn) { if (g_Gui.CallInventory(LaraItem, true)) diff --git a/TombEngine/Game/control/flipeffect.cpp b/TombEngine/Game/control/flipeffect.cpp index 9e35c2c2f..942428891 100644 --- a/TombEngine/Game/control/flipeffect.cpp +++ b/TombEngine/Game/control/flipeffect.cpp @@ -315,11 +315,11 @@ void FloorShake(ItemInfo* item) int y = abs(item->Pose.Position.y - Camera.pos.y); int z = abs(item->Pose.Position.z - Camera.pos.z); - if (x < SECTOR(16) && - y < SECTOR(16) && - z < SECTOR(16)) + if (x < BLOCK(16) && + y < BLOCK(16) && + z < BLOCK(16)) { - Camera.bounce = 66 * ((pow(x, 2) + pow(y, 2) + pow(z, 2)) / CLICK(1) - pow(SECTOR(1), 2)) / pow(SECTOR(1), 2); + Camera.bounce = 66 * ((pow(x, 2) + pow(y, 2) + pow(z, 2)) / CLICK(1) - pow(BLOCK(1), 2)) / pow(BLOCK(1), 2); } } diff --git a/TombEngine/Game/control/los.cpp b/TombEngine/Game/control/los.cpp index 4aa840947..f334b4de8 100644 --- a/TombEngine/Game/control/los.cpp +++ b/TombEngine/Game/control/los.cpp @@ -606,7 +606,7 @@ int xLOS(GameVector* origin, GameVector* target) break; } - x -= SECTOR(1); + x -= BLOCK(1); y -= dy; z -= dz; } @@ -656,7 +656,7 @@ int xLOS(GameVector* origin, GameVector* target) break; } - x += SECTOR(1); + x += BLOCK(1); y += dy; z += dz; } @@ -726,7 +726,7 @@ int zLOS(GameVector* origin, GameVector* target) break; } - z -= SECTOR(1); + z -= BLOCK(1); x -= dx; y -= dy; } @@ -776,7 +776,7 @@ int zLOS(GameVector* origin, GameVector* target) break; } - z += SECTOR(1); + z += BLOCK(1); x += dx; y += dy; } diff --git a/TombEngine/Game/control/lot.cpp b/TombEngine/Game/control/lot.cpp index e1a6bf4ab..66e06c183 100644 --- a/TombEngine/Game/control/lot.cpp +++ b/TombEngine/Game/control/lot.cpp @@ -117,16 +117,16 @@ void InitializeSlot(short itemNumber, bool makeTarget) // Can fly. case LotType::Flyer: - creature->LOT.Step = SECTOR(20); - creature->LOT.Drop = -SECTOR(20); + creature->LOT.Step = BLOCK(20); + creature->LOT.Drop = -BLOCK(20); creature->LOT.Fly = DEFAULT_FLY_UPDOWN_SPEED; creature->LOT.Zone = ZoneType::Flyer; break; // Can swim. case LotType::Water: - creature->LOT.Step = SECTOR(20); - creature->LOT.Drop = -SECTOR(20); + creature->LOT.Step = BLOCK(20); + creature->LOT.Drop = -BLOCK(20); creature->LOT.Zone = ZoneType::Water; if (item->ObjectNumber == ID_CROCODILE) @@ -197,7 +197,7 @@ void InitializeSlot(short itemNumber, bool makeTarget) } ClearLOT(&creature->LOT); - if (itemNumber != Lara.ItemNumber) + if (itemNumber != LaraItem->Index) CreateZone(item); SlotsUsed++; diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp index 1c9e44a8a..29d219a29 100644 --- a/TombEngine/Game/control/volume.cpp +++ b/TombEngine/Game/control/volume.cpp @@ -30,7 +30,7 @@ namespace TEN::Control::Volumes if (roomNumber == Camera.pos.RoomNumber) { g_Renderer.AddDebugBox(volume.Box, - Vector4(color, 0.0f, color, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); + Vector4(color, 0.0f, color, 1.0f), RendererDebugPage::CollisionStats); } return volume.Box.Intersects(box); @@ -38,7 +38,7 @@ namespace TEN::Control::Volumes if (roomNumber == Camera.pos.RoomNumber) { g_Renderer.AddDebugSphere(volume.Sphere.Center, volume.Sphere.Radius, - Vector4(color, 0.0f, color, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); + Vector4(color, 0.0f, color, 1.0f), RendererDebugPage::CollisionStats); } return volume.Sphere.Intersects(box); @@ -171,7 +171,7 @@ namespace TEN::Control::Volumes auto box = (coll != nullptr) ? ConstructRoughBox(item, *coll) : GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose); - g_Renderer.AddDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RENDERER_DEBUG_PAGE::LARA_STATS); + g_Renderer.AddDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats); if (item.IsLara() || item.Index == Lara.Context.Vehicle) { diff --git a/TombEngine/Game/effects/debris.cpp b/TombEngine/Game/effects/debris.cpp index 79cbe0905..e221f9c48 100644 --- a/TombEngine/Game/effects/debris.cpp +++ b/TombEngine/Game/effects/debris.cpp @@ -24,7 +24,7 @@ bool ExplodeItemNode(ItemInfo* item, int node, int noXZVel, int bits) if (1 << node & item->MeshBits.ToPackedBits()) { int number = bits; - if (number == BODY_EXPLODE) + if (number == BODY_DO_EXPLOSION) number = -64; GetSpheres(item, CreatureSpheres, SPHERES_SPACE_WORLD | SPHERES_SPACE_BONE_ORIGIN, Matrix::Identity); diff --git a/TombEngine/Game/effects/effects.cpp b/TombEngine/Game/effects/effects.cpp index c48cbdea6..1d6202e4d 100644 --- a/TombEngine/Game/effects/effects.cpp +++ b/TombEngine/Game/effects/effects.cpp @@ -1146,7 +1146,7 @@ void TriggerWaterfallMist(const ItemInfo& item) if (item.TriggerFlags != 0) { size = item.TriggerFlags % 100; - width = std::clamp(int(round(item.TriggerFlags / 100) * 100) / 2, 0, SECTOR(8)); + width = std::clamp(int(round(item.TriggerFlags / 100) * 100) / 2, 0, BLOCK(8)); } float cos = phd_cos(angle); diff --git a/TombEngine/Game/effects/effects.h b/TombEngine/Game/effects/effects.h index b2f754e3d..4ac8024c2 100644 --- a/TombEngine/Game/effects/effects.h +++ b/TombEngine/Game/effects/effects.h @@ -157,8 +157,8 @@ struct Particle BLEND_MODES blendMode; unsigned char extras; signed char dynamic; - unsigned char fxObj; - unsigned char roomNumber; + int fxObj; + int roomNumber; unsigned char nodeNumber; // ParticleNodeOffsetIDs enum. }; @@ -211,9 +211,10 @@ extern FX_INFO EffectList[NUM_EFFECTS]; template TEffect& GetNewEffect(std::vector& effects, unsigned int countMax) { + assertion(effects.size() <= countMax, "Too many particle effects."); + // Add and return new effect. - assert(effects.size() <= countMax); - if (effects.size() != countMax) + if (effects.size() < countMax) return effects.emplace_back(); TEffect* effectPtr = nullptr; diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp index db6ea1b35..495cd73bb 100644 --- a/TombEngine/Game/effects/hair.cpp +++ b/TombEngine/Game/effects/hair.cpp @@ -29,7 +29,7 @@ namespace TEN::Effects::Hair // Get world matrix from head bone. auto worldMatrix = Matrix::Identity; - g_Renderer.GetBoneMatrix(player.ItemNumber, LM_HEAD, &worldMatrix); + g_Renderer.GetBoneMatrix(item.Index, LM_HEAD, &worldMatrix); // Apply base offset to world matrix. auto relOffset = GetRelBaseOffset(hairUnitIndex, isYoung); diff --git a/TombEngine/Game/effects/tomb4fx.cpp b/TombEngine/Game/effects/tomb4fx.cpp index 281066859..ba7d5a411 100644 --- a/TombEngine/Game/effects/tomb4fx.cpp +++ b/TombEngine/Game/effects/tomb4fx.cpp @@ -30,6 +30,9 @@ using namespace TEN::Collision::Floordata; using namespace TEN::Math; using TEN::Renderer::g_Renderer; +// NOTE: This fixes body part exploding instantly if entity is on ground. +constexpr auto BODY_PART_SPAWN_VERTICAL_OFFSET = CLICK(1); + char LaserSightActive = 0; char LaserSightCol = 0; int NextGunshell = 0; @@ -43,12 +46,11 @@ int NextSmokeSpark = 0; int NextBlood = 0; int NextGunShell = 0; -GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH]; -FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; -SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE]; -GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL]; -BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD]; -SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE]; +FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; +SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE]; +GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL]; +BLOOD_STRUCT Blood[MAX_SPARKS_BLOOD]; +SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE]; FIRE_LIST Fires[MAX_FIRE_LIST]; int GetFreeFireSpark() @@ -1168,7 +1170,7 @@ void ExplodeVehicle(ItemInfo* laraItem, ItemInfo* vehicle) auto* lara = GetLaraInfo(laraItem); - ExplodingDeath(lara->Context.Vehicle, BODY_EXPLODE | BODY_STONE_SOUND); + ExplodingDeath(lara->Context.Vehicle, BODY_DO_EXPLOSION | BODY_STONE_SOUND); KillItem(lara->Context.Vehicle); vehicle->Status = ITEM_DEACTIVATED; SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose); @@ -1192,6 +1194,10 @@ void ExplodingDeath(short itemNumber, short flags) auto world = item->Pose.Orientation.ToRotationMatrix(); + // If only BODY_PART_EXPLODE flag exists but not BODY_EXPLODE, add it. + if ((flags & BODY_PART_EXPLODE) && !(flags & BODY_DO_EXPLOSION)) + flags |= BODY_DO_EXPLOSION; + for (int i = 0; i < obj->nmeshes; i++) { Matrix boneMatrix; @@ -1203,7 +1209,7 @@ void ExplodingDeath(short itemNumber, short flags) item->MeshBits.Clear(i); - if (i == 0 || ((GetRandomControl() & 3) != 0 && (flags & BODY_EXPLODE))) + if (i == 0 || ((GetRandomControl() & 3) != 0 && (flags & BODY_DO_EXPLOSION))) { short fxNumber = CreateNewEffect(item->RoomNumber); if (fxNumber != NO_ITEM) @@ -1211,26 +1217,26 @@ void ExplodingDeath(short itemNumber, short flags) FX_INFO* fx = &EffectList[fxNumber]; fx->pos.Position.x = boneMatrix.Translation().x; - fx->pos.Position.y = boneMatrix.Translation().y; + fx->pos.Position.y = boneMatrix.Translation().y - BODY_PART_SPAWN_VERTICAL_OFFSET; fx->pos.Position.z = boneMatrix.Translation().z; fx->roomNumber = item->RoomNumber; fx->pos.Orientation.x = 0; - fx->pos.Orientation.y = GetRandomControl() * 2; + fx->pos.Orientation.y = Random::GenerateAngle(); - if (!(flags & 0x10)) + if (!(flags & BODY_NO_RAND_VELOCITY)) { - if (flags & 0x20) + if (flags & BODY_MORE_RAND_VELOCITY) fx->speed = GetRandomControl() >> 12; else fx->speed = GetRandomControl() >> 8; } - if (flags & 0x40) + if (flags & BODY_NO_VERTICAL_VELOCITY) fx->fallspeed = 0; else { - if ((flags & 0x80) == 0) + if (flags & BODY_LESS_IMPULSE) fx->fallspeed = -(GetRandomControl() >> 8); else fx->fallspeed = -(GetRandomControl() >> 12); diff --git a/TombEngine/Game/effects/tomb4fx.h b/TombEngine/Game/effects/tomb4fx.h index d0494a792..df0815c15 100644 --- a/TombEngine/Game/effects/tomb4fx.h +++ b/TombEngine/Game/effects/tomb4fx.h @@ -10,20 +10,19 @@ struct ItemInfo; enum BodyPartFlags { - BODY_NO_BOUNCE = (1 << 0), - BODY_GIBS = (1 << 1), - BODY_EXPLODE = (1 << 8), - BODY_NO_BOUNCE_ALT = (1 << 9), - BODY_STONE_SOUND = (1 << 11) -}; - -struct Matrix3D -{ - short m00, m01, m02; - short m10, m11, m12; - short m20, m21, m22; - short pad; - int tx, ty, tz; + BODY_NO_BOUNCE = (1 << 0), // No bounce. + BODY_GIBS = (1 << 1), // Add blood and SFX_TR4_LARA_THUD upon floor collision. + BODY_PART_EXPLODE = (1 << 2), // Explode upon impact. Requires BODY_EXPLODE flag. + BODY_NO_FLAME = (1 << 3), // No flame. + BODY_NO_RAND_VELOCITY = (1 << 4), // No random velocity. + BODY_MORE_RAND_VELOCITY = (1 << 5), // Add more randomness to velocity. + BODY_NO_VERTICAL_VELOCITY = (1 << 6), // No vertical velocity. + BODY_LESS_IMPULSE = (1 << 7), // Add less vertical velocity than normal. TODO: Weird name. + BODY_DO_EXPLOSION = (1 << 8), // Explode. + BODY_NO_BOUNCE_ALT = (1 << 9), // Same as BODY_NO_BOUNCE, but with delay before despawning. + BODY_STONE_SOUND = (1 << 11), // Do impact sound if stone. NOTE: BODY_GIBS also add sound, but this one is prioritary. + BODY_NO_SMOKE = (1 << 12), // Remove smoke upon despawn or shatter. + BODY_NO_SHATTER_EFFECT = (1 << 13), // Remove shatter effect upon despawn. }; struct SMOKE_SPARKS @@ -59,12 +58,6 @@ struct SMOKE_SPARKS byte mirror; }; -struct GUNFLASH_STRUCT -{ - Matrix3D matrix; - short on; -}; - struct SHOCKWAVE_STRUCT { int x; @@ -219,7 +212,6 @@ constexpr auto MAX_GUNFLASH = 4; constexpr auto MAX_GUNSHELL = 24; constexpr auto MAX_SHOCKWAVE = 16; -extern GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH]; extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE]; extern GUNSHELL_STRUCT Gunshells[MAX_GUNSHELL]; @@ -254,7 +246,7 @@ int GetFreeGunshell(); void TriggerGunShell(short hand, short objNum, LaraWeaponType weaponType); void UpdateGunShells(); void AddWaterSparks(int x, int y, int z, int num); -void ExplodingDeath(short itemNumber, short flags); // EXPLODE_ flags +void ExplodingDeath(short itemNumber, short flags); // BODY_ flags int GetFreeShockwave(); void TriggerShockwave(Pose* pos, short innerRad, short outerRad, int speed, unsigned char r, unsigned char g, unsigned char b, unsigned char life, EulerAngles rotation, short damage, bool sound, bool fadein, int style); void TriggerShockwaveHitEffect(int x, int y, int z, unsigned char r, unsigned char g, unsigned char b, short rot, int vel); diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index 8066736fa..91f38f23b 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -41,7 +41,7 @@ namespace TEN::Gui GuiController g_Gui; - const char* OptionStrings[] = + std::vector OptionStrings = { STRING_USE, STRING_CHOOSE_AMMO, @@ -58,31 +58,61 @@ namespace TEN::Gui // STRING_READ_DIARY }; - const char* ControlStrings[] = + std::vector GeneralActionStrings = { - STRING_CONTROLS_MOVE_FORWARD, - STRING_CONTROLS_MOVE_BACKWARD, - STRING_CONTROLS_MOVE_LEFT, - STRING_CONTROLS_MOVE_RIGHT, - STRING_CONTROLS_CROUCH, - STRING_CONTROLS_SPRINT, - STRING_CONTROLS_WALK, - STRING_CONTROLS_JUMP, - STRING_CONTROLS_ACTION, - STRING_CONTROLS_DRAW_WEAPON, - STRING_CONTROLS_USE_FLARE, - STRING_CONTROLS_LOOK, - STRING_CONTROLS_ROLL, - STRING_CONTROLS_INVENTORY, - STRING_CONTROLS_PAUSE, - STRING_CONTROLS_STEP_LEFT, - STRING_CONTROLS_STEP_RIGHT, - STRING_CONTROLS_V_ACCELERATE, - STRING_CONTROLS_V_REVERSE, - STRING_CONTROLS_V_SPEED, - STRING_CONTROLS_V_SLOW, - STRING_CONTROLS_V_BRAKE, - STRING_CONTROLS_V_FIRE + STRING_ACTIONS_FORWARD, + STRING_ACTIONS_BACKWARD, + STRING_ACTIONS_LEFT, + STRING_ACTIONS_RIGHT, + STRING_ACTIONS_STEP_LEFT, + STRING_ACTIONS_STEP_RIGHT, + STRING_ACTIONS_WALK, + STRING_ACTIONS_SPRINT, + STRING_ACTIONS_CROUCH, + STRING_ACTIONS_JUMP, + STRING_ACTIONS_ROLL, + STRING_ACTIONS_ACTION, + STRING_ACTIONS_DRAW, + STRING_ACTIONS_LOOK + }; + + std::vector VehicleActionStrings = + { + STRING_ACTIONS_ACCELERATE, + STRING_ACTIONS_REVERSE, + STRING_ACTIONS_SPEED, + STRING_ACTIONS_SLOW, + STRING_ACTIONS_BRAKE, + STRING_ACTIONS_FIRE + }; + + std::vector QuickActionStrings = + { + STRING_ACTIONS_FLARE, + STRING_ACTIONS_SMALL_MEDIPACK, + STRING_ACTIONS_LARGE_MEDIPACK, + STRING_ACTIONS_PREVIOUS_WEAPON, + STRING_ACTIONS_NEXT_WEAPON, + STRING_ACTIONS_WEAPON_1, + STRING_ACTIONS_WEAPON_2, + STRING_ACTIONS_WEAPON_3, + STRING_ACTIONS_WEAPON_4, + STRING_ACTIONS_WEAPON_5, + STRING_ACTIONS_WEAPON_6, + STRING_ACTIONS_WEAPON_7, + STRING_ACTIONS_WEAPON_8, + STRING_ACTIONS_WEAPON_9, + STRING_ACTIONS_WEAPON_10 + }; + + std::vector MenuActionStrings = + { + STRING_ACTIONS_SELECT, + STRING_ACTIONS_DESELECT, + STRING_ACTIONS_PAUSE, + STRING_ACTIONS_INVENTORY, + STRING_ACTIONS_SAVE, + STRING_ACTIONS_LOAD }; bool GuiController::GuiIsPulsed(ActionID actionID) const @@ -90,7 +120,12 @@ namespace TEN::Gui constexpr auto DELAY = 0.1f; constexpr auto INITIAL_DELAY = 0.4f; - auto oppositeAction = In::None; + // Action already held prior to entering menu; lock input. + if (GetActionTimeActive(actionID) >= TimeInMenu) + return false; + + // Pulse only directional inputs. + auto oppositeAction = std::optional(std::nullopt); switch (actionID) { case In::Forward: @@ -108,25 +143,39 @@ namespace TEN::Gui case In::Right: oppositeAction = In::Left; break; + + default: + break; } - bool isActionLocked = (oppositeAction == In::None) ? false : IsHeld(oppositeAction); - return (IsPulsed(actionID, DELAY, INITIAL_DELAY) && !isActionLocked); + // Opposite action held; lock input. + bool isActionLocked = oppositeAction.has_value() ? IsHeld(*oppositeAction) : false; + if (isActionLocked) + return false; + + return IsPulsed(actionID, DELAY, INITIAL_DELAY); } - bool GuiController::GuiIsSelected() const + bool GuiController::GuiIsSelected(bool onClicked) const { - return ((IsReleased(In::Select) || IsReleased(In::Action)) && CanSelect()); + if (onClicked) + { + return ((IsClicked(In::Select) || IsClicked(In::Action)) && CanSelect()); + } + else + { + return ((IsReleased(In::Select) || IsReleased(In::Action)) && CanSelect()); + } } bool GuiController::GuiIsDeselected() const { - return (IsClicked(In::Deselect) && CanDeselect()); + return ((IsClicked(In::Deselect) || IsClicked(In::Draw)) && CanDeselect()); } bool GuiController::CanSelect() const { - // Holding Deselect safely cancels input. + // Holding Deselect safely cancels select actions. if (IsHeld(In::Deselect)) return false; @@ -147,9 +196,9 @@ namespace TEN::Gui return CurrentSettings; } - InventoryRing* GuiController::GetRings(int ringIndex) + const InventoryRing& GuiController::GetRing(RingTypes ringType) { - return Rings[ringIndex]; + return Rings[(int)ringType]; } short GuiController::GetSelectedOption() @@ -211,6 +260,11 @@ namespace TEN::Gui return LastInvItem; } + void GuiController::SetLastInventoryItem(int itemNumber) + { + LastInvItem = itemNumber; + } + void GuiController::DrawInventory() { g_Renderer.RenderInventory(); @@ -260,7 +314,10 @@ namespace TEN::Gui HandleDisplaySettingsInput(false); return inventoryResult; - case Menu::Controls: + case Menu::GeneralActions: + case Menu::VehicleActions: + case Menu::QuickActions: + case Menu::MenuActions: HandleControlSettingsInput(item, false); return inventoryResult; @@ -307,8 +364,7 @@ namespace TEN::Gui SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); } - if (GuiIsDeselected() && - MenuToDisplay != Menu::Title) + if (GuiIsDeselected() && MenuToDisplay != Menu::Title) { MenuToDisplay = Menu::Title; SelectedOption = selectedOptionBackup; @@ -378,8 +434,8 @@ namespace TEN::Gui for (int i = 0; i < g_Configuration.SupportedScreenResolutions.size(); i++) { auto screenResolution = g_Configuration.SupportedScreenResolutions[i]; - if (screenResolution.x == CurrentSettings.Configuration.Width && - screenResolution.y == CurrentSettings.Configuration.Height) + if (screenResolution.x == CurrentSettings.Configuration.ScreenWidth && + screenResolution.y == CurrentSettings.Configuration.ScreenHeight) { CurrentSettings.SelectedScreenResolution = i; break; @@ -425,7 +481,7 @@ namespace TEN::Gui case DisplaySettingsOption::Windowed: SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); - CurrentSettings.Configuration.Windowed = !CurrentSettings.Configuration.Windowed; + CurrentSettings.Configuration.EnableWindowedMode = !CurrentSettings.Configuration.EnableWindowedMode; break; case DisplaySettingsOption::ShadowType: @@ -446,10 +502,10 @@ namespace TEN::Gui case DisplaySettingsOption::Antialiasing: SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); - if (CurrentSettings.Configuration.Antialiasing == AntialiasingMode::None) - CurrentSettings.Configuration.Antialiasing = AntialiasingMode::High; + if (CurrentSettings.Configuration.AntialiasingMode == AntialiasingMode::None) + CurrentSettings.Configuration.AntialiasingMode = AntialiasingMode::High; else - CurrentSettings.Configuration.Antialiasing = AntialiasingMode(int(CurrentSettings.Configuration.Antialiasing) - 1); + CurrentSettings.Configuration.AntialiasingMode = AntialiasingMode(int(CurrentSettings.Configuration.AntialiasingMode) - 1); break; } @@ -467,7 +523,7 @@ namespace TEN::Gui case DisplaySettingsOption::Windowed: SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); - CurrentSettings.Configuration.Windowed = !CurrentSettings.Configuration.Windowed; + CurrentSettings.Configuration.EnableWindowedMode = !CurrentSettings.Configuration.EnableWindowedMode; break; case DisplaySettingsOption::ShadowType: @@ -487,10 +543,10 @@ namespace TEN::Gui case DisplaySettingsOption::Antialiasing: SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); - if (CurrentSettings.Configuration.Antialiasing == AntialiasingMode::High) - CurrentSettings.Configuration.Antialiasing = AntialiasingMode::None; + if (CurrentSettings.Configuration.AntialiasingMode == AntialiasingMode::High) + CurrentSettings.Configuration.AntialiasingMode = AntialiasingMode::None; else - CurrentSettings.Configuration.Antialiasing = AntialiasingMode(int(CurrentSettings.Configuration.Antialiasing) + 1); + CurrentSettings.Configuration.AntialiasingMode = AntialiasingMode(int(CurrentSettings.Configuration.AntialiasingMode) + 1); break; } @@ -524,15 +580,15 @@ namespace TEN::Gui { // Save the configuration. auto screenResolution = g_Configuration.SupportedScreenResolutions[CurrentSettings.SelectedScreenResolution]; - CurrentSettings.Configuration.Width = screenResolution.x; - CurrentSettings.Configuration.Height = screenResolution.y; + CurrentSettings.Configuration.ScreenWidth = screenResolution.x; + CurrentSettings.Configuration.ScreenHeight = screenResolution.y; g_Configuration = CurrentSettings.Configuration; SaveConfiguration(); // Reset screen and go back. - g_Renderer.ChangeScreenResolution(CurrentSettings.Configuration.Width, CurrentSettings.Configuration.Height, - CurrentSettings.Configuration.Windowed); + g_Renderer.ChangeScreenResolution(CurrentSettings.Configuration.ScreenWidth, CurrentSettings.Configuration.ScreenHeight, + CurrentSettings.Configuration.EnableWindowedMode); MenuToDisplay = fromPauseMenu ? Menu::Pause : Menu::Options; SelectedOption = fromPauseMenu ? 1 : 0; @@ -547,7 +603,26 @@ namespace TEN::Gui void GuiController::HandleControlSettingsInput(ItemInfo* item, bool fromPauseMenu) { - static const int numControlSettingsOptions = KEY_COUNT + 2; + unsigned int numControlSettingsOptions = 0; + switch (MenuToDisplay) + { + default: + case Menu::GeneralActions: + numControlSettingsOptions = (int)GeneralActionStrings.size() + 2; + break; + + case Menu::VehicleActions: + numControlSettingsOptions = (int)VehicleActionStrings.size() + 2; + break; + + case Menu::QuickActions: + numControlSettingsOptions = (int)QuickActionStrings.size() + 2; + break; + + case Menu::MenuActions: + numControlSettingsOptions = (int)MenuActionStrings.size() + 2; + break; + } OptionCount = numControlSettingsOptions; CurrentSettings.WaitingForKey = false; @@ -593,9 +668,28 @@ namespace TEN::Gui if (selectedKey == MAX_INPUT_SLOTS) selectedKey = 0; - if (selectedKey && g_KeyNames[selectedKey]) + if (selectedKey && !g_KeyNames[selectedKey].empty()) { - KeyboardLayout[1][SelectedOption] = selectedKey; + unsigned int baseIndex = 0; + switch (MenuToDisplay) + { + case Menu::VehicleActions: + baseIndex = (unsigned int)GeneralActionStrings.size(); + break; + + case Menu::QuickActions: + baseIndex = unsigned int(GeneralActionStrings.size() + VehicleActionStrings.size()); + break; + + case Menu::MenuActions: + baseIndex = unsigned int(GeneralActionStrings.size() + VehicleActionStrings.size() + QuickActionStrings.size()); + break; + + default: + break; + } + + Bindings[1][baseIndex + SelectedOption] = selectedKey; DefaultConflict(); CurrentSettings.WaitingForKey = false; @@ -640,6 +734,43 @@ namespace TEN::Gui SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); } + // HACK: Menu screen scroll. + if (GuiIsPulsed(In::Left) || GuiIsPulsed(In::Right)) + { + auto menu = std::optional(std::nullopt); + + if (GuiIsPulsed(In::Left)) + { + if ((int)MenuToDisplay == (int)Menu::GeneralActions) + { + menu = Menu::MenuActions; + } + else + { + menu = Menu((int)MenuToDisplay - 1); + } + } + else if (GuiIsPulsed(In::Right)) + { + if ((int)MenuToDisplay == (int)Menu::MenuActions) + { + menu = Menu::GeneralActions; + } + else + { + menu = Menu((int)MenuToDisplay + 1); + } + } + + if (menu.has_value()) + { + MenuToDisplay = *menu; + SelectedOption = 0; + SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); + return; + } + } + if (GuiIsSelected()) { // Defaults. @@ -654,8 +785,8 @@ namespace TEN::Gui if (SelectedOption == (OptionCount - 1)) { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); - memcpy(CurrentSettings.Configuration.KeyboardLayout, KeyboardLayout[1], KEY_COUNT * sizeof(short)); - memcpy(g_Configuration.KeyboardLayout, KeyboardLayout[1], KEY_COUNT * sizeof(short)); + CurrentSettings.Configuration.Bindings = Bindings[1]; + g_Configuration.Bindings = Bindings[1]; SaveConfiguration(); MenuToDisplay = fromPauseMenu ? Menu::Pause : Menu::Options; SelectedOption = 2; @@ -666,7 +797,7 @@ namespace TEN::Gui if (SelectedOption == OptionCount) { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); - memcpy(KeyboardLayout[1], CurrentSettings.Configuration.KeyboardLayout, KEY_COUNT * sizeof(short)); + Bindings[1] = CurrentSettings.Configuration.Bindings; MenuToDisplay = fromPauseMenu ? Menu::Pause : Menu::Options; SelectedOption = 2; return; @@ -713,7 +844,7 @@ namespace TEN::Gui case OptionsOption::Controls: BackupOptions(); - MenuToDisplay = Menu::Controls; + MenuToDisplay = Menu::GeneralActions; SelectedOption = 0; break; } @@ -783,7 +914,7 @@ namespace TEN::Gui case OtherSettingsOption::ThumbstickCameraControl: SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); - CurrentSettings.Configuration.EnableThumbstickCameraControl = !CurrentSettings.Configuration.EnableThumbstickCameraControl; + CurrentSettings.Configuration.EnableThumbstickCamera = !CurrentSettings.Configuration.EnableThumbstickCamera; break; } } @@ -937,7 +1068,10 @@ namespace TEN::Gui HandleDisplaySettingsInput(true); return InventoryResult::None; - case Menu::Controls: + case Menu::GeneralActions: + case Menu::VehicleActions: + case Menu::QuickActions: + case Menu::MenuActions: HandleControlSettingsInput(item, true); return InventoryResult::None; @@ -970,8 +1104,7 @@ namespace TEN::Gui } } - if (GuiIsDeselected() || - IsClicked(In::Pause)) + if (GuiIsDeselected() || IsClicked(In::Pause)) { if (MenuToDisplay == Menu::Pause) { @@ -1093,9 +1226,11 @@ namespace TEN::Gui bool GuiController::IsItemInInventory(int objectNumber) { + const auto& ring = Rings[(int)RingTypes::Inventory]; for (int i = 0; i < INVENTORY_TABLE_SIZE; i++) { - if (Rings[(int)RingTypes::Inventory]->CurrentObjectList[i].InventoryItem == objectNumber) + const auto& listObject = ring.CurrentObjectList[i]; + if (listObject.InventoryItem == objectNumber) return true; } @@ -1138,10 +1273,12 @@ namespace TEN::Gui void GuiController::SetupObjectListStartPosition(int newObjectNumber) { + auto& ring = Rings[(int)RingTypes::Inventory]; for (int i = 0; i < INVENTORY_TABLE_SIZE; i++) { - if (Rings[(int)RingTypes::Inventory]->CurrentObjectList[i].InventoryItem == newObjectNumber) - Rings[(int)RingTypes::Inventory]->CurrentObjectInList = i; + const auto& listObject = ring.CurrentObjectList[i]; + if (listObject.InventoryItem == newObjectNumber) + ring.CurrentObjectInList = i; } } @@ -1154,19 +1291,22 @@ namespace TEN::Gui void GuiController::SetupAmmoSelector() { + const auto& ring = Rings[(int)RingTypes::Inventory]; + const auto& invObject = InventoryObjectTable[ring.CurrentObjectList[ring.CurrentObjectInList].InventoryItem]; + int number = 0; - unsigned __int64 options = InventoryObjectTable[Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem].Options; + unsigned __int64 options = invObject.Options; AmmoSelectorFlag = 0; NumAmmoSlots = 0; - if (Rings[(int)RingTypes::Ammo]->RingActive) + if (Rings[(int)RingTypes::Ammo].RingActive) return; AmmoObjectList[0].Orientation = EulerAngles::Zero; AmmoObjectList[1].Orientation = EulerAngles::Zero; AmmoObjectList[2].Orientation = EulerAngles::Zero; - if (options & + if (options & (OPT_CHOOSE_AMMO_UZI | OPT_CHOOSE_AMMO_PISTOLS | OPT_CHOOSE_AMMO_REVOLVER | OPT_CHOOSE_AMMO_CROSSBOW | OPT_CHOOSE_AMMO_HK | OPT_CHOOSE_AMMO_SHOTGUN | OPT_CHOOSE_AMMO_GRENADEGUN | OPT_CHOOSE_AMMO_HARPOON | OPT_CHOOSE_AMMO_ROCKET)) { @@ -1279,10 +1419,10 @@ namespace TEN::Gui void GuiController::InsertObjectIntoList(int objectNumber) { - Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->NumObjectsInList].InventoryItem = objectNumber; - Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->NumObjectsInList].Orientation = EulerAngles::Zero; - Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->NumObjectsInList].Bright = 32; - Rings[(int)RingTypes::Inventory]->NumObjectsInList++; + Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].NumObjectsInList].InventoryItem = objectNumber; + Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].NumObjectsInList].Orientation = EulerAngles::Zero; + Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].NumObjectsInList].Bright = 32; + Rings[(int)RingTypes::Inventory].NumObjectsInList++; } void GuiController::InsertObjectIntoList_v2(int objectNumber) @@ -1291,11 +1431,11 @@ namespace TEN::Gui if (options & (OPT_COMBINABLE | OPT_ALWAYS_COMBINE)) { - if (Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem != objectNumber) + if (Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem != objectNumber) { - Rings[(int)RingTypes::Ammo]->CurrentObjectList[Rings[(int)RingTypes::Ammo]->NumObjectsInList].InventoryItem = objectNumber; - Rings[(int)RingTypes::Ammo]->CurrentObjectList[Rings[(int)RingTypes::Ammo]->NumObjectsInList].Orientation = EulerAngles::Zero; - Rings[(int)RingTypes::Ammo]->CurrentObjectList[Rings[(int)RingTypes::Ammo]->NumObjectsInList++].Bright = 32; + Rings[(int)RingTypes::Ammo].CurrentObjectList[Rings[(int)RingTypes::Ammo].NumObjectsInList].InventoryItem = objectNumber; + Rings[(int)RingTypes::Ammo].CurrentObjectList[Rings[(int)RingTypes::Ammo].NumObjectsInList].Orientation = EulerAngles::Zero; + Rings[(int)RingTypes::Ammo].CurrentObjectList[Rings[(int)RingTypes::Ammo].NumObjectsInList++].Bright = 32; } } } @@ -1304,10 +1444,10 @@ namespace TEN::Gui { auto* lara = GetLaraInfo(item); - Rings[(int)RingTypes::Inventory]->NumObjectsInList = 0; + Rings[(int)RingTypes::Inventory].NumObjectsInList = 0; for (int i = 0; i < INVENTORY_TABLE_SIZE; i++) - Rings[(int)RingTypes::Inventory]->CurrentObjectList[i].InventoryItem = NO_ITEM; + Rings[(int)RingTypes::Inventory].CurrentObjectList[i].InventoryItem = NO_ITEM; Ammo.CurrentPistolsAmmoType = 0; Ammo.CurrentUziAmmoType = 0; @@ -1526,12 +1666,12 @@ namespace TEN::Gui InsertObjectIntoList(INV_OBJECT_SAVE_FLOPPY); } - Rings[(int)RingTypes::Inventory]->ObjectListMovement = 0; - Rings[(int)RingTypes::Inventory]->CurrentObjectInList = 0; - Rings[(int)RingTypes::Inventory]->RingActive = true; - Rings[(int)RingTypes::Ammo]->ObjectListMovement = 0; - Rings[(int)RingTypes::Ammo]->CurrentObjectInList = 0; - Rings[(int)RingTypes::Ammo]->RingActive = false; + Rings[(int)RingTypes::Inventory].ObjectListMovement = 0; + Rings[(int)RingTypes::Inventory].CurrentObjectInList = 0; + Rings[(int)RingTypes::Inventory].RingActive = true; + Rings[(int)RingTypes::Ammo].ObjectListMovement = 0; + Rings[(int)RingTypes::Ammo].CurrentObjectInList = 0; + Rings[(int)RingTypes::Ammo].RingActive = false; HandleObjectChangeover((int)RingTypes::Inventory); AmmoActive = 0; } @@ -1540,10 +1680,10 @@ namespace TEN::Gui { auto* lara = GetLaraInfo(item); - Rings[(int)RingTypes::Ammo]->NumObjectsInList = 0; + Rings[(int)RingTypes::Ammo].NumObjectsInList = 0; for (int i = 0; i < INVENTORY_TABLE_SIZE; i++) - Rings[(int)RingTypes::Ammo]->CurrentObjectList[i].InventoryItem = NO_ITEM; + Rings[(int)RingTypes::Ammo].CurrentObjectList[i].InventoryItem = NO_ITEM; if (!(g_GameFlow->GetLevel(CurrentLevel)->GetLaraType() == LaraType::Young)) { @@ -1617,9 +1757,16 @@ namespace TEN::Gui InsertObjectIntoList_v2(INV_OBJECT_EXAMINE1_COMBO1 + i); } - Rings[(int)RingTypes::Ammo]->ObjectListMovement = 0; - Rings[(int)RingTypes::Ammo]->CurrentObjectInList = 0; - Rings[(int)RingTypes::Ammo]->RingActive = false; + Rings[(int)RingTypes::Ammo].ObjectListMovement = 0; + Rings[(int)RingTypes::Ammo].CurrentObjectInList = 0; + Rings[(int)RingTypes::Ammo].RingActive = false; + } + + void GuiController::Initialize() + { + g_Gui.SetMenuToDisplay(Menu::Title); + g_Gui.SetSelectedOption(0); + g_Gui.SetLastInventoryItem(NO_ITEM); } void GuiController::InitializeInventory(ItemInfo* item) @@ -1697,9 +1844,11 @@ namespace TEN::Gui } } } + else + { + LastInvItem = NO_ITEM; + } } - - LastInvItem = NO_ITEM; } } else @@ -1730,8 +1879,8 @@ namespace TEN::Gui { for (int i = 0; i < INVENTORY_TABLE_SIZE; i++) { - if (InventoryObjectTable[Rings[(int)RingTypes::Inventory]->CurrentObjectList[i].InventoryItem].ObjectNumber == newObjectNumber) - Rings[(int)RingTypes::Inventory]->CurrentObjectInList = i; + if (InventoryObjectTable[Rings[(int)RingTypes::Inventory].CurrentObjectList[i].InventoryItem].ObjectNumber == newObjectNumber) + Rings[(int)RingTypes::Inventory].CurrentObjectInList = i; } } @@ -1753,8 +1902,10 @@ namespace TEN::Gui void GuiController::FadeAmmoSelector() { - if (Rings[(int)RingTypes::Inventory]->RingActive) + if (Rings[(int)RingTypes::Inventory].RingActive) + { AmmoSelectorFadeVal = 0; + } else if (AmmoSelectorFadeDir == 1) { if (AmmoSelectorFadeVal < 128) @@ -1802,7 +1953,7 @@ namespace TEN::Gui auto* lara = GetLaraInfo(item); int prevBinocularRange = BinocularRange; - short inventoryObject = Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem; + short inventoryObject = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem; short gameObject = InventoryObjectTable[inventoryObject].ObjectNumber; item->MeshBits = ALL_JOINT_BITS; @@ -2061,22 +2212,24 @@ namespace TEN::Gui void GuiController::DoInventory(ItemInfo* item) { auto* lara = GetLaraInfo(item); + auto& invRing = Rings[(int)RingTypes::Inventory]; + auto& ammoRing = Rings[(int)RingTypes::Ammo]; - if (Rings[(int)RingTypes::Ammo]->RingActive) + if (ammoRing.RingActive) { - auto optionString = g_GameFlow->GetString(OptionStrings[5]); + auto optionString = g_GameFlow->GetString(OptionStrings[5].c_str()); g_Renderer.AddString(PHD_CENTER_X, PHD_CENTER_Y, optionString, PRINTSTRING_COLOR_WHITE, PRINTSTRING_BLINK | PRINTSTRING_CENTER | PRINTSTRING_OUTLINE); - if (Rings[(int)RingTypes::Inventory]->ObjectListMovement) + if (invRing.ObjectListMovement) return; - if (Rings[(int)RingTypes::Ammo]->ObjectListMovement) + if (ammoRing.ObjectListMovement) return; - if (GuiIsSelected()) + if (GuiIsSelected(false)) { - short invItem = Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem; - short ammoItem = Rings[(int)RingTypes::Ammo]->CurrentObjectList[Rings[(int)RingTypes::Ammo]->CurrentObjectInList].InventoryItem; + short invItem = invRing.CurrentObjectList[invRing.CurrentObjectInList].InventoryItem; + short ammoItem = ammoRing.CurrentObjectList[ammoRing.CurrentObjectInList].InventoryItem; if (DoObjectsCombine(invItem, ammoItem)) { @@ -2135,66 +2288,66 @@ namespace TEN::Gui } else { - int num = Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem; + int num = invRing.CurrentObjectList[invRing.CurrentObjectInList].InventoryItem; for (int i = 0; i < 3; i++) { CurrentOptions[i].Type = MenuType::None; - CurrentOptions[i].Text = 0; + CurrentOptions[i].Text = {}; } int n = 0; unsigned long options; if (!AmmoActive) { - options = InventoryObjectTable[Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem].Options; + options = InventoryObjectTable[invRing.CurrentObjectList[invRing.CurrentObjectInList].InventoryItem].Options; if (options & OPT_LOAD) { CurrentOptions[0].Type = MenuType::Load; - CurrentOptions[0].Text = g_GameFlow->GetString(OptionStrings[6]); + CurrentOptions[0].Text = g_GameFlow->GetString(OptionStrings[6].c_str()); n = 1; } if (options & OPT_SAVE) { CurrentOptions[n].Type = MenuType::Save; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[7]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[7].c_str()); n++; } if (options & OPT_EXAMINABLE) { CurrentOptions[n].Type = MenuType::Examine; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[8]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[8].c_str()); n++; } if (options & OPT_STATS) { CurrentOptions[n].Type = MenuType::Statistics; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[9]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[9].c_str()); n++; } if (options & OPT_USE) { CurrentOptions[n].Type = MenuType::Use; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[0]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[0].c_str()); n++; } if (options & OPT_EQUIP) { CurrentOptions[n].Type = MenuType::Equip; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[4]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[4].c_str()); n++; } if (options & (OPT_CHOOSE_AMMO_SHOTGUN | OPT_CHOOSE_AMMO_CROSSBOW | OPT_CHOOSE_AMMO_GRENADEGUN | OPT_CHOOSE_AMMO_HK)) { CurrentOptions[n].Type = MenuType::ChooseAmmo; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[1]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[1].c_str()); n++; } @@ -2203,7 +2356,7 @@ namespace TEN::Gui if (IsItemCurrentlyCombinable(num)) { CurrentOptions[n].Type = MenuType::Combine; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[2]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[2].c_str()); n++; } } @@ -2211,21 +2364,21 @@ namespace TEN::Gui if (options & OPT_ALWAYS_COMBINE) { CurrentOptions[n].Type = MenuType::Combine; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[2]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[2].c_str()); n++; } if (options & OPT_SEPERABLE) { CurrentOptions[n].Type = MenuType::Seperate; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[3]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[3].c_str()); n++; } if (options & OPT_DIARY) { CurrentOptions[n].Type = MenuType::Diary; - CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[11]); + CurrentOptions[n].Text = g_GameFlow->GetString(OptionStrings[11].c_str()); n++; } } @@ -2237,7 +2390,7 @@ namespace TEN::Gui CurrentOptions[1].Text = g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[1].InventoryItem].ObjectName); n = 2; - options = InventoryObjectTable[Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem].Options; + options = InventoryObjectTable[invRing.CurrentObjectList[invRing.CurrentObjectInList].InventoryItem].Options; if (options & (OPT_CHOOSE_AMMO_CROSSBOW | OPT_CHOOSE_AMMO_GRENADEGUN | OPT_CHOOSE_AMMO_HK)) { @@ -2252,15 +2405,19 @@ namespace TEN::Gui int yPos = 310 - LINE_HEIGHT; if (n == 1) + { yPos += LINE_HEIGHT; + } else if (n == 2) + { yPos += LINE_HEIGHT / 2; + } if (n > 0) { for (int i = 0; i < n; i++) { - auto optionString = std::string(CurrentOptions[i].Text); + auto optionString = CurrentOptions[i].Text; if (i == CurrentSelectedOption) { @@ -2276,8 +2433,8 @@ namespace TEN::Gui } if (MenuActive && - !Rings[(int)RingTypes::Inventory]->ObjectListMovement && - !Rings[(int)RingTypes::Ammo]->ObjectListMovement) + !invRing.ObjectListMovement && + !ammoRing.ObjectListMovement) { if (AmmoActive) { @@ -2325,15 +2482,18 @@ namespace TEN::Gui } } - if (GuiIsSelected()) + if (GuiIsSelected(false)) { - if (CurrentOptions[CurrentSelectedOption].Type != MenuType::Equip && CurrentOptions[CurrentSelectedOption].Type != MenuType::Use) + if (CurrentOptions[CurrentSelectedOption].Type != MenuType::Equip && + CurrentOptions[CurrentSelectedOption].Type != MenuType::Use) + { SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always); + } switch (CurrentOptions[CurrentSelectedOption].Type) { case MenuType::ChooseAmmo: - Rings[(int)RingTypes::Inventory]->RingActive = false; + invRing.RingActive = false; AmmoActive = 1; Ammo.StashedCurrentSelectedOption = CurrentSelectedOption; Ammo.StashedCurrentPistolsAmmoType = Ammo.CurrentPistolsAmmoType; @@ -2369,14 +2529,14 @@ namespace TEN::Gui case MenuType::Ammo2: case MenuType::Ammo3: AmmoActive = 0; - Rings[(int)RingTypes::Inventory]->RingActive = true; + invRing.RingActive = true; CurrentSelectedOption = 0; break; case MenuType::Combine: ConstructCombineObjectList(item); - Rings[(int)RingTypes::Inventory]->RingActive = false; - Rings[(int)RingTypes::Ammo]->RingActive = true; + invRing.RingActive = false; + ammoRing.RingActive = true; AmmoSelectorFlag = 0; MenuActive = false; CombineRingFadeDir = 1; @@ -2404,7 +2564,7 @@ namespace TEN::Gui { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); AmmoActive = 0; - Rings[(int)RingTypes::Inventory]->RingActive = true; + invRing.RingActive = true; Ammo.CurrentPistolsAmmoType = Ammo.StashedCurrentPistolsAmmoType; Ammo.CurrentUziAmmoType = Ammo.StashedCurrentUziAmmoType; Ammo.CurrentRevolverAmmoType = Ammo.StashedCurrentRevolverAmmoType; @@ -2517,9 +2677,13 @@ namespace TEN::Gui char invTextBuffer[256]; if (AmmoObjectList[n].Amount == -1) + { sprintf(&invTextBuffer[0], "Unlimited %s", g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName)); + } else + { sprintf(&invTextBuffer[0], "%d x %s", AmmoObjectList[n].Amount, g_GameFlow->GetString(InventoryObjectTable[AmmoObjectList[n].InventoryItem].ObjectName)); + } // CHECK: AmmoSelectorFadeVal is never true and therefore the string is never printed. //if (AmmoSelectorFadeVal) @@ -2540,14 +2704,15 @@ namespace TEN::Gui } } - void GuiController::DrawCurrentObjectList(ItemInfo* item, int ringIndex) + void GuiController::DrawCurrentObjectList(ItemInfo* item, RingTypes ringType) { - auto* lara = GetLaraInfo(item); + const auto& player = GetLaraInfo(*item); + auto& ring = Rings[(int)ringType]; - if (Rings[ringIndex]->CurrentObjectList <= 0) + if (ring.CurrentObjectList <= 0) return; - if (ringIndex == (int)RingTypes::Ammo) + if (ringType == RingTypes::Ammo) { AmmoSelectorFadeVal = 0; AmmoSelectorFadeDir = 0; @@ -2573,16 +2738,18 @@ namespace TEN::Gui CombineRingFadeDir = 0; if (CombineTypeFlag) + { NormalRingFadeDir = 2; + } else { - Rings[(int)RingTypes::Inventory]->RingActive = true; + Rings[(int)RingTypes::Inventory].RingActive = true; MenuActive = true; - Rings[(int)RingTypes::Ammo]->RingActive = false; + Rings[(int)RingTypes::Ammo].RingActive = false; HandleObjectChangeover((int)RingTypes::Inventory); } - Rings[(int)RingTypes::Ammo]->RingActive = false; + Rings[(int)RingTypes::Ammo].RingActive = false; } } } @@ -2595,7 +2762,7 @@ namespace TEN::Gui { NormalRingFadeVal = 128; NormalRingFadeDir = 0; - Rings[(int)RingTypes::Inventory]->RingActive = true; + Rings[(int)RingTypes::Inventory].RingActive = true; MenuActive = true; } @@ -2621,7 +2788,9 @@ namespace TEN::Gui SetupObjectListStartPosition(CombineObject1); } else if (SeperateTypeFlag) - SeparateObject(item, Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem); + { + SeparateObject(item, Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem); + } HandleObjectChangeover((int)RingTypes::Inventory); } @@ -2632,34 +2801,34 @@ namespace TEN::Gui int xOffset = 0; int n = 0; - if (Rings[ringIndex]->NumObjectsInList != 1) - xOffset = (OBJLIST_SPACING * Rings[ringIndex]->ObjectListMovement) >> 16; + if (ring.NumObjectsInList != 1) + xOffset = (OBJLIST_SPACING * ring.ObjectListMovement) >> 16; - if (Rings[ringIndex]->NumObjectsInList == 2) + if (ring.NumObjectsInList == 2) { minObj = -1; maxObj = 0; - n = Rings[ringIndex]->CurrentObjectInList - 1; + n = ring.CurrentObjectInList - 1; } - if (Rings[ringIndex]->NumObjectsInList == 3 || Rings[ringIndex]->NumObjectsInList == 4) + if (ring.NumObjectsInList == 3 || ring.NumObjectsInList == 4) { minObj = -2; maxObj = 1; - n = Rings[ringIndex]->CurrentObjectInList - 2; + n = ring.CurrentObjectInList - 2; } - if (Rings[ringIndex]->NumObjectsInList >= 5) + if (ring.NumObjectsInList >= 5) { minObj = -3; maxObj = 2; - n = Rings[ringIndex]->CurrentObjectInList - 3; + n = ring.CurrentObjectInList - 3; } if (n < 0) - n += Rings[ringIndex]->NumObjectsInList; + n += ring.NumObjectsInList; - if (Rings[ringIndex]->ObjectListMovement < 0) + if (ring.ObjectListMovement < 0) maxObj++; if (minObj <= maxObj) @@ -2670,230 +2839,270 @@ namespace TEN::Gui if (minObj == i) { - if (Rings[ringIndex]->ObjectListMovement < 0) + if (ring.ObjectListMovement < 0) + { shade = 0; + } else - shade = Rings[ringIndex]->ObjectListMovement >> 9; + { + shade = ring.ObjectListMovement >> 9; + } } else if (i != minObj + 1 || maxObj == minObj + 1) { if (i != maxObj) + { shade = 128; + } else { - if (Rings[ringIndex]->ObjectListMovement < 0) - shade = (-128 * Rings[ringIndex]->ObjectListMovement) >> 16; + if (ring.ObjectListMovement < 0) + { + shade = (-128 * ring.ObjectListMovement) >> 16; + } else - shade = 128 - short(Rings[ringIndex]->ObjectListMovement >> 9); + { + shade = 128 - short(ring.ObjectListMovement >> 9); + } } } else { - if (Rings[ringIndex]->ObjectListMovement < 0) - shade = 128 - ((-128 * Rings[ringIndex]->ObjectListMovement) >> 16); + if (ring.ObjectListMovement < 0) + { + shade = 128 - ((-128 * ring.ObjectListMovement) >> 16); + } else + { shade = 128; + } } if (!minObj && !maxObj) shade = 128; - if (ringIndex == (int)RingTypes::Ammo && CombineRingFadeVal < 128 && shade) + if (ringType == RingTypes::Ammo && CombineRingFadeVal < 128 && shade) + { shade = CombineRingFadeVal; - else if (ringIndex == (int)RingTypes::Inventory && NormalRingFadeVal < 128 && shade) + } + else if (ringType == RingTypes::Inventory && NormalRingFadeVal < 128 && shade) + { shade = NormalRingFadeVal; + } + + auto& listObject = ring.CurrentObjectList[n]; + const auto& invObject = InventoryObjectTable[listObject.InventoryItem]; if (!i) { int numItems = 0; int count = 0; - char textBufferMe[128]; + char textBuffer[128]; - switch (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber) + switch (invObject.ObjectNumber) { case ID_BIGMEDI_ITEM: - numItems = lara->Inventory.TotalLargeMedipacks; + numItems = player.Inventory.TotalLargeMedipacks; break; case ID_SMALLMEDI_ITEM: - numItems = lara->Inventory.TotalSmallMedipacks; + numItems = player.Inventory.TotalSmallMedipacks; break; case ID_FLARE_INV_ITEM: - numItems = lara->Inventory.TotalFlares; + numItems = player.Inventory.TotalFlares; break; default: - if (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber < ID_PUZZLE_ITEM1 || - InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber > ID_PUZZLE_ITEM16) + if (invObject.ObjectNumber < ID_PUZZLE_ITEM1 || + invObject.ObjectNumber > ID_PUZZLE_ITEM16) { - switch (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber) + switch (invObject.ObjectNumber) { case ID_SHOTGUN_AMMO1_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); break; case ID_SHOTGUN_AMMO2_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::Shotgun].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); break; case ID_HK_AMMO_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::HK].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); break; case ID_CROSSBOW_AMMO1_ITEM: - count = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + count = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); numItems = count; break; case ID_CROSSBOW_AMMO2_ITEM: - count = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); + count = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); numItems = count; break; case ID_CROSSBOW_AMMO3_ITEM: - count = lara->Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); + count = player.Weapons[(int)LaraWeaponType::Crossbow].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); numItems = count; break; case ID_GRENADE_AMMO1_ITEM: - count = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + count = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); numItems = count; break; case ID_GRENADE_AMMO2_ITEM: - count = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); + count = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo2].GetCount(); numItems = count; break; case ID_GRENADE_AMMO3_ITEM: - count = lara->Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); + count = player.Weapons[(int)LaraWeaponType::GrenadeLauncher].Ammo[(int)WeaponAmmoType::Ammo3].GetCount(); numItems = count; break; case ID_ROCKET_LAUNCHER_AMMO_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::RocketLauncher].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); break; case ID_HARPOON_AMMO_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::HarpoonGun].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); break; case ID_REVOLVER_AMMO_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::Revolver].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); break; case ID_UZI_AMMO_ITEM: - numItems = lara->Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); + numItems = player.Weapons[(int)LaraWeaponType::Uzi].Ammo[(int)WeaponAmmoType::Ammo1].GetCount(); break; } } else { - numItems = lara->Inventory.Puzzles[InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber - ID_PUZZLE_ITEM1]; - + numItems = player.Inventory.Puzzles[invObject.ObjectNumber - ID_PUZZLE_ITEM1]; if (numItems <= 1) - sprintf(textBufferMe, g_GameFlow->GetString(InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectName)); + { + sprintf(textBuffer, g_GameFlow->GetString(invObject.ObjectName)); + } else - sprintf(textBufferMe, "%d x %s", numItems, g_GameFlow->GetString(InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectName)); + { + sprintf(textBuffer, "%d x %s", numItems, g_GameFlow->GetString(invObject.ObjectName)); + } } break; } - if (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber < ID_PUZZLE_ITEM1 || - InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectNumber > ID_PUZZLE_ITEM16) + if (invObject.ObjectNumber < ID_PUZZLE_ITEM1 || + invObject.ObjectNumber > ID_PUZZLE_ITEM16) { if (numItems) { if (numItems == -1) - sprintf(textBufferMe, "Unlimited %s", g_GameFlow->GetString(InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectName)); + { + sprintf(textBuffer, "Unlimited %s", g_GameFlow->GetString(invObject.ObjectName)); + } else - sprintf(textBufferMe, "%d x %s", numItems, g_GameFlow->GetString(InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectName)); + { + sprintf(textBuffer, "%d x %s", numItems, g_GameFlow->GetString(invObject.ObjectName)); + } } else - sprintf(textBufferMe, g_GameFlow->GetString(InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].ObjectName)); + { + sprintf(textBuffer, g_GameFlow->GetString(invObject.ObjectName)); + } } int objectNumber; - if (ringIndex == (int)RingTypes::Inventory) + if (ringType == RingTypes::Inventory) + { objectNumber = int(PHD_CENTER_Y - (SCREEN_SPACE_RES.y + 1) * 0.0625 * 2.5); + } else + { objectNumber = int(PHD_CENTER_Y + (SCREEN_SPACE_RES.y + 1) * 0.0625 * 2.0); + } - g_Renderer.AddString(PHD_CENTER_X, objectNumber, textBufferMe, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE); + g_Renderer.AddString(PHD_CENTER_X, objectNumber, textBuffer, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE); } - if (!i && !Rings[ringIndex]->ObjectListMovement) + if (!i && !ring.ObjectListMovement) { - if (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].RotFlags & INV_ROT_X) - Rings[ringIndex]->CurrentObjectList[n].Orientation.x += ANGLE(5.0f); + if (invObject.RotFlags & INV_ROT_X) + listObject.Orientation.x += ANGLE(5.0f); - if (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].RotFlags & INV_ROT_Y) - Rings[ringIndex]->CurrentObjectList[n].Orientation.y += ANGLE(5.0f); + if (invObject.RotFlags & INV_ROT_Y) + listObject.Orientation.y += ANGLE(5.0f); - if (InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].RotFlags & INV_ROT_Z) - Rings[ringIndex]->CurrentObjectList[n].Orientation.z += ANGLE(5.0f); + if (invObject.RotFlags & INV_ROT_Z) + listObject.Orientation.z += ANGLE(5.0f); } else - SpinBack(Rings[ringIndex]->CurrentObjectList[n].Orientation); + { + SpinBack(listObject.Orientation); + } int activeNum = 0; - if (Rings[ringIndex]->ObjectListMovement) + if (ring.ObjectListMovement) { - if (Rings[ringIndex]->ObjectListMovement > 0) + if (ring.ObjectListMovement > 0) + { activeNum = -1; + } else + { activeNum = 1; + } } if (i == activeNum) { - if (Rings[ringIndex]->CurrentObjectList[n].Bright < 160) - Rings[ringIndex]->CurrentObjectList[n].Bright += 16; + if (listObject.Bright < 160) + listObject.Bright += 16; - if (Rings[ringIndex]->CurrentObjectList[n].Bright > 160) - Rings[ringIndex]->CurrentObjectList[n].Bright = 160; + if (listObject.Bright > 160) + listObject.Bright = 160; } else { - if (Rings[ringIndex]->CurrentObjectList[n].Bright > 32) - Rings[ringIndex]->CurrentObjectList[n].Bright -= 16; + if (listObject.Bright > 32) + listObject.Bright -= 16; - if (Rings[ringIndex]->CurrentObjectList[n].Bright < 32) - Rings[ringIndex]->CurrentObjectList[n].Bright = 32; + if (listObject.Bright < 32) + listObject.Bright = 32; } int x = 400 + xOffset + i * OBJLIST_SPACING; int y = 150; int y2 = 480; // Combine. - short objectNumber = ConvertInventoryItemToObject(Rings[ringIndex]->CurrentObjectList[n].InventoryItem); - float scaler = InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].Scale1; - auto& orientation = Rings[ringIndex]->CurrentObjectList[n].Orientation; - int bits = InventoryObjectTable[Rings[ringIndex]->CurrentObjectList[n].InventoryItem].MeshBits; + short objectNumber = ConvertInventoryItemToObject(listObject.InventoryItem); + float scaler = invObject.Scale1; + auto& orient = listObject.Orientation; + int bits = invObject.MeshBits; - g_Renderer.DrawObjectIn2DSpace(objectNumber, Vector2(x, (ringIndex == (int)RingTypes::Inventory) ? y : y2), orientation, scaler, 1.0f, bits); + g_Renderer.DrawObjectIn2DSpace(objectNumber, Vector2(x, (ringType == RingTypes::Inventory) ? y : y2), orient, scaler, 1.0f, bits); - if (++n >= Rings[ringIndex]->NumObjectsInList) + if (++n >= ring.NumObjectsInList) n = 0; } - if (Rings[ringIndex]->RingActive) + if (ring.RingActive) { - if (Rings[ringIndex]->NumObjectsInList != 1 && (ringIndex != 1 || CombineRingFadeVal == 128)) + if (ring.NumObjectsInList != 1 && (ringType != RingTypes::Ammo || CombineRingFadeVal == 128)) { - if (Rings[ringIndex]->ObjectListMovement > 0) - Rings[ringIndex]->ObjectListMovement += ANGLE(45.0f); + if (ring.ObjectListMovement > 0) + ring.ObjectListMovement += ANGLE(45.0f); - if (Rings[ringIndex]->ObjectListMovement < 0) - Rings[ringIndex]->ObjectListMovement -= ANGLE(45.0f); + if (ring.ObjectListMovement < 0) + ring.ObjectListMovement -= ANGLE(45.0f); if (IsHeld(In::Left)) { - if (!Rings[ringIndex]->ObjectListMovement) + if (!ring.ObjectListMovement) { SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always); - Rings[ringIndex]->ObjectListMovement += ANGLE(45.0f); + ring.ObjectListMovement += ANGLE(45.0f); if (AmmoSelectorFlag) AmmoSelectorFadeDir = 2; @@ -2902,41 +3111,41 @@ namespace TEN::Gui if (IsHeld(In::Right)) { - if (!Rings[ringIndex]->ObjectListMovement) + if (!ring.ObjectListMovement) { SoundEffect(SFX_TR4_MENU_ROTATE, nullptr, SoundEnvironment::Always); - Rings[ringIndex]->ObjectListMovement -= ANGLE(45.0f); + ring.ObjectListMovement -= ANGLE(45.0f); if (AmmoSelectorFlag) AmmoSelectorFadeDir = 2; } } - if (Rings[ringIndex]->ObjectListMovement < 65536) + if (ring.ObjectListMovement < 65536) { - if (Rings[ringIndex]->ObjectListMovement < -65535) + if (ring.ObjectListMovement < -65535) { - Rings[ringIndex]->CurrentObjectInList++; + ring.CurrentObjectInList++; - if (Rings[ringIndex]->CurrentObjectInList >= Rings[ringIndex]->NumObjectsInList) - Rings[ringIndex]->CurrentObjectInList = 0; + if (ring.CurrentObjectInList >= ring.NumObjectsInList) + ring.CurrentObjectInList = 0; - Rings[ringIndex]->ObjectListMovement = 0; + ring.ObjectListMovement = 0; - if (ringIndex == (int)RingTypes::Inventory) + if (ringType == RingTypes::Inventory) HandleObjectChangeover(0); } } else { - Rings[ringIndex]->CurrentObjectInList--; + ring.CurrentObjectInList--; - if (Rings[ringIndex]->CurrentObjectInList < 0) - Rings[ringIndex]->CurrentObjectInList = Rings[ringIndex]->NumObjectsInList - 1; + if (ring.CurrentObjectInList < 0) + ring.CurrentObjectInList = ring.NumObjectsInList - 1; - Rings[ringIndex]->ObjectListMovement = 0; + ring.ObjectListMovement = 0; - if (ringIndex == (int)RingTypes::Inventory) + if (ringType == RingTypes::Inventory) HandleObjectChangeover(0); } } @@ -2984,9 +3193,6 @@ namespace TEN::Gui lara->Inventory.OldBusy = lara->Inventory.IsBusy; - Rings[(int)RingTypes::Inventory] = &PCRing1; - Rings[(int)RingTypes::Ammo] = &PCRing2; - g_Renderer.DumpGameScene(); PauseAllSounds(SoundPauseMode::Inventory); SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); @@ -3008,7 +3214,7 @@ namespace TEN::Gui UpdateInputActions(item); - if (IsClicked(In::Option)) + if (GuiIsDeselected() || IsClicked(In::Inventory)) { SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always); exitLoop = true; @@ -3076,7 +3282,7 @@ namespace TEN::Gui Camera.numberFrames = g_Renderer.Synchronize(); } - LastInvItem = Rings[(int)RingTypes::Inventory]->CurrentObjectList[Rings[(int)RingTypes::Inventory]->CurrentObjectInList].InventoryItem; + LastInvItem = Rings[(int)RingTypes::Inventory].CurrentObjectList[Rings[(int)RingTypes::Inventory].CurrentObjectInList].InventoryItem; UpdateWeaponStatus(item); if (UseItem) diff --git a/TombEngine/Game/gui.h b/TombEngine/Game/gui.h index e417bf82f..41357a9b2 100644 --- a/TombEngine/Game/gui.h +++ b/TombEngine/Game/gui.h @@ -5,11 +5,11 @@ #include "Specific/configuration.h" #include "Specific/Input/InputAction.h" +struct ItemInfo; + using namespace TEN::Input; using namespace TEN::Math; -struct ItemInfo; - namespace TEN::Gui { enum class InventoryMode @@ -76,20 +76,23 @@ namespace TEN::Gui LoadGame, Options, Display, - Controls, + GeneralActions, + VehicleActions, + QuickActions, + MenuActions, OtherSettings }; struct MenuOption { - MenuType Type; - char const* Text; + MenuType Type = MenuType::None; + std::string Text = {}; }; struct ObjectList { - short InventoryItem; - EulerAngles Orientation = EulerAngles::Zero; + int InventoryItem = 0; + EulerAngles Orientation = EulerAngles::Zero; unsigned short Bright; }; @@ -115,7 +118,7 @@ namespace TEN::Gui private: // Input inquirers bool GuiIsPulsed(ActionID actionID) const; - bool GuiIsSelected() const; + bool GuiIsSelected(bool onClicked = true) const; bool GuiIsDeselected() const; bool CanSelect() const; bool CanDeselect() const; @@ -135,9 +138,7 @@ namespace TEN::Gui bool UseItem; char SeperateTypeFlag; char CombineTypeFlag; - InventoryRing PCRing1; - InventoryRing PCRing2; - InventoryRing* Rings[2]; + InventoryRing Rings[2]; int CurrentSelectedOption; bool MenuActive; char AmmoSelectorFlag; @@ -161,12 +162,13 @@ namespace TEN::Gui public: int CompassNeedleAngle; + void Initialize(); bool CallPause(); bool CallInventory(ItemInfo* item, bool resetMode); InventoryResult TitleOptions(ItemInfo* item); InventoryResult DoPauseMenu(ItemInfo* item); void DrawInventory(); - void DrawCurrentObjectList(ItemInfo* item, int ringIndex); + void DrawCurrentObjectList(ItemInfo* item, RingTypes ringType); int IsObjectInInventory(int objectNumber); int ConvertObjectToInventoryItem(int objectNumber); int ConvertInventoryItemToObject(int objectNumber); @@ -176,7 +178,7 @@ namespace TEN::Gui void DrawCompass(ItemInfo* item); // Getters - InventoryRing* GetRings(int ringIndex); + const InventoryRing& GetRing(RingTypes ringType); short GetSelectedOption(); Menu GetMenuToDisplay(); InventoryMode GetInventoryMode(); @@ -192,6 +194,7 @@ namespace TEN::Gui void SetInventoryMode(InventoryMode mode); void SetEnterInventory(int number); void SetInventoryItemChosen(int number); + void SetLastInventoryItem(int itemNumber); private: void HandleDisplaySettingsInput(bool fromPauseMenu); @@ -226,5 +229,9 @@ namespace TEN::Gui }; extern GuiController g_Gui; - extern const char* ControlStrings[]; + extern std::vector OptionStrings; + extern std::vector GeneralActionStrings; + extern std::vector VehicleActionStrings; + extern std::vector QuickActionStrings; + extern std::vector MenuActionStrings; } diff --git a/TombEngine/Game/itemdata/creature_info.h b/TombEngine/Game/itemdata/creature_info.h index 79ec80761..206e3ded2 100644 --- a/TombEngine/Game/itemdata/creature_info.h +++ b/TombEngine/Game/itemdata/creature_info.h @@ -73,20 +73,20 @@ struct LOTInfo struct CreatureBiteInfo { - Vector3i Position = Vector3i::Zero; // TODO: Change back to Vector3. - int BoneID = -1; + Vector3 Position = Vector3::Zero; + int BoneID = -1; CreatureBiteInfo() {} - CreatureBiteInfo(const Vector3i& pos, int boneID) + CreatureBiteInfo(const Vector3& pos, int boneID) { Position = pos; BoneID = boneID; } - CreatureBiteInfo(int x, int y, int z, int boneID) + CreatureBiteInfo(float x, float y, float z, int boneID) { - Position = Vector3i(x, y, z); + Position = Vector3(x, y, z); BoneID = boneID; } }; @@ -103,7 +103,7 @@ struct CreatureMuzzleFlashInfo CreatureMuzzleFlashInfo() {} - CreatureMuzzleFlashInfo(const Vector3i& pos, int boneID, int delay, bool changeToMuzzle2 = false) + CreatureMuzzleFlashInfo(const Vector3& pos, int boneID, int delay, bool changeToMuzzle2 = false) { Bite = CreatureBiteInfo(pos, boneID); Delay = delay; diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp index 0ce0f2819..e574205be 100644 --- a/TombEngine/Game/items.cpp +++ b/TombEngine/Game/items.cpp @@ -149,10 +149,23 @@ bool ItemInfo::IsCreature() const void ItemInfo::ResetModelToDefault() { - Model.BaseMesh = Objects[ObjectNumber].meshIndex; + if (Objects[ObjectNumber].nmeshes > 0) + { + Model.MeshIndex.resize(Objects[ObjectNumber].nmeshes); + Model.BaseMesh = Objects[ObjectNumber].meshIndex; - for (int i = 0; i < Model.MeshIndex.size(); i++) - Model.MeshIndex[i] = Model.BaseMesh + i; + for (int i = 0; i < Model.MeshIndex.size(); i++) + Model.MeshIndex[i] = Model.BaseMesh + i; + + Model.Mutators.resize(Objects[ObjectNumber].nmeshes); + for (auto& mutator : Model.Mutators) + mutator = {}; + } + else + { + Model.Mutators.clear(); + Model.MeshIndex.clear(); + } } bool TestState(int refState, const vector& stateList) @@ -239,7 +252,9 @@ void KillItem(short const itemNumber) if (item == Lara.TargetEntity) Lara.TargetEntity = nullptr; - if (Objects[item->ObjectNumber].floor != nullptr) + // AI target generation uses a hack with making a dummy item without ObjectNumber. + // Therefore, a check should be done here to prevent access violation. + if (item->ObjectNumber != GAME_OBJECT_ID::ID_NO_OBJECT && Objects[item->ObjectNumber].floor != nullptr) UpdateBridgeItem(itemNumber, true); GameScriptHandleKilled(itemNumber, true); @@ -553,20 +568,7 @@ void InitializeItem(short itemNumber) item->Floor = floor->GetSurfaceHeight(item->Pose.Position.x, item->Pose.Position.z, true); item->BoxNumber = floor->Box; - if (Objects[item->ObjectNumber].nmeshes > 0) - { - item->Model.MeshIndex.resize(Objects[item->ObjectNumber].nmeshes); - item->ResetModelToDefault(); - - item->Model.Mutators.resize(Objects[item->ObjectNumber].nmeshes); - for (auto& mutator : item->Model.Mutators) - mutator = {}; - } - else - { - item->Model.Mutators.clear(); - item->Model.MeshIndex.clear(); - } + item->ResetModelToDefault(); if (Objects[item->ObjectNumber].Initialize != nullptr) Objects[item->ObjectNumber].Initialize(itemNumber); @@ -710,7 +712,7 @@ ItemInfo* FindItem(GAME_OBJECT_ID objectID) int FindItem(ItemInfo* item) { if (item == LaraItem) - return Lara.ItemNumber; + return item->Index; for (int i = 0; i < g_Level.NumItems; i++) if (item == &g_Level.Items[i]) @@ -729,6 +731,9 @@ void UpdateAllItems() auto* item = &g_Level.Items[itemNumber]; short nextItem = item->NextActive; + if (!Objects.CheckID(item->ObjectNumber)) + continue; + if (item->AfterDeath <= ITEM_DEATH_TIMEOUT) { if (Objects[item->ObjectNumber].control) diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp index 606a10329..96a2b7ed9 100644 --- a/TombEngine/Game/missile.cpp +++ b/TombEngine/Game/missile.cpp @@ -75,7 +75,9 @@ void ControlMissile(short fxNumber) else if (fx.objectNumber == ID_PROJ_BOMB) { SoundEffect(SFX_TR1_ATLANTEAN_EXPLODE, &fx.pos, soundFXType); - TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 0, false, isUnderwater, fx.roomNumber); + TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -2, 0, fx.roomNumber); + TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -1, 0, fx.roomNumber); + TriggerShockwave(&fx.pos, 48, 304, (GetRandomControl() & 0x1F) + 112, 128, 32, 32, 32, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, (int)ShockwaveStyle::Normal); } if (hasHitPlayer) @@ -83,24 +85,20 @@ void ControlMissile(short fxNumber) if (fx.objectNumber == ID_KNIFETHROWER_KNIFE) { DoDamage(LaraItem, KNIFE_DAMAGE); - KillEffect(fxNumber); } else if (fx.objectNumber == ID_SCUBA_HARPOON) { DoDamage(LaraItem, DIVER_HARPOON_DAMAGE); - KillEffect(fxNumber); } else if (fx.objectNumber == ID_PROJ_BOMB) { DoDamage(LaraItem, MUTANT_BOMB_DAMAGE); - KillEffect(fxNumber); } else if (fx.objectNumber == ID_PROJ_SHARD) { TriggerBlood(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 0, 10); SoundEffect(SFX_TR4_BLOOD_LOOP, &fx.pos, soundFXType); DoDamage(LaraItem, MUTANT_SHARD_DAMAGE); - KillEffect(fxNumber); } LaraItem->HitStatus = true; @@ -109,6 +107,8 @@ void ControlMissile(short fxNumber) fx.frameNumber = 0; fx.counter = 0; } + + KillEffect(fxNumber); } if (pointColl.RoomNumber != fx.roomNumber) @@ -161,14 +161,14 @@ void ControlNatlaGun(short fxNumber) fxNew.roomNumber = pointColl.RoomNumber; fxNew.speed = fx.speed; fxNew.frameNumber = 0; - fxNew.objectNumber = ID_PROJ_NATLA; + fxNew.objectNumber = ID_PROJ_BOMB; } } } short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber) { - short fxNumber = CreateNewEffect(roomNumber); + int fxNumber = CreateNewEffect(roomNumber); if (fxNumber != NO_ITEM) { auto& fx = EffectList[fxNumber]; @@ -188,7 +188,7 @@ short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber) { - short fxNumber = CreateNewEffect(roomNumber); + int fxNumber = CreateNewEffect(roomNumber); if (fxNumber != NO_ITEM) { auto& fx = EffectList[fxNumber]; @@ -205,23 +205,3 @@ short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber) return fxNumber; } - -short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber) -{ - short fxNumber = CreateNewEffect(roomNumber); - if (fxNumber != NO_ITEM) - { - auto& fx = EffectList[fxNumber]; - - fx.pos.Position = Vector3i(x, y, z); - fx.pos.Orientation = EulerAngles(0, yRot, 0); - fx.roomNumber = roomNumber; - fx.speed = velocity; - fx.frameNumber = 0; - fx.objectNumber = ID_PROJ_NATLA; - fx.color = Vector4::One; - ShootAtLara(fx); - } - - return fxNumber; -} diff --git a/TombEngine/Game/missile.h b/TombEngine/Game/missile.h index 6b87a0fd2..cefd6872f 100644 --- a/TombEngine/Game/missile.h +++ b/TombEngine/Game/missile.h @@ -7,4 +7,3 @@ void ControlNatlaGun(short fxNumber); short ShardGun(int x, int y, int z, short velocity, short yRot, short roomNumber); short BombGun(int x, int y, int z, short velocity, short yRot, short roomNumber); -short NatlaGun(int x, int y, int z, short velocity, short yRot, short roomNumber); diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp index 45806ae62..6395808fe 100644 --- a/TombEngine/Game/pickup/pickup.cpp +++ b/TombEngine/Game/pickup/pickup.cpp @@ -212,6 +212,20 @@ void CollectCarriedItems(ItemInfo* item) item->CarriedItem = NO_ITEM; } +static void HideOrDisablePickup(ItemInfo& pickupItem) +{ + if (pickupItem.TriggerFlags & 0xC0) + { + pickupItem.Status = ITEM_INVISIBLE; + pickupItem.Flags |= TRIGGERED; + pickupItem.ItemFlags[3] = 1; + } + else + { + KillItem(pickupItem.Index); + } +} + void CollectMultiplePickups(int itemNumber) { auto* firstItem = &g_Level.Items[itemNumber]; @@ -244,15 +258,7 @@ void CollectMultiplePickups(int itemNumber) } } - if (currentItem->TriggerFlags & 0xC0) - { - currentItem->Status = ITEM_INVISIBLE; - currentItem->Flags |= TRIGGERED; - currentItem->ItemFlags[3] = 1; - } - - //currentItem->Pose.Orientation = prevOrient; - KillItem(currentItem->Index); + HideOrDisablePickup(*currentItem); if (currentItem == firstItem) break; @@ -313,16 +319,7 @@ void DoPickup(ItemInfo* laraItem) } g_Hud.PickupSummary.AddDisplayPickup(pickupItem->ObjectNumber, pickupItem->Pose.Position.ToVector3()); - if (!(pickupItem->TriggerFlags & 0xC0)) - { - KillItem(pickupItemNumber); - } - else - { - pickupItem->Status = ITEM_INVISIBLE; - pickupItem->Flags |= TRIGGERED; - pickupItem->ItemFlags[3] = 1; - } + HideOrDisablePickup(*pickupItem); pickupItem->Pose.Orientation = prevOrient; lara->Context.InteractedItem = NO_ITEM; @@ -357,15 +354,9 @@ void DoPickup(ItemInfo* laraItem) } } - if (pickupItem->TriggerFlags & 0xC0) - { - pickupItem->Status = ITEM_INVISIBLE; - pickupItem->Flags |= TRIGGERED; - pickupItem->ItemFlags[3] = 1; - } + HideOrDisablePickup(*pickupItem); pickupItem->Pose.Orientation = prevOrient; - KillItem(pickupItemNumber); lara->Context.InteractedItem = NO_ITEM; return; } diff --git a/TombEngine/Game/room.cpp b/TombEngine/Game/room.cpp index 37c7052b0..ebc8f615b 100644 --- a/TombEngine/Game/room.cpp +++ b/TombEngine/Game/room.cpp @@ -123,8 +123,8 @@ int IsRoomOutside(int x, int y, int z) if (x < 0 || z < 0) return NO_ROOM; - int xTable = x / SECTOR(1); - int zTable = z / SECTOR(1); + int xTable = x / BLOCK(1); + int zTable = z / BLOCK(1); if (OutsideRoomTable[xTable][zTable].empty()) return NO_ROOM; @@ -135,8 +135,8 @@ int IsRoomOutside(int x, int y, int z) auto* room = &g_Level.Rooms[roomNumber]; if ((y > room->maxceiling && y < room->minfloor) && - (z > (room->z + SECTOR(1)) && z < (room->z + (room->zSize - 1) * SECTOR(1))) && - (x > (room->x + SECTOR(1)) && x < (room->x + (room->xSize - 1) * SECTOR(1)))) + (z > (room->z + BLOCK(1)) && z < (room->z + (room->zSize - 1) * BLOCK(1))) && + (x > (room->x + BLOCK(1)) && x < (room->x + (room->xSize - 1) * BLOCK(1)))) { auto probe = GetCollision(x, y, z, roomNumber); @@ -161,8 +161,8 @@ int IsRoomOutside(int x, int y, int z) FloorInfo* GetSector(ROOM_INFO* room, int x, int z) { - int sectorX = std::clamp(x / SECTOR(1), 0, room->xSize - 1); - int sectorZ = std::clamp(z / SECTOR(1), 0, room->zSize - 1); + int sectorX = std::clamp(x / BLOCK(1), 0, room->xSize - 1); + int sectorZ = std::clamp(z / BLOCK(1), 0, room->zSize - 1); int index = sectorZ + sectorX * room->zSize; if (index > room->floor.size()) @@ -218,8 +218,8 @@ Vector3i GetRoomCenter(int roomNumber) { auto* room = &g_Level.Rooms[roomNumber]; - auto halfLength = SECTOR(room->xSize) / 2; - auto halfDepth = SECTOR(room->zSize) / 2; + auto halfLength = BLOCK(room->xSize) / 2; + auto halfDepth = BLOCK(room->zSize) / 2; auto halfHeight = (room->maxceiling - room->minfloor) / 2; auto center = Vector3i( diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index 698a564dd..578e37956 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -80,59 +80,52 @@ void SaveGame::LoadSavegameInfos() } } -Pose ToPHD(const Save::Position* src) +Pose ToPose(const Save::Pose* pose) { - Pose dest; - dest.Position.x = src->x_pos(); - dest.Position.y = src->y_pos(); - dest.Position.z = src->z_pos(); - dest.Orientation.x = (short)src->x_rot(); - dest.Orientation.y = (short)src->y_rot(); - dest.Orientation.z = (short)src->z_rot(); - return dest; + return Pose( + pose->x_pos(), pose->y_pos(), pose->z_pos(), + (short)pose->x_rot(), (short)pose->y_rot(), (short)pose->z_rot()); } -Save::Position FromPHD(const Pose& src) +Save::Pose FromPose(const Pose& pose) { - return Save::Position - { - src.Position.x, - src.Position.y, - src.Position.z, - src.Orientation.x, - src.Orientation.y, - src.Orientation.z - }; + return Save::Pose( + pose.Position.x, + pose.Position.y, + pose.Position.z, + pose.Orientation.x, + pose.Orientation.y, + pose.Orientation.z); } -Save::Vector2 FromVector2(Vector2i vec) +Save::EulerAngles FromEulerAngles(const EulerAngles& eulers) +{ + return Save::EulerAngles(eulers.x, eulers.y, eulers.z); +} + +Save::Vector2 FromVector2(const Vector2i& vec) { return Save::Vector2(vec.x, vec.y); } -Save::Vector3 FromVector3(Vector3 vec) +Save::Vector3 FromVector3(const Vector3& vec) { return Save::Vector3(vec.x, vec.y, vec.z); } -Save::Vector3 FromVector3(Vector3i vec) +Save::Vector3 FromVector3(const Vector3i& vec) { return Save::Vector3(vec.x, vec.y, vec.z); } -Save::Vector3 FromVector3(EulerAngles vec) -{ - return Save::Vector3(vec.x, vec.y, vec.z); -} - -Save::Vector4 FromVector4(Vector4 vec) +Save::Vector4 FromVector4(const Vector4& vec) { return Save::Vector4(vec.x, vec.y, vec.z, vec.w); } -EulerAngles ToEulerAngles(const Save::Vector3* vec) +EulerAngles ToEulerAngles(const Save::EulerAngles* eulers) { - return EulerAngles((short)vec->x(), (short)vec->y(), (short)vec->z()); + return EulerAngles((short)eulers->x(), (short)eulers->y(), (short)eulers->z()); } Vector2i ToVector2i(const Save::Vector2* vec) @@ -271,11 +264,6 @@ bool SaveGame::Save(int slot) dripNodes.push_back(Lara.Effect.DripNodes[i] == 1); auto dripNodesOffset = fbb.CreateVector(dripNodes); - std::vector laraTargetAngles{}; - laraTargetAngles.push_back(Lara.TargetArmOrient.y); - laraTargetAngles.push_back(Lara.TargetArmOrient.x); - auto laraTargetAnglesOffset = fbb.CreateVector(laraTargetAngles); - std::vector subsuitVelocity{}; subsuitVelocity.push_back(Lara.Control.Subsuit.Velocity[0]); subsuitVelocity.push_back(Lara.Control.Subsuit.Velocity[1]); @@ -294,7 +282,7 @@ bool SaveGame::Save(int slot) leftArm.add_frame_base(Lara.LeftArm.FrameBase); leftArm.add_frame_number(Lara.LeftArm.FrameNumber); leftArm.add_locked(Lara.LeftArm.Locked); - leftArm.add_rotation(&FromVector3(Lara.LeftArm.Orientation)); + leftArm.add_rotation(&FromEulerAngles(Lara.LeftArm.Orientation)); auto leftArmOffset = leftArm.Finish(); Save::ArmInfoBuilder rightArm{ fbb }; @@ -304,7 +292,7 @@ bool SaveGame::Save(int slot) rightArm.add_frame_base(Lara.RightArm.FrameBase); rightArm.add_frame_number(Lara.RightArm.FrameNumber); rightArm.add_locked(Lara.RightArm.Locked); - rightArm.add_rotation(&FromVector3(Lara.RightArm.Orientation)); + rightArm.add_rotation(&FromEulerAngles(Lara.RightArm.Orientation)); auto rightArmOffset = rightArm.Finish(); Save::FlareDataBuilder flare{ fbb }; @@ -402,10 +390,21 @@ bool SaveGame::Save(int slot) subsuitControl.add_hit_count(Lara.Control.Subsuit.HitCount); auto subsuitControlOffset = subsuitControl.Finish(); + Save::PlayerContextDataBuilder context{ fbb }; + context.add_calc_jump_velocity(Lara.Context.CalcJumpVelocity); + context.add_interacted_item_number(Lara.Context.InteractedItem); + context.add_next_corner_pose(&FromPose(Lara.Context.NextCornerPos)); + context.add_projected_floor_height(Lara.Context.ProjectedFloorHeight); + context.add_target_orient(&FromEulerAngles(Lara.Context.TargetOrientation)); + context.add_vehicle_item_number(Lara.Context.Vehicle); + context.add_water_current_active(Lara.Context.WaterCurrentActive); + context.add_water_current_pull(&FromVector3(Lara.Context.WaterCurrentPull)); + context.add_water_surface_dist(Lara.Context.WaterSurfaceDist); + auto contextOffset = context.Finish(); + Save::LaraControlDataBuilder control{ fbb }; control.add_move_angle(Lara.Control.MoveAngle); control.add_turn_rate(Lara.Control.TurnRate); - control.add_calculated_jump_velocity(Lara.Context.CalcJumpVelocity); control.add_jump_direction((int)Lara.Control.JumpDirection); control.add_hand_status((int)Lara.Control.HandStatus); control.add_is_moving(Lara.Control.IsMoving); @@ -467,33 +466,25 @@ bool SaveGame::Save(int slot) auto carriedWeaponsOffset = fbb.CreateVector(carriedWeapons); Save::LaraBuilder lara{ fbb }; + lara.add_context(contextOffset); lara.add_control(controlOffset); - lara.add_next_corner_pose(&FromPHD(Lara.Context.NextCornerPos)); lara.add_effect(effectOffset); lara.add_extra_anim(Lara.ExtraAnim); - lara.add_extra_head_rot(&FromVector3(Lara.ExtraHeadRot)); - lara.add_extra_torso_rot(&FromVector3(Lara.ExtraTorsoRot)); + lara.add_extra_head_rot(&FromEulerAngles(Lara.ExtraHeadRot)); + lara.add_extra_torso_rot(&FromEulerAngles(Lara.ExtraTorsoRot)); lara.add_flare(flareOffset); lara.add_highest_location(Lara.HighestLocation); lara.add_hit_direction(Lara.HitDirection); lara.add_hit_frame(Lara.HitFrame); - lara.add_interacted_item(Lara.Context.InteractedItem); lara.add_inventory(inventoryOffset); - lara.add_item_number(Lara.ItemNumber); lara.add_left_arm(leftArmOffset); lara.add_location(Lara.Location); lara.add_location_pad(Lara.LocationPad); - lara.add_projected_floor_height(Lara.Context.ProjectedFloorHeight); lara.add_right_arm(rightArmOffset); lara.add_status(statusOffset); - lara.add_target_facing_angle(Lara.Context.TargetOrientation.y); - lara.add_target_arm_angles(laraTargetAnglesOffset); + lara.add_target_arm_orient(&FromEulerAngles(Lara.TargetArmOrient)); lara.add_target_entity_number(Lara.TargetEntity == nullptr ? -1 : Lara.TargetEntity->Index); lara.add_torch(torchOffset); - lara.add_vehicle(Lara.Context.Vehicle); - lara.add_water_current_active(Lara.Context.WaterCurrentActive); - lara.add_water_current_pull(&FromVector3(Lara.Context.WaterCurrentPull)); - lara.add_water_surface_dist(Lara.Context.WaterSurfaceDist); lara.add_weapons(carriedWeaponsOffset); auto laraOffset = lara.Finish(); @@ -516,8 +507,6 @@ bool SaveGame::Save(int slot) int currentItemIndex = 0; for (auto& itemToSerialize : g_Level.Items) { - ObjectInfo* obj = &Objects[itemToSerialize.ObjectNumber]; - auto luaNameOffset = fbb.CreateString(itemToSerialize.Name); auto luaOnKilledNameOffset = fbb.CreateString(itemToSerialize.Callbacks.OnKilled); auto luaOnHitNameOffset = fbb.CreateString(itemToSerialize.Callbacks.OnHit); @@ -543,7 +532,8 @@ bool SaveGame::Save(int slot) flatbuffers::Offset shortOffset; flatbuffers::Offset intOffset; - if (Objects[itemToSerialize.ObjectNumber].intelligent && itemToSerialize.IsCreature()) + if (Objects.CheckID(itemToSerialize.ObjectNumber, true) && + Objects[itemToSerialize.ObjectNumber].intelligent && itemToSerialize.IsCreature()) { auto creature = GetCreatureInfo(&itemToSerialize); @@ -649,7 +639,7 @@ bool SaveGame::Save(int slot) kayakBuilder.add_front_vertical_velocity(kayak->FrontVerticalVelocity); kayakBuilder.add_left_right_count(kayak->LeftRightPaddleCount); kayakBuilder.add_left_vertical_velocity(kayak->LeftVerticalVelocity); - kayakBuilder.add_old_pos(&FromPHD(kayak->OldPose)); + kayakBuilder.add_old_pos(&FromPose(kayak->OldPose)); kayakBuilder.add_right_vertical_velocity(kayak->RightVerticalVelocity); kayakBuilder.add_true_water(kayak->TrueWater); kayakBuilder.add_turn(kayak->Turn); @@ -672,9 +662,12 @@ bool SaveGame::Save(int slot) } Save::ItemBuilder serializedItem{ fbb }; + + if (Objects.CheckID(itemToSerialize.ObjectNumber, true)) + serializedItem.add_anim_number(itemToSerialize.Animation.AnimNumber - Objects[itemToSerialize.ObjectNumber].animIndex); + serializedItem.add_next_item(itemToSerialize.NextItem); serializedItem.add_next_item_active(itemToSerialize.NextActive); - serializedItem.add_anim_number(itemToSerialize.Animation.AnimNumber - obj->animIndex); serializedItem.add_after_death(itemToSerialize.AfterDeath); serializedItem.add_box_number(itemToSerialize.BoxNumber); serializedItem.add_carried_item(itemToSerialize.CarriedItem); @@ -690,7 +683,7 @@ bool SaveGame::Save(int slot) serializedItem.add_mesh_pointers(meshPointerOffset); serializedItem.add_base_mesh(itemToSerialize.Model.BaseMesh); serializedItem.add_object_id(itemToSerialize.ObjectNumber); - serializedItem.add_pose(&FromPHD(itemToSerialize.Pose)); + serializedItem.add_pose(&FromPose(itemToSerialize.Pose)); serializedItem.add_required_state(itemToSerialize.Animation.RequiredState); serializedItem.add_room_number(itemToSerialize.RoomNumber); serializedItem.add_velocity(&FromVector3(itemToSerialize.Animation.Velocity)); @@ -711,8 +704,8 @@ bool SaveGame::Save(int slot) serializedItem.add_effect_secondary_colour(&FromVector3(itemToSerialize.Effect.SecondaryEffectColor)); serializedItem.add_effect_count(itemToSerialize.Effect.Count); - if (Objects[itemToSerialize.ObjectNumber].intelligent - && itemToSerialize.Data.is()) + if (Objects.CheckID(itemToSerialize.ObjectNumber, true) && + Objects[itemToSerialize.ObjectNumber].intelligent && itemToSerialize.Data.is()) { serializedItem.add_data_type(Save::ItemData::Creature); serializedItem.add_data(creatureOffset.Union()); @@ -769,7 +762,7 @@ bool SaveGame::Save(int slot) { Save::FXInfoBuilder serializedEffect{ fbb }; - serializedEffect.add_pose(&FromPHD(effectToSerialize.pos)); + serializedEffect.add_pose(&FromPose(effectToSerialize.pos)); serializedEffect.add_room_number(effectToSerialize.roomNumber); serializedEffect.add_object_number(effectToSerialize.objectNumber); serializedEffect.add_next_fx(effectToSerialize.nextFx); @@ -788,7 +781,6 @@ bool SaveGame::Save(int slot) auto serializedEffectsOffset = fbb.CreateVector(serializedEffects); // Event set call counters - std::vector> serializedEventSetCallCounters{}; for (auto& set : g_Level.EventSets) { @@ -804,12 +796,18 @@ bool SaveGame::Save(int slot) auto serializedEventSetCallCountersOffset = fbb.CreateVector(serializedEventSetCallCounters); // Soundtrack playheads - auto bgmTrackData = GetSoundTrackNameAndPosition(SoundTrackType::BGM); - auto oneshotTrackData = GetSoundTrackNameAndPosition(SoundTrackType::OneShot); - auto voiceTrackData = GetSoundTrackNameAndPosition(SoundTrackType::Voice); - auto bgmTrackOffset = fbb.CreateString(bgmTrackData.first); - auto oneshotTrackOffset = fbb.CreateString(oneshotTrackData.first); - auto voiceTrackOffset = fbb.CreateString(voiceTrackData.first); + std::vector> soundtracks; + for (int j = 0; j < (int)SoundTrackType::Count; j++) + { + auto trackData = GetSoundTrackNameAndPosition((SoundTrackType)j); + auto nameOffset = fbb.CreateString(trackData.first); + + Save::SoundtrackBuilder track{ fbb }; + track.add_name(nameOffset); + track.add_position(trackData.second); + soundtracks.push_back(track.Finish()); + } + auto soundtrackOffset = fbb.CreateVector(soundtracks); // Legacy soundtrack map std::vector soundTrackMap; @@ -883,7 +881,7 @@ bool SaveGame::Save(int slot) { Save::StaticMeshInfoBuilder staticMesh{ fbb }; - staticMesh.add_pose(&FromPHD(room->mesh[j].pos)); + staticMesh.add_pose(&FromPose(room->mesh[j].pos)); staticMesh.add_scale(room->mesh[j].scale); staticMesh.add_color(&FromVector4(room->mesh[j].color)); @@ -998,7 +996,7 @@ bool SaveGame::Save(int slot) batInfo.add_flags(bat->Counter); batInfo.add_on(bat->On); batInfo.add_room_number(bat->RoomNumber); - batInfo.add_pose(&FromPHD(bat->Pose)); + batInfo.add_pose(&FromPose(bat->Pose)); bats.push_back(batInfo.Finish()); } @@ -1014,7 +1012,7 @@ bool SaveGame::Save(int slot) spiderInfo.add_flags(spider->Flags); spiderInfo.add_on(spider->On); spiderInfo.add_room_number(spider->RoomNumber); - spiderInfo.add_pose(&FromPHD(spider->Pose)); + spiderInfo.add_pose(&FromPose(spider->Pose)); spiders.push_back(spiderInfo.Finish()); } @@ -1030,7 +1028,7 @@ bool SaveGame::Save(int slot) ratInfo.add_flags(rat->Flags); ratInfo.add_on(rat->On); ratInfo.add_room_number(rat->RoomNumber); - ratInfo.add_pose(&FromPHD(rat->Pose)); + ratInfo.add_pose(&FromPose(rat->Pose)); rats.push_back(ratInfo.Finish()); } @@ -1046,7 +1044,7 @@ bool SaveGame::Save(int slot) scarabInfo.add_flags(beetle->Flags); scarabInfo.add_on(beetle->On); scarabInfo.add_room_number(beetle->RoomNumber); - scarabInfo.add_pose(&FromPHD(beetle->Pose)); + scarabInfo.add_pose(&FromPose(beetle->Pose)); scarabs.push_back(scarabInfo.Finish()); } @@ -1270,12 +1268,7 @@ bool SaveGame::Save(int slot) sgb.add_fxinfos(serializedEffectsOffset); sgb.add_next_fx_free(NextFxFree); sgb.add_next_fx_active(NextFxActive); - sgb.add_ambient_track(bgmTrackOffset); - sgb.add_ambient_position(bgmTrackData.second); - sgb.add_oneshot_track(oneshotTrackOffset); - sgb.add_oneshot_position(oneshotTrackData.second); - sgb.add_voice_track(voiceTrackOffset); - sgb.add_voice_position(voiceTrackData.second); + sgb.add_soundtracks(soundtrackOffset); sgb.add_cd_flags(soundtrackMapOffset); sgb.add_action_queue(actionQueueOffset); sgb.add_flip_maps(flipMapsOffset); @@ -1284,6 +1277,7 @@ bool SaveGame::Save(int slot) sgb.add_flip_effect(FlipEffect); sgb.add_flip_status(FlipStatus); sgb.add_current_fov(LastFOV); + sgb.add_last_inv_item(g_Gui.GetLastInventoryItem()); sgb.add_static_meshes(staticMeshesOffset); sgb.add_volumes(volumesOffset); sgb.add_fixed_cameras(camerasOffset); @@ -1389,7 +1383,7 @@ bool SaveGame::Load(int slot) auto room = &g_Level.Rooms[staticMesh->room_number()]; int number = staticMesh->number(); - room->mesh[number].pos = ToPHD(staticMesh->pose()); + room->mesh[number].pos = ToPose(staticMesh->pose()); room->mesh[number].roomNumber = staticMesh->room_number(); room->mesh[number].scale = staticMesh->scale(); room->mesh[number].color = ToVector4(staticMesh->color()); @@ -1450,6 +1444,9 @@ bool SaveGame::Load(int slot) // Restore camera FOV AlterFOV(s->current_fov()); + // Restore current inventory item + g_Gui.SetLastInventoryItem(s->last_inv_item()); + // Restore action queue for (int i = 0; i < s->action_queue()->size(); i++) { @@ -1458,9 +1455,13 @@ bool SaveGame::Load(int slot) } // Restore soundtracks - PlaySoundTrack(s->ambient_track()->str(), SoundTrackType::BGM, s->ambient_position()); - PlaySoundTrack(s->oneshot_track()->str(), SoundTrackType::OneShot, s->oneshot_position()); - PlaySoundTrack(s->voice_track()->str(), SoundTrackType::Voice, s->voice_position()); + for (int i = 0; i < s->soundtracks()->size(); i++) + { + assertion(i < (int)SoundTrackType::Count, "Soundtrack type count was changed"); + + auto track = s->soundtracks()->Get(i); + PlaySoundTrack(track->name()->str(), (SoundTrackType)i, track->position()); + } // Legacy soundtrack map for (int i = 0; i < s->cd_flags()->size(); i++) @@ -1511,6 +1512,9 @@ bool SaveGame::Load(int slot) item->NextItem = savedItem->next_item(); item->NextActive = savedItem->next_item_active(); + if (item->ObjectNumber == GAME_OBJECT_ID::ID_NO_OBJECT) + continue; + ObjectInfo* obj = &Objects[item->ObjectNumber]; item->Name = savedItem->lua_name()->str(); @@ -1524,7 +1528,7 @@ bool SaveGame::Load(int slot) g_GameScriptEntities->TryAddColliding(i); - item->Pose = ToPHD(savedItem->pose()); + item->Pose = ToPose(savedItem->pose()); item->RoomNumber = savedItem->room_number(); item->Animation.Velocity = ToVector3(savedItem->velocity()); @@ -1532,10 +1536,9 @@ bool SaveGame::Load(int slot) if (item->ObjectNumber == ID_LARA && !dynamicItem) { LaraItem->Data = nullptr; - Lara.ItemNumber = i; LaraItem = item; LaraItem->Location.roomNumber = savedItem->room_number(); - LaraItem->Location.yNumber = item->Pose.Orientation.y; + LaraItem->Location.yNumber = item->Pose.Position.y; LaraItem->Data = &Lara; } @@ -1710,7 +1713,7 @@ bool SaveGame::Load(int slot) kayak->FrontVerticalVelocity = savedKayak->front_vertical_velocity(); kayak->LeftRightPaddleCount = savedKayak->left_right_count(); kayak->LeftVerticalVelocity = savedKayak->left_vertical_velocity(); - kayak->OldPose = ToPHD(savedKayak->old_pos()); + kayak->OldPose = ToPose(savedKayak->old_pos()); kayak->RightVerticalVelocity = savedKayak->right_vertical_velocity(); kayak->TrueWater = savedKayak->true_water(); kayak->Turn = savedKayak->turn(); @@ -1784,7 +1787,7 @@ bool SaveGame::Load(int slot) bat->On = batInfo->on(); bat->Counter = batInfo->flags(); bat->RoomNumber = batInfo->room_number(); - bat->Pose = ToPHD(batInfo->pose()); + bat->Pose = ToPose(batInfo->pose()); } for (int i = 0; i < s->rats()->size(); i++) @@ -1795,7 +1798,7 @@ bool SaveGame::Load(int slot) rat->On = ratInfo->on(); rat->Flags = ratInfo->flags(); rat->RoomNumber = ratInfo->room_number(); - rat->Pose = ToPHD(ratInfo->pose()); + rat->Pose = ToPose(ratInfo->pose()); } for (int i = 0; i < s->spiders()->size(); i++) @@ -1806,7 +1809,7 @@ bool SaveGame::Load(int slot) spider->On = spiderInfo->on(); spider->Flags = spiderInfo->flags(); spider->RoomNumber = spiderInfo->room_number(); - spider->Pose = ToPHD(spiderInfo->pose()); + spider->Pose = ToPose(spiderInfo->pose()); } for (int i = 0; i < s->scarabs()->size(); i++) @@ -1817,7 +1820,7 @@ bool SaveGame::Load(int slot) beetle->On = beetleInfo->on(); beetle->Flags = beetleInfo->flags(); beetle->RoomNumber = beetleInfo->room_number(); - beetle->Pose = ToPHD(beetleInfo->pose()); + beetle->Pose = ToPose(beetleInfo->pose()); } NextFxFree = s->next_fx_free(); @@ -1827,7 +1830,7 @@ bool SaveGame::Load(int slot) { auto& fx = EffectList[i]; auto fx_saved = s->fxinfos()->Get(i); - fx.pos = ToPHD(fx_saved->pose()); + fx.pos = ToPose(fx_saved->pose()); fx.roomNumber = fx_saved->room_number(); fx.objectNumber = fx_saved->object_number(); fx.nextFx = fx_saved->next_fx(); @@ -1894,7 +1897,17 @@ bool SaveGame::Load(int slot) for (int i = 0; i < Lara.Effect.DripNodes.size(); i++) Lara.Effect.DripNodes[i] = s->lara()->effect()->drip_nodes()->Get(i); - Lara.Context.CalcJumpVelocity = s->lara()->control()->calculated_jump_velocity(); + Lara.Context.CalcJumpVelocity = s->lara()->context()->calc_jump_velocity(); + Lara.Context.WaterCurrentActive = s->lara()->context()->water_current_active(); + Lara.Context.WaterCurrentPull.x = s->lara()->context()->water_current_pull()->x(); + Lara.Context.WaterCurrentPull.y = s->lara()->context()->water_current_pull()->y(); + Lara.Context.WaterCurrentPull.z = s->lara()->context()->water_current_pull()->z(); + Lara.Context.InteractedItem = s->lara()->context()->interacted_item_number(); + Lara.Context.NextCornerPos = ToPose(s->lara()->context()->next_corner_pose()); + Lara.Context.ProjectedFloorHeight = s->lara()->context()->projected_floor_height(); + Lara.Context.TargetOrientation = ToEulerAngles(s->lara()->context()->target_orient()); + Lara.Context.Vehicle = s->lara()->context()->vehicle_item_number(); + Lara.Context.WaterSurfaceDist = s->lara()->context()->water_surface_dist(); Lara.Control.CanMonkeySwing = s->lara()->control()->can_monkey_swing(); Lara.Control.CanClimbLadder = s->lara()->control()->is_climbing_ladder(); Lara.Control.Count.Death = s->lara()->control()->count()->death(); @@ -1934,17 +1947,12 @@ bool SaveGame::Load(int slot) Lara.ExtraTorsoRot.z = s->lara()->extra_torso_rot()->x(); Lara.ExtraTorsoRot.y = s->lara()->extra_torso_rot()->y(); Lara.ExtraTorsoRot.z = s->lara()->extra_torso_rot()->z(); - Lara.Context.WaterCurrentActive = s->lara()->water_current_active(); - Lara.Context.WaterCurrentPull.x = s->lara()->water_current_pull()->x(); - Lara.Context.WaterCurrentPull.y = s->lara()->water_current_pull()->y(); - Lara.Context.WaterCurrentPull.z = s->lara()->water_current_pull()->z(); Lara.Flare.Life = s->lara()->flare()->life(); Lara.Flare.ControlLeft = s->lara()->flare()->control_left(); Lara.Flare.Frame = s->lara()->flare()->frame(); Lara.HighestLocation = s->lara()->highest_location(); Lara.HitDirection = s->lara()->hit_direction(); Lara.HitFrame = s->lara()->hit_frame(); - Lara.Context.InteractedItem = s->lara()->interacted_item(); Lara.Inventory.BeetleComponents = s->lara()->inventory()->beetle_components(); Lara.Inventory.BeetleLife = s->lara()->inventory()->beetle_life(); Lara.Inventory.BigWaterskin = s->lara()->inventory()->big_waterskin(); @@ -1959,7 +1967,6 @@ bool SaveGame::Load(int slot) Lara.Inventory.TotalFlares = s->lara()->inventory()->total_flares(); Lara.Inventory.TotalLargeMedipacks = s->lara()->inventory()->total_large_medipacks(); Lara.Inventory.TotalSmallMedipacks = s->lara()->inventory()->total_small_medipacks(); - Lara.ItemNumber = s->lara()->item_number(); Lara.LeftArm.AnimNumber = s->lara()->left_arm()->anim_number(); Lara.LeftArm.GunFlash = s->lara()->left_arm()->gun_flash(); Lara.LeftArm.GunSmoke = s->lara()->left_arm()->gun_smoke(); @@ -1969,8 +1976,6 @@ bool SaveGame::Load(int slot) Lara.LeftArm.Orientation = ToEulerAngles(s->lara()->left_arm()->rotation()); Lara.Location = s->lara()->location(); Lara.LocationPad = s->lara()->location_pad(); - Lara.Context.NextCornerPos = ToPHD(s->lara()->next_corner_pose()); - Lara.Context.ProjectedFloorHeight = s->lara()->projected_floor_height(); Lara.RightArm.AnimNumber = s->lara()->right_arm()->anim_number(); Lara.RightArm.GunFlash = s->lara()->right_arm()->gun_flash(); Lara.RightArm.GunSmoke = s->lara()->right_arm()->gun_smoke(); @@ -2012,12 +2017,8 @@ bool SaveGame::Load(int slot) Lara.Status.Exposure = s->lara()->status()->exposure(); Lara.Status.Poison = s->lara()->status()->poison(); Lara.Status.Stamina = s->lara()->status()->stamina(); - Lara.TargetEntity = (s->lara()->target_entity_number() >= 0 ? &g_Level.Items[s->lara()->target_entity_number()] : nullptr); - Lara.TargetArmOrient.y = s->lara()->target_arm_angles()->Get(0); - Lara.TargetArmOrient.x = s->lara()->target_arm_angles()->Get(1); - Lara.Context.TargetOrientation.y = s->lara()->target_facing_angle(); - Lara.Context.Vehicle = s->lara()->vehicle(); - Lara.Context.WaterSurfaceDist = s->lara()->water_surface_dist(); + Lara.TargetEntity = (s->lara()->target_entity_number() >= 0) ? &g_Level.Items[s->lara()->target_entity_number()] : nullptr; + Lara.TargetArmOrient = ToEulerAngles(s->lara()->target_arm_orient()); for (int i = 0; i < s->lara()->weapons()->size(); i++) { diff --git a/TombEngine/Math/Constants.h b/TombEngine/Math/Constants.h index e0a9aee2f..c3c137c01 100644 --- a/TombEngine/Math/Constants.h +++ b/TombEngine/Math/Constants.h @@ -4,29 +4,27 @@ //namespace TEN::Math //{ // Math constants - constexpr inline auto PI = 3.14159265358979323846264338327950288419716939937510f; - constexpr inline auto PI_MUL_2 = PI * 2; - constexpr inline auto PI_DIV_2 = PI / 2; - constexpr inline auto PI_DIV_4 = PI / 4; - constexpr inline auto RADIAN = PI / 180; - constexpr inline auto SQRT_2 = 1.41421356237309504880168872420969807856967187537694f; - constexpr inline auto EPSILON = 0.00001f; + constexpr auto PI = 3.14159265358979323846264338327950288419716939937510f; + constexpr auto PI_MUL_2 = PI * 2; + constexpr auto PI_DIV_2 = PI / 2; + constexpr auto PI_DIV_4 = PI / 4; + constexpr auto RADIAN = PI / 180; + constexpr auto SQRT_2 = 1.41421356237309504880168872420969807856967187537694f; + constexpr auto EPSILON = 0.00001f; - constexpr inline auto SQUARE = [](auto x) { return (x * x); }; - constexpr inline auto CUBE = [](auto x) { return (x * x * x); }; + constexpr auto SQUARE = [](auto x) { return (x * x); }; + constexpr auto CUBE = [](auto x) { return (x * x * x); }; // World constants - constexpr inline auto BLOCK_UNIT = 1024; - constexpr inline auto NO_HEIGHT = INT_MIN + UCHAR_MAX; - constexpr inline auto MAX_HEIGHT = INT_MIN + 1; // NOTE: +1 prevents issues with sign change. - constexpr inline auto DEEP_WATER = INT_MAX - 1; // NOTE: -1 prevents issues with sign change. + constexpr auto BLOCK_UNIT = 1024; + constexpr auto NO_HEIGHT = INT_MIN + UCHAR_MAX; + constexpr auto MAX_HEIGHT = INT_MIN + 1; // NOTE: +1 prevents issues with sign change. + constexpr auto DEEP_WATER = INT_MAX - 1; // NOTE: -1 prevents issues with sign change. - constexpr inline auto BLOCK = [](auto x) { return (BLOCK_UNIT * x); }; - constexpr inline auto SECTOR = [](auto x) { return BLOCK(x); }; // TODO: Replace with BLOCK() at some point. - constexpr inline auto CLICK = [](auto x) { return ((BLOCK(1) / 4) * x); }; + constexpr auto BLOCK = [](auto x) { return (BLOCK_UNIT * x); }; + constexpr auto CLICK = [](auto x) { return ((BLOCK(1) / 4) * x); }; - constexpr inline auto STEP_SIZE = CLICK(1); - constexpr inline auto STOP_SIZE = CLICK(2); - constexpr inline auto WALL_MASK = BLOCK(1) - 1; // TODO: Rename to BLOCK_MASK? - constexpr inline auto GRID_SNAP_SIZE = (int)BLOCK(1 / 8.0f); + constexpr auto STEP_SIZE = CLICK(1); + constexpr auto WALL_MASK = BLOCK(1) - 1; + constexpr auto GRID_SNAP_SIZE = (int)BLOCK(1 / 8.0f); //} diff --git a/TombEngine/Math/Objects/AxisAngle.h b/TombEngine/Math/Objects/AxisAngle.h index 002d00cb5..ce1e922c8 100644 --- a/TombEngine/Math/Objects/AxisAngle.h +++ b/TombEngine/Math/Objects/AxisAngle.h @@ -7,7 +7,7 @@ class EulerAngles; class AxisAngle { private: - // Components + // Members Vector3 Axis = Vector3::Backward; short Angle = 0; diff --git a/TombEngine/Math/Objects/EulerAngles.h b/TombEngine/Math/Objects/EulerAngles.h index abadc3190..e888dbb4f 100644 --- a/TombEngine/Math/Objects/EulerAngles.h +++ b/TombEngine/Math/Objects/EulerAngles.h @@ -6,7 +6,7 @@ class EulerAngles { public: - // Components (CONVENTION: X = Pitch, Y = Yaw, Z = Roll) + // Members (CONVENTION: X = Pitch, Y = Yaw, Z = Roll) short x = 0; short y = 0; short z = 0; diff --git a/TombEngine/Math/Objects/GameBoundingBox.h b/TombEngine/Math/Objects/GameBoundingBox.h index d5bf4f4ec..f8f276457 100644 --- a/TombEngine/Math/Objects/GameBoundingBox.h +++ b/TombEngine/Math/Objects/GameBoundingBox.h @@ -11,7 +11,7 @@ struct ObjectInfo; class GameBoundingBox { public: - // Components + // Members int X1 = 0; int X2 = 0; int Y1 = 0; diff --git a/TombEngine/Math/Objects/GameVector.h b/TombEngine/Math/Objects/GameVector.h index 6913e71fd..0f5070965 100644 --- a/TombEngine/Math/Objects/GameVector.h +++ b/TombEngine/Math/Objects/GameVector.h @@ -7,7 +7,7 @@ class Vector3i; class GameVector { public: - // Components + // Members int x = 0; int y = 0; int z = 0; diff --git a/TombEngine/Math/Objects/Pose.h b/TombEngine/Math/Objects/Pose.h index 8c93bbc08..8584e56e2 100644 --- a/TombEngine/Math/Objects/Pose.h +++ b/TombEngine/Math/Objects/Pose.h @@ -7,7 +7,7 @@ class Pose { public: - // Components + // Members Vector3i Position = Vector3i::Zero; EulerAngles Orientation = EulerAngles::Zero; diff --git a/TombEngine/Math/Objects/Vector2i.h b/TombEngine/Math/Objects/Vector2i.h index f8f4ccba8..5d72b843b 100644 --- a/TombEngine/Math/Objects/Vector2i.h +++ b/TombEngine/Math/Objects/Vector2i.h @@ -5,7 +5,7 @@ namespace TEN::Math class Vector2i { public: - // Components + // Members int x = 0; int y = 0; diff --git a/TombEngine/Math/Objects/Vector3i.h b/TombEngine/Math/Objects/Vector3i.h index 20ba9c44c..4dbf89bcb 100644 --- a/TombEngine/Math/Objects/Vector3i.h +++ b/TombEngine/Math/Objects/Vector3i.h @@ -5,7 +5,7 @@ class Vector3i { public: - // Components + // Members int x = 0; int y = 0; int z = 0; diff --git a/TombEngine/Objects/Effects/tr5_electricity.cpp b/TombEngine/Objects/Effects/tr5_electricity.cpp index dac327018..3eb14a769 100644 --- a/TombEngine/Objects/Effects/tr5_electricity.cpp +++ b/TombEngine/Objects/Effects/tr5_electricity.cpp @@ -142,7 +142,7 @@ void ElectricityWiresControl(short itemNumber) SoundEffect(SFX_TR5_ELECTRIC_WIRES, &item->Pose); - GetCollidedObjects(item, SECTOR(4), true, CollidedItems, nullptr, 0) && CollidedItems[0]; + GetCollidedObjects(item, BLOCK(4), true, CollidedItems, nullptr, 0) && CollidedItems[0]; auto* object = &Objects[item->ObjectNumber]; diff --git a/TombEngine/Objects/Generic/Doors/double_doors.cpp b/TombEngine/Objects/Generic/Doors/double_doors.cpp index 1b1cbabdb..62d0da064 100644 --- a/TombEngine/Objects/Generic/Doors/double_doors.cpp +++ b/TombEngine/Objects/Generic/Doors/double_doors.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::Doors GameBoundingBox( -384, 384, 0, 0, - -SECTOR(1), SECTOR(0.5f) + -BLOCK(1), BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Doors/generic_doors.cpp b/TombEngine/Objects/Generic/Doors/generic_doors.cpp index 096f1a457..627daba91 100644 --- a/TombEngine/Objects/Generic/Doors/generic_doors.cpp +++ b/TombEngine/Objects/Generic/Doors/generic_doors.cpp @@ -32,9 +32,9 @@ namespace TEN::Entities::Doors const ObjectCollisionBounds CrowbarDoorBounds = { GameBoundingBox( - -SECTOR(0.5f), SECTOR(0.5f), - -SECTOR(1), 0, - 0, SECTOR(0.5f) + -BLOCK(0.5f), BLOCK(0.5f), + -BLOCK(1), 0, + 0, BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-80.0f), ANGLE(-80.0f), ANGLE(-80.0f)), @@ -67,13 +67,13 @@ namespace TEN::Entities::Doors int zOffset = 0; if (doorItem->Pose.Orientation.y == 0) - zOffset = -SECTOR(1); + zOffset = -BLOCK(1); else if (doorItem->Pose.Orientation.y == ANGLE(180.0f)) - zOffset = SECTOR(1); + zOffset = BLOCK(1); else if (doorItem->Pose.Orientation.y == ANGLE(90.0f)) - xOffset = -SECTOR(1); + xOffset = -BLOCK(1); else - xOffset = SECTOR(1); + xOffset = BLOCK(1); auto* r = &g_Level.Rooms[doorItem->RoomNumber]; doorData->d1.floor = GetSector(r, doorItem->Pose.Position.x - r->x + xOffset, doorItem->Pose.Position.z - r->z + zOffset); @@ -347,7 +347,7 @@ namespace TEN::Entities::Doors // TR5 lift doors /*if (!TriggerActive(item)) { - if (item->itemFlags[0] >= SECTOR(4)) + if (item->itemFlags[0] >= BLOCK(4)) { if (door->opened) { @@ -369,7 +369,7 @@ namespace TEN::Entities::Doors { if (item->itemFlags[0] > 0) { - if (item->itemFlags[0] == SECTOR(4)) + if (item->itemFlags[0] == BLOCK(4)) SoundEffect(SFX_TR5_LIFT_DOORS, &item->pos); item->itemFlags[0] -= STEP_SIZE; } diff --git a/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp b/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp index 7f07858c7..c40c01675 100644 --- a/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp +++ b/TombEngine/Objects/Generic/Doors/pushpull_kick_door.cpp @@ -41,7 +41,7 @@ namespace TEN::Entities::Doors GameBoundingBox( -384, 384, 0, 0, - -SECTOR(1), SECTOR(0.5f) + -BLOCK(1), BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Object/burning_torch.cpp b/TombEngine/Objects/Generic/Object/burning_torch.cpp index d0180af7b..2a8cb70c0 100644 --- a/TombEngine/Objects/Generic/Object/burning_torch.cpp +++ b/TombEngine/Objects/Generic/Object/burning_torch.cpp @@ -22,7 +22,7 @@ using namespace TEN::Input; namespace TEN::Entities::Generic { - void TriggerTorchFlame(char fxObject, char node) + void TriggerTorchFlame(int fxObject, unsigned char node) { auto* spark = GetFreeParticle(); @@ -53,6 +53,7 @@ namespace TEN::Entities::Generic spark->flags = SP_NODEATTACH | SP_EXPDEF | SP_ITEM | SP_ROTATE | SP_DEF | SP_SCALE; spark->rotAng = GetRandomControl() & 0xFFF; + spark->blendMode = BLEND_MODES::BLENDMODE_ADDITIVE; if (GetRandomControl() & 1) spark->rotAdd = -16 - (GetRandomControl() & 0xF); @@ -177,8 +178,8 @@ namespace TEN::Entities::Generic auto pos = GetJointPosition(laraItem, LM_LHAND, Vector3i(-32, 64, 256)); TriggerDynamicLight(pos.x, pos.y, pos.z, 12 - (GetRandomControl() & 1), (GetRandomControl() & 0x3F) + 192, (GetRandomControl() & 0x1F) + 96, 0); - if (!(Wibble & 7)) - TriggerTorchFlame(laraItem - g_Level.Items.data(), 0); + if (!(Wibble & 3)) + TriggerTorchFlame(laraItem->Index, 0); SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, (Pose*)&pos); } @@ -252,7 +253,7 @@ namespace TEN::Entities::Generic if (!Objects[CollidedItems[0]->ObjectNumber].intelligent && CollidedItems[0]->ObjectNumber != ID_LARA) { - ObjectCollision(CollidedItems[0] - g_Level.Items.data(), item, &LaraCollision); + ObjectCollision(CollidedItems[0]->Index, item, &LaraCollision); } } else if (CollidedMeshes[0]) diff --git a/TombEngine/Objects/Generic/Object/burning_torch.h b/TombEngine/Objects/Generic/Object/burning_torch.h index 431588a36..73d22eec7 100644 --- a/TombEngine/Objects/Generic/Object/burning_torch.h +++ b/TombEngine/Objects/Generic/Object/burning_torch.h @@ -6,7 +6,7 @@ struct ItemInfo; namespace TEN::Entities::Generic { - void TriggerTorchFlame(char fxObject, char node); + void TriggerTorchFlame(int fxObject, unsigned char node); void DoFlameTorch(); void GetFlameTorch(); void TorchControl(short itemNumber); diff --git a/TombEngine/Objects/Generic/Object/generic_bridge.h b/TombEngine/Objects/Generic/Object/generic_bridge.h index bd3fd1e10..e3b1b941c 100644 --- a/TombEngine/Objects/Generic/Object/generic_bridge.h +++ b/TombEngine/Objects/Generic/Object/generic_bridge.h @@ -17,7 +17,7 @@ std::optional BridgeFloor(short itemNumber, int x, int y, int z) if (bboxHeight.has_value() && tilt != 0) { - const auto height = item->Pose.Position.y + tilt * (GetOffset(item->Pose.Orientation.y, x, z) / 4 + SECTOR(1) / 8); + const auto height = item->Pose.Position.y + tilt * (GetOffset(item->Pose.Orientation.y, x, z) / 4 + BLOCK(1) / 8); return std::optional{ height }; } @@ -32,7 +32,7 @@ std::optional BridgeCeiling(short itemNumber, int x, int y, int z) if (bboxHeight.has_value() && tilt != 0) { - const auto height = item->Pose.Position.y + tilt * (GetOffset(item->Pose.Orientation.y, x, z) / 4 + SECTOR(1) / 8); + const auto height = item->Pose.Position.y + tilt * (GetOffset(item->Pose.Orientation.y, x, z) / 4 + BLOCK(1) / 8); return std::optional{ height + CLICK(1) }; // To be customized with Lua } return bboxHeight; diff --git a/TombEngine/Objects/Generic/Object/generic_trapdoor.cpp b/TombEngine/Objects/Generic/Object/generic_trapdoor.cpp index 73f836321..7010527b2 100644 --- a/TombEngine/Objects/Generic/Object/generic_trapdoor.cpp +++ b/TombEngine/Objects/Generic/Object/generic_trapdoor.cpp @@ -21,7 +21,7 @@ const ObjectCollisionBounds CeilingTrapDoorBounds = GameBoundingBox( -CLICK(1), CLICK(1), 0, 900, - -SECTOR(0.75f), -CLICK(1) + -BLOCK(0.75f), -CLICK(1) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), @@ -35,7 +35,7 @@ const ObjectCollisionBounds FloorTrapDoorBounds = GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - -SECTOR(1), -CLICK(1) + -BLOCK(1), -CLICK(1) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/cog_switch.cpp b/TombEngine/Objects/Generic/Switches/cog_switch.cpp index 338b4fb0a..933c75e6f 100644 --- a/TombEngine/Objects/Generic/Switches/cog_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/cog_switch.cpp @@ -20,9 +20,9 @@ namespace TEN::Entities::Switches const ObjectCollisionBounds CogSwitchBounds = { GameBoundingBox( - -SECTOR(0.5f), SECTOR(0.5f), + -BLOCK(0.5f), BLOCK(0.5f), 0, 0, - -SECTOR(1.5f), -SECTOR(0.5f) + -BLOCK(1.5f), -BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), @@ -100,7 +100,7 @@ namespace TEN::Entities::Switches { if (!door->opened) { - AddActiveItem((target - g_Level.Items.data())); + AddActiveItem(target->Index); target->Status = ITEM_ACTIVE; } } diff --git a/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp b/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp index 8ff901961..1380289af 100644 --- a/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/crowbar_switch.cpp @@ -23,7 +23,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - -SECTOR(0.5f), -CLICK(1) + -BLOCK(0.5f), -CLICK(1) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), @@ -37,7 +37,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - CLICK(1), SECTOR(0.5f) + CLICK(1), BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/fullblock_switch.cpp b/TombEngine/Objects/Generic/Switches/fullblock_switch.cpp index 89adc9631..7ec958ac2 100644 --- a/TombEngine/Objects/Generic/Switches/fullblock_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/fullblock_switch.cpp @@ -20,7 +20,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -384, 384, 0, CLICK(1), - 0, SECTOR(0.5f) + 0, BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/jump_switch.cpp b/TombEngine/Objects/Generic/Switches/jump_switch.cpp index 8c385760c..c7ba6b6cd 100644 --- a/TombEngine/Objects/Generic/Switches/jump_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/jump_switch.cpp @@ -18,7 +18,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(0.5f), CLICK(0.5f), -CLICK(1), CLICK(1), - CLICK(1.5f), SECTOR(0.5f) + CLICK(1.5f), BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/pulley_switch.cpp b/TombEngine/Objects/Generic/Switches/pulley_switch.cpp index 0acab5169..2943e21d3 100644 --- a/TombEngine/Objects/Generic/Switches/pulley_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/pulley_switch.cpp @@ -20,7 +20,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - -SECTOR(0.5f), SECTOR(0.5f) + -BLOCK(0.5f), BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/rail_switch.cpp b/TombEngine/Objects/Generic/Switches/rail_switch.cpp index e06afa5ce..d18d3ffce 100644 --- a/TombEngine/Objects/Generic/Switches/rail_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/rail_switch.cpp @@ -19,7 +19,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - -SECTOR(0.75f), -SECTOR(0.5f) + -BLOCK(0.75f), -BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), @@ -33,7 +33,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - SECTOR(0.5f), SECTOR(0.75f) + BLOCK(0.5f), BLOCK(0.75f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/turn_switch.cpp b/TombEngine/Objects/Generic/Switches/turn_switch.cpp index 66be48526..771ef9563 100644 --- a/TombEngine/Objects/Generic/Switches/turn_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/turn_switch.cpp @@ -30,9 +30,9 @@ namespace TEN::Entities::Switches const ObjectCollisionBounds TurnSwitchBoundsA = { GameBoundingBox( - SECTOR(0.5f), CLICK(3.5f), + BLOCK(0.5f), CLICK(3.5f), 0, 0, - -SECTOR(0.5f), 0 + -BLOCK(0.5f), 0 ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), @@ -42,9 +42,9 @@ namespace TEN::Entities::Switches const ObjectCollisionBounds TurnSwitchBoundsC = { GameBoundingBox( - SECTOR(0.5f), CLICK(3.5f), + BLOCK(0.5f), CLICK(3.5f), 0, 0, - 0, SECTOR(0.5f) + 0, BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/Generic/Switches/underwater_switch.cpp b/TombEngine/Objects/Generic/Switches/underwater_switch.cpp index 29b15e854..57ba52547 100644 --- a/TombEngine/Objects/Generic/Switches/underwater_switch.cpp +++ b/TombEngine/Objects/Generic/Switches/underwater_switch.cpp @@ -155,9 +155,9 @@ namespace TEN::Entities::Switches AddActiveItem(itemNumber); - ForcedFixedCamera.x = switchItem->Pose.Position.x - SECTOR(1) * phd_sin(switchItem->Pose.Orientation.y + ANGLE(90.0f)); - ForcedFixedCamera.y = switchItem->Pose.Position.y - SECTOR(1); - ForcedFixedCamera.z = switchItem->Pose.Position.z - SECTOR(1) * phd_cos(switchItem->Pose.Orientation.y + ANGLE(90.0f)); + ForcedFixedCamera.x = switchItem->Pose.Position.x - BLOCK(1) * phd_sin(switchItem->Pose.Orientation.y + ANGLE(90.0f)); + ForcedFixedCamera.y = switchItem->Pose.Position.y - BLOCK(1); + ForcedFixedCamera.z = switchItem->Pose.Position.z - BLOCK(1) * phd_cos(switchItem->Pose.Orientation.y + ANGLE(90.0f)); ForcedFixedCamera.RoomNumber = switchItem->RoomNumber; } } diff --git a/TombEngine/Objects/TR1/Entity/Kold.cpp b/TombEngine/Objects/TR1/Entity/Kold.cpp index 748b43285..29dfb733e 100644 --- a/TombEngine/Objects/TR1/Entity/Kold.cpp +++ b/TombEngine/Objects/TR1/Entity/Kold.cpp @@ -17,7 +17,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto KOLD_SHOTGUN_SHELL_COUNT = 6; - const auto KoldGunBite = CreatureBiteInfo(Vector3i(-20, 440, 20), 9); + const auto KoldGunBite = CreatureBiteInfo(Vector3(-20, 440, 20), 9); enum KoldState { diff --git a/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp b/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp index a4bbf665f..2e5548a6f 100644 --- a/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp +++ b/TombEngine/Objects/TR1/Entity/SkateboardKid.cpp @@ -16,8 +16,8 @@ namespace TEN::Entities::Creatures::TR1 // NOTES: // ItemFlags[0] = skateboard entity ID. - constexpr auto KID_IDLE_SHOT_DAMAGE = 50; - constexpr auto KID_SKATE_SHOT_DAMAGE = 40; + constexpr auto KID_IDLE_SHOT_DAMAGE = 30; + constexpr auto KID_SKATE_SHOT_DAMAGE = 20; constexpr auto KID_CLOSE_RANGE = SQUARE(BLOCK(1)); constexpr auto KID_SKATE_RANGE = SQUARE(BLOCK(2.5f)); @@ -27,8 +27,8 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto KID_TURN_RATE_MAX = ANGLE(4.0f); - const auto KidGunBiteRight = CreatureBiteInfo(Vector3i(0, 170, 34), 7); - const auto KidGunBiteLeft = CreatureBiteInfo(Vector3i(0, 170, 37), 4); + const auto KidGunBiteRight = CreatureBiteInfo(Vector3(0, 170, 34), 7); + const auto KidGunBiteLeft = CreatureBiteInfo(Vector3(0, 170, 37), 4); enum SkateKidState { @@ -71,7 +71,7 @@ namespace TEN::Entities::Creatures::TR1 skate.Pose.Orientation = item.Pose.Orientation; skate.StartPose = item.StartPose; skate.Model.Color = item.Model.Color; - skate.Collidable = true; + skate.RoomNumber = item.RoomNumber; InitializeItem(skateItemNumber); AddActiveItem(skateItemNumber); @@ -84,7 +84,6 @@ namespace TEN::Entities::Creatures::TR1 void InitializeSkateboardKid(short itemNumber) { auto& item = g_Level.Items[itemNumber]; - InitializeCreature(itemNumber); SpawnSkateboard(item); } @@ -113,21 +112,24 @@ namespace TEN::Entities::Creatures::TR1 { if (!CreatureActive(itemNumber)) return; - auto& item = g_Level.Items[itemNumber]; + if (item.ItemFlags[0] == NO_ITEM) + { + TENLog("Failed to do the skateboard kid control (itemNumber: " + std::to_string(itemNumber) + "), the skateboard itemNumber is missing, probably failed to be created !"); + return; + } auto& creature = *GetCreatureInfo(&item); auto& skateItem = g_Level.Items[item.ItemFlags[0]]; - - if (skateItem.Status & ITEM_INVISIBLE) - { - skateItem.Active = false; - skateItem.Status &= ~(ITEM_INVISIBLE); - } - short headingAngle = 0; auto extraHeadRot = EulerAngles::Zero; auto extraTorsoRot = EulerAngles::Zero; + if (skateItem.Status & ITEM_INVISIBLE) + { + skateItem.Active = true; + skateItem.Status &= ~(ITEM_INVISIBLE); + } + for (auto& flash : creature.MuzzleFlash) { if (flash.Delay != 0) @@ -216,9 +218,10 @@ namespace TEN::Entities::Creatures::TR1 } skateItem.Animation.AnimNumber = Objects[ID_SKATEBOARD].animIndex + (item.Animation.AnimNumber - Objects[ID_SKATEBOARD_KID].animIndex); - skateItem.Animation.FrameNumber = g_Level.Anims[item.Animation.AnimNumber].frameBase + (item.Animation.FrameNumber - g_Level.Anims[item.Animation.AnimNumber].frameBase); + skateItem.Animation.FrameNumber = GetAnimData(item).frameBase + (item.Animation.FrameNumber - GetAnimData(item).frameBase); skateItem.Pose.Position = item.Pose.Position; skateItem.Pose.Orientation = item.Pose.Orientation; + UpdateItemRoom(item.ItemFlags[0]); AnimateItem(&skateItem); CreatureJoint(&item, 0, extraHeadRot.y); diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 8f30e1905..9eb9876fd 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -35,7 +35,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto APE_RUN_TURN_RATE_MAX = ANGLE(5.0f); constexpr auto APE_DISPLAY_ANGLE = ANGLE(45.0f); - const auto ApeBite = CreatureBiteInfo(Vector3i(0, -19, 75), 15); + const auto ApeBite = CreatureBiteInfo(Vector3(0, -19, 75), 15); const auto ApeAttackJoints = std::vector{ 8, 9, 10, 11, 12, 13, 14, 15 }; enum ApeState @@ -103,8 +103,8 @@ namespace TEN::Entities::Creatures::TR1 creature->Flags &= ~APE_FLAG_TURN_RIGHT; } - int xx = item->Pose.Position.z / SECTOR(1); - int yy = item->Pose.Position.x / SECTOR(1); + int xx = item->Pose.Position.z / BLOCK(1); + int yy = item->Pose.Position.x / BLOCK(1); int y = item->Pose.Position.y; CreatureAnimation(itemNumber, angle, 0); @@ -112,8 +112,8 @@ namespace TEN::Entities::Creatures::TR1 if (item->Pose.Position.y > (y - CLICK(1.5f))) return; - int xFloor = item->Pose.Position.z / SECTOR(1); - int yFloor = item->Pose.Position.x / SECTOR(1); + int xFloor = item->Pose.Position.z / BLOCK(1); + int yFloor = item->Pose.Position.x / BLOCK(1); if (xx == xFloor) { if (yy == yFloor) @@ -121,12 +121,12 @@ namespace TEN::Entities::Creatures::TR1 if (yy < yFloor) { - item->Pose.Position.x = (yFloor * SECTOR(1)) - APE_SHIFT; + item->Pose.Position.x = (yFloor * BLOCK(1)) - APE_SHIFT; item->Pose.Orientation.y = ANGLE(90.0f); } else { - item->Pose.Position.x = (yy * SECTOR(1)) + APE_SHIFT; + item->Pose.Position.x = (yy * BLOCK(1)) + APE_SHIFT; item->Pose.Orientation.y = -ANGLE(90.0f); } } @@ -134,12 +134,12 @@ namespace TEN::Entities::Creatures::TR1 { if (xx < xFloor) { - item->Pose.Position.z = (xFloor * SECTOR(1)) - APE_SHIFT; + item->Pose.Position.z = (xFloor * BLOCK(1)) - APE_SHIFT; item->Pose.Orientation.y = 0; } else { - item->Pose.Position.z = (xx * SECTOR(1)) + APE_SHIFT; + item->Pose.Position.z = (xx * BLOCK(1)) + APE_SHIFT; item->Pose.Orientation.y = -ANGLE(180.0f); } } diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp index de0099cda..ea1714ba6 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp @@ -33,7 +33,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto BEAR_WALK_TURN_RATE_MAX = ANGLE(2.0f); constexpr auto BEAR_RUN_TURN_RATE_MAX = ANGLE(5.0f); - const auto BearBite = CreatureBiteInfo(Vector3i(0, 96, 335), 14); + const auto BearBite = CreatureBiteInfo(Vector3(0, 96, 335), 14); const auto BearAttackJoints = std::vector{ 2, 3, 5, 6, 14, 17 }; enum BearState diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp index cb3ae76ea..c29232faf 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp @@ -33,7 +33,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto BIG_RAT_RUN_TURN_RATE_MAX = ANGLE(6.0f); constexpr auto BIG_RAT_SWIM_TURN_RATE_MAX = ANGLE(3.0f); - const auto BigRatBite = CreatureBiteInfo(Vector3i(0, -11, 108), 3); + const auto BigRatBite = CreatureBiteInfo(Vector3(0, -11, 108), 3); enum BigRatState { diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp index 3694fa6db..85b10484f 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp @@ -150,7 +150,7 @@ namespace TEN::Entities::Creatures::TR1 if (item->Status == ITEM_DEACTIVATED) { SoundEffect(SFX_TR1_ATLANTEAN_DEATH, &item->Pose); - ExplodingDeath(itemNumber, BODY_EXPLODE); + ExplodingDeath(itemNumber, BODY_DO_EXPLOSION); KillItem(itemNumber); item->Status = ITEM_DEACTIVATED; } diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp index 29382cb7e..26cffbd02 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp @@ -13,22 +13,21 @@ namespace TEN::Entities::Creatures::TR1 { - ItemInfo* FindReference(ItemInfo* item, short objectNumber) + ItemInfo* FindDoppelgangerReference(const ItemInfo& item, int objectNumber) { for (int i = 0; i < g_Level.NumItems; i++) { - auto* currentItem = &g_Level.Items[i]; - if (currentItem->ObjectNumber == objectNumber && item->TriggerFlags == currentItem->TriggerFlags) - { - return currentItem; - } + auto& currentItem = g_Level.Items[i]; + if (currentItem.ObjectNumber == objectNumber && item.TriggerFlags == currentItem.TriggerFlags) + return ¤tItem; } + return nullptr; } - short GetWeaponDamage(LaraWeaponType weaponType) + int GetWeaponDamage(LaraWeaponType weaponType) { - return short(Weapons[(int)weaponType].Damage) * 10; + return (Weapons[(int)weaponType].Damage * 10); } void DoppelgangerControl(short itemNumber) @@ -36,85 +35,106 @@ namespace TEN::Entities::Creatures::TR1 if (!CreatureActive(itemNumber)) return; - auto* item = &g_Level.Items[itemNumber]; - if (item->HitPoints < LARA_HEALTH_MAX) + auto& item = g_Level.Items[itemNumber]; + if (item.HitPoints < LARA_HEALTH_MAX) { - item->HitPoints = LARA_HEALTH_MAX; + item.HitPoints = LARA_HEALTH_MAX; DoDamage(LaraItem, GetWeaponDamage(Lara.Control.Weapon.GunType)); } - auto* reference = FindReference(item, ID_BACON_REFERENCE); - if (reference == nullptr) + auto* referencePtr = FindDoppelgangerReference(item, ID_DOPPELGANGER_ORIGIN); + if (referencePtr == nullptr) { - TENLog("Doppelganger require ID_BACON_REFERENCE to be placed on the center (on floor) of the room to be used !", LogLevel::Warning); + TENLog("Doppelganger requires ID_DOPPELGANGER_ORIGIN to be placed in room center.", LogLevel::Warning); return; } - switch (item->ItemFlags[7]) + switch (item.ItemFlags[7]) { case 0: { int laraFloorHeight = GetCollision(LaraItem).Position.Floor; // Get floor heights for comparison. - Vector3i pos(2 * reference->Pose.Position.x - LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, 2 * reference->Pose.Position.z - LaraItem->Pose.Position.z); - item->Floor = GetCollision(pos.x, pos.y, pos.z, item->RoomNumber).Position.Floor; + auto pos = Vector3i( + (referencePtr->Pose.Position.x * 2) - LaraItem->Pose.Position.x, + LaraItem->Pose.Position.y, + (referencePtr->Pose.Position.z * 2) - LaraItem->Pose.Position.z); + item.Floor = GetCollision(pos.x, pos.y, pos.z, item.RoomNumber).Position.Floor; - // Animate bacon Lara, mirroring Lara's position. - item->Animation.AnimNumber = LaraItem->Animation.AnimNumber; - item->Animation.FrameNumber = LaraItem->Animation.FrameNumber; - item->Pose.Position = pos; - item->Pose.Orientation.x = LaraItem->Pose.Orientation.x; - item->Pose.Orientation.y = LaraItem->Pose.Orientation.y - ANGLE(180.0f); - item->Pose.Orientation.z = LaraItem->Pose.Orientation.z; - item->Animation.IsAirborne = LaraItem->Animation.IsAirborne; + // Animate doppelganger, mirroring player's position. + item.Animation.AnimNumber = LaraItem->Animation.AnimNumber; + item.Animation.FrameNumber = LaraItem->Animation.FrameNumber; + item.Pose.Position = pos; + item.Pose.Orientation.x = LaraItem->Pose.Orientation.x; + item.Pose.Orientation.y = LaraItem->Pose.Orientation.y - ANGLE(180.0f); + item.Pose.Orientation.z = LaraItem->Pose.Orientation.z; + item.Animation.IsAirborne = LaraItem->Animation.IsAirborne; // Compare floor heights. - if (item->Floor >= (laraFloorHeight + SECTOR(1) + 1) && !LaraItem->Animation.IsAirborne) + if (item.Floor >= (laraFloorHeight + BLOCK(1) + 1) && !LaraItem->Animation.IsAirborne) { SetAnimation(item, LA_FREEFALL); - item->Animation.IsAirborne = true; - item->Pose.Position.y += 64; - item->ItemFlags[7] = 1; + item.Animation.IsAirborne = true; + item.Pose.Position.y += 64; + item.ItemFlags[7] = 1; } + break; } case 1: - if (item->Animation.Velocity.x > 0.0f) - item->Animation.Velocity.x -= 2; - else if (item->Animation.Velocity.x < 0.0f) - item->Animation.Velocity.x += 2; - else - item->Animation.Velocity.x = 0.0f; - - if (item->Animation.Velocity.z > 0.0f) - item->Animation.Velocity.z -= 2; - else if (item->Animation.Velocity.z < 0.0f) - item->Animation.Velocity.z += 2; - else - item->Animation.Velocity.z = 0.0f; - - TestTriggers(item, true); - item->Floor = GetCollision(item).Position.Floor; - if (item->Pose.Position.y >= item->Floor) + if (item.Animation.Velocity.x > 0.0f) { - item->Pose.Position.y = item->Floor; - TestTriggers(item, true); - SetAnimation(item, LA_FREEFALL_DEATH); - item->Animation.IsAirborne = false; - item->Animation.Velocity.y = 0.0f; - if (item->Animation.FrameNumber >= GetFrameCount(LA_FREEFALL_DEATH)-1) - item->ItemFlags[7] = 2; + item.Animation.Velocity.x -= 2; } + else if (item.Animation.Velocity.x < 0.0f) + { + item.Animation.Velocity.x += 2; + } + else + { + item.Animation.Velocity.x = 0.0f; + } + + if (item.Animation.Velocity.z > 0.0f) + { + item.Animation.Velocity.z -= 2; + } + else if (item.Animation.Velocity.z < 0.0f) + { + item.Animation.Velocity.z += 2; + } + else + { + item.Animation.Velocity.z = 0.0f; + } + + TestTriggers(&item, true); + item.Floor = GetCollision(&item).Position.Floor; + + if (item.Pose.Position.y >= item.Floor) + { + item.Pose.Position.y = item.Floor; + TestTriggers(&item, true); + + SetAnimation(item, LA_FREEFALL_DEATH); + item.Animation.IsAirborne = false; + item.Animation.Velocity.y = 0.0f; + + if (item.Animation.FrameNumber >= GetFrameCount(LA_FREEFALL_DEATH) - 1) + item.ItemFlags[7] = 2; + } + break; + case 2: DisableEntityAI(itemNumber); RemoveActiveItem(itemNumber); - item->Collidable = FALSE; + item.Collidable = false; break; } - ItemNewRoom(itemNumber, GetCollision(item).RoomNumber); - AnimateItem(item); + ItemNewRoom(itemNumber, GetCollision(&item).RoomNumber); + AnimateItem(&item); } } diff --git a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp index 5871ee9e8..16c8f5ece 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp @@ -228,12 +228,14 @@ namespace TEN::Entities::Creatures::TR1 } } else + { CreatureAnimation(itemNumber, 0, 0); + } if (item->Status == ITEM_DEACTIVATED) { SoundEffect(SFX_TR1_ATLANTEAN_DEATH, &item->Pose); - ExplodingDeath(itemNumber, BODY_EXPLODE); + ExplodingDeath(itemNumber, BODY_DO_EXPLOSION); TestTriggers(item, true); diff --git a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp index e0bf98e6f..0fcbc0d3d 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp @@ -8,32 +8,31 @@ #include "Game/misc.h" #include "Game/missile.h" #include "Game/people.h" +#include "Game/Setup.h" #include "Math/Math.h" #include "Specific/clock.h" -#include "Sound/sound.h" -#include "Specific/clock.h" #include "Specific/level.h" +#include "Sound/sound.h" using namespace TEN::Math; namespace TEN::Entities::Creatures::TR1 { // TODO: Organise. - constexpr auto NATLA_SHOT_DAMAGE = 100; - constexpr auto NATLA_NEAR_DEATH = 200; - constexpr auto NATLA_DEATH_TIME = FPS * 16; // 16 seconds. - constexpr auto NATLA_FLYMODE = 0x8000; - constexpr auto NATLA_TIMER = 0x7FFF; + constexpr auto NATLA_SHOT_DAMAGE = 100; + constexpr auto NATLA_DEATH_TIME = 16 * FPS; // 16 seconds. + constexpr auto NATLA_FLY_MODE = 0x8000; + constexpr auto NATLA_TIMER = 0x7FFF; constexpr auto NATLA_GUN_VELOCITY = 400; constexpr auto NATLA_LAND_CHANCE = 1 / 128.0f; constexpr auto NATLA_TURN_NEAR_DEATH_SPEED = ANGLE(6.0f); - constexpr auto NATLA_TURN_SPEED = ANGLE(5.0f); - constexpr auto NATLA_FLY_ANGLE_SPEED = ANGLE(5.0f); - constexpr auto NATLA_SHOOT_ANGLE = ANGLE(30.0f); + constexpr auto NATLA_TURN_SPEED = ANGLE(5.0f); + constexpr auto NATLA_FLY_ANGLE_SPEED = ANGLE(5.0f); + constexpr auto NATLA_SHOOT_ANGLE = ANGLE(30.0f); - const auto NatlaGunBite = CreatureBiteInfo(Vector3i(5, 220, 7), 4); + const auto NatlaGunBite = CreatureBiteInfo(Vector3(5, 220, 7), 4); enum NatlaState { @@ -46,7 +45,8 @@ namespace TEN::Entities::Creatures::TR1 NATLA_STATE_SHOOT, NATLA_STATE_FALL, NATLA_STATE_STAND, - NATLA_STATE_DEATH + NATLA_STATE_DEATH, + NATLA_STATE_SHOOT_2, // After first phase when cannot fly anymore. }; void NatlaControl(short itemNumber) @@ -57,53 +57,61 @@ namespace TEN::Entities::Creatures::TR1 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; - short tilt = 0; - short angle = 0; - short facing = 0; - short gun = creature->JointRotation[0] * 7 / 8; + short headingAngle = 0; + short tiltAngle = 0; + auto extraHeadRot = EulerAngles::Zero; + auto extraTorsoRot = EulerAngles::Zero; - int shoot; - short timer = creature->Flags & NATLA_TIMER; + AI_INFO ai; + int timer = creature->Flags & NATLA_TIMER; + bool shoot = false; - AI_INFO AI; - - if (item->HitPoints <= 0 && item->HitPoints != NOT_TARGETABLE) + if (item->HitPoints <= 0 && item->ItemFlags[1] != 0) + { item->Animation.TargetState = NATLA_STATE_DEATH; - else if (item->HitPoints <= NATLA_NEAR_DEATH) + } + else if (item->HitPoints <= (Objects[item->ObjectNumber].HitPoints / 2)) { creature->LOT.Step = CLICK(1); creature->LOT.Drop = -CLICK(1); creature->LOT.Fly = NO_FLYING; - CreatureAIInfo(item, &AI); + creature->LOT.Zone = ZoneType::Basic; + CreatureAIInfo(item, &ai); - if (AI.ahead) - head = AI.angle; - - GetCreatureMood(item, &AI, true); - CreatureMood(item, &AI, true); - - angle = CreatureTurn(item, NATLA_TURN_NEAR_DEATH_SPEED); - shoot = (AI.angle > -NATLA_SHOOT_ANGLE && AI.angle < NATLA_SHOOT_ANGLE&& Targetable(item, &AI)); - - if (facing) + // NOTE: Only rotate joints if alive. + if (ai.ahead && item->ItemFlags[1] == 1) { - item->Pose.Orientation.y += facing; - facing = 0; + extraHeadRot.x = ai.xAngle / 2; + extraHeadRot.y = ai.angle / 2; + extraTorsoRot.x = ai.xAngle / 2; + extraTorsoRot.y = ai.angle / 2; + } + + GetCreatureMood(item, &ai, true); + CreatureMood(item, &ai, true); + + headingAngle = CreatureTurn(item, creature->MaxTurn); + + if (item->ItemFlags[0] != 0) + { + item->Pose.Orientation.y += item->ItemFlags[0]; + item->ItemFlags[0] = 0; } switch (item->Animation.ActiveState) { case NATLA_STATE_FALL: + creature->MaxTurn = 0; + if (item->Pose.Position.y < item->Floor) { item->Animation.IsAirborne = true; item->Animation.Velocity.z = 0; } - else + else if (item->Pose.Position.y >= item->Floor) { item->Animation.TargetState = NATLA_STATE_SEMI_DEATH; - item->Animation.IsAirborne = 0; + item->Animation.IsAirborne = false; item->Pose.Position.y = item->Floor; timer = 0; } @@ -111,60 +119,68 @@ namespace TEN::Entities::Creatures::TR1 break; case NATLA_STATE_STAND: - if (!shoot) + creature->MaxTurn = NATLA_TURN_NEAR_DEATH_SPEED; + + if (Targetable(item, &ai)) + { + item->Animation.TargetState = NATLA_STATE_SHOOT_2; + } + else + { item->Animation.TargetState = NATLA_STATE_RUN; + } + + break; + + case NATLA_STATE_SHOOT_2: + creature->MaxTurn = 0; if (timer >= 20) { - short FXNumber = CreatureEffect(item, NatlaGunBite, ShardGun); - if (FXNumber != NO_ITEM) - { - auto* fx = &EffectList[FXNumber]; - gun = fx->pos.Orientation.x; - SoundEffect(SFX_TR1_ATLANTEAN_BALL, &fx->pos); - } - timer = 0; + CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle, ShardGun); + SoundEffect(SFX_TR1_ATLANTEAN_NEEDLE, &item->Pose); } break; case NATLA_STATE_RUN: - tilt = angle; + creature->MaxTurn = NATLA_TURN_NEAR_DEATH_SPEED; + tiltAngle = headingAngle; - if (timer >= 20) + if (timer >= 20 && Targetable(item, &ai)) { - short FXNumber = CreatureEffect(item, NatlaGunBite, ShardGun); - if (FXNumber != NO_ITEM) - { - auto* fx = &EffectList[FXNumber]; - gun = fx->pos.Orientation.x; - SoundEffect(SFX_TR1_ATLANTEAN_BALL, &fx->pos); - } - + CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle, ShardGun); + SoundEffect(SFX_TR1_ATLANTEAN_NEEDLE, &item->Pose); timer = 0; } - if (shoot) + if (Targetable(item, &ai)) item->Animation.TargetState = NATLA_STATE_STAND; break; case NATLA_STATE_SEMI_DEATH: + creature->MaxTurn = 0; + if (timer == NATLA_DEATH_TIME) { item->Animation.TargetState = NATLA_STATE_STAND; + item->HitPoints = Objects[item->ObjectNumber].HitPoints / 2; + item->ItemFlags[1] = 1; creature->Flags = 0; timer = 0; - item->HitPoints = NATLA_NEAR_DEATH; } else + { item->HitPoints = NOT_TARGETABLE; + } break; case NATLA_STATE_FLY: item->Animation.TargetState = NATLA_STATE_FALL; + creature->MaxTurn = 0; timer = 0; break; @@ -173,6 +189,7 @@ namespace TEN::Entities::Creatures::TR1 case NATLA_STATE_AIM: item->Animation.TargetState = NATLA_STATE_SEMI_DEATH; item->Flags = 0; + creature->MaxTurn = 0; timer = 0; break; } @@ -182,108 +199,132 @@ namespace TEN::Entities::Creatures::TR1 creature->LOT.Step = CLICK(1); creature->LOT.Drop = -CLICK(1); creature->LOT.Fly = NO_FLYING; - CreatureAIInfo(item, &AI); + creature->LOT.Zone = ZoneType::Basic; + CreatureAIInfo(item, &ai); - shoot = (AI.angle > -NATLA_SHOOT_ANGLE && AI.angle < NATLA_SHOOT_ANGLE&& Targetable(item, &AI)); + shoot = (ai.angle > -NATLA_SHOOT_ANGLE && ai.angle < NATLA_SHOOT_ANGLE) && Targetable(item, &ai); - if (item->Animation.ActiveState == NATLA_STATE_FLY && (creature->Flags & NATLA_FLYMODE)) + if (item->Animation.ActiveState == NATLA_STATE_FLY && (creature->Flags & NATLA_FLY_MODE)) { - if (creature->Flags & NATLA_FLYMODE && shoot && Random::TestProbability(NATLA_LAND_CHANCE)) - creature->Flags -= NATLA_FLYMODE; + if (shoot && Random::TestProbability(NATLA_LAND_CHANCE)) + creature->Flags &= ~NATLA_FLY_MODE; - if (!(creature->Flags & NATLA_FLYMODE)) - CreatureMood(item, &AI, true); + if (!(creature->Flags & NATLA_FLY_MODE)) + { + GetCreatureMood(item, &ai, true); + CreatureMood(item, &ai, true); + } - creature->LOT.Step = SECTOR(20); - creature->LOT.Drop = -SECTOR(20); - creature->LOT.Fly = CLICK(0.25f) / 2; - - CreatureAIInfo(item, &AI); + creature->LOT.Step = BLOCK(20); + creature->LOT.Drop = -BLOCK(20); + creature->LOT.Fly = 16; + creature->LOT.Zone = ZoneType::Flyer; + CreatureAIInfo(item, &ai); } else if (!shoot) - creature->Flags |= NATLA_FLYMODE; + { + creature->Flags |= NATLA_FLY_MODE; + } - if (AI.ahead) - head = AI.angle; + if (ai.ahead) + { + extraHeadRot.x = ai.xAngle / 2; + extraHeadRot.y = ai.angle / 2; + extraTorsoRot.x = ai.xAngle / 2; + extraTorsoRot.y = ai.angle / 2; + } - if (item->Animation.ActiveState != NATLA_STATE_FLY || (creature->Flags & NATLA_FLYMODE)) - CreatureMood(item, &AI, false); + if (item->Animation.ActiveState != NATLA_STATE_FLY || (creature->Flags & NATLA_FLY_MODE)) + { + GetCreatureMood(item, &ai, false); + CreatureMood(item, &ai, false); + } - item->Pose.Orientation.y -= facing; - angle = CreatureTurn(item, NATLA_TURN_SPEED); + item->Pose.Orientation.y -= item->ItemFlags[0]; + headingAngle = CreatureTurn(item, creature->MaxTurn); if (item->Animation.ActiveState == NATLA_STATE_FLY) { - if (AI.angle > NATLA_FLY_ANGLE_SPEED) - facing += NATLA_FLY_ANGLE_SPEED; - else if (AI.angle < -NATLA_FLY_ANGLE_SPEED) - facing -= NATLA_FLY_ANGLE_SPEED; + if (ai.angle > NATLA_FLY_ANGLE_SPEED) + { + item->ItemFlags[0] += NATLA_FLY_ANGLE_SPEED; + } + else if (ai.angle < -NATLA_FLY_ANGLE_SPEED) + { + item->ItemFlags[0] -= NATLA_FLY_ANGLE_SPEED; + } else - facing += AI.angle; + { + item->ItemFlags[0] += ai.angle; + } - item->Pose.Orientation.y += facing; + item->Pose.Orientation.y += item->ItemFlags[0]; } else { - item->Pose.Orientation.y += facing - angle; - facing = 0; + item->Pose.Orientation.y += item->ItemFlags[0] - headingAngle; + item->ItemFlags[0] = 0; } switch (item->Animation.ActiveState) { case NATLA_STATE_IDLE: + creature->MaxTurn = NATLA_TURN_SPEED; timer = 0; - if (creature->Flags & NATLA_FLYMODE) + if (creature->Flags & NATLA_FLY_MODE) + { item->Animation.TargetState = NATLA_STATE_FLY; + } else + { item->Animation.TargetState = NATLA_STATE_AIM; + } break; case NATLA_STATE_FLY: - if (!(creature->Flags & NATLA_FLYMODE) && item->Pose.Position.y == item->Floor) + creature->MaxTurn = NATLA_FLY_ANGLE_SPEED; + + if (!(creature->Flags & NATLA_FLY_MODE) && item->Pose.Position.y == item->Floor) item->Animation.TargetState = NATLA_STATE_IDLE; - if (timer >= 30) + if (timer >= 30 && ai.ahead) { - short FXNumber = CreatureEffect(item, NatlaGunBite, BombGun); - if (FXNumber != NO_ITEM) - { - auto* fx = &EffectList[FXNumber]; - gun = fx->pos.Orientation.x; - SoundEffect(SFX_TR1_ATLANTEAN_WINGS, &fx->pos); - } - timer = 0; + CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle, BombGun); + SoundEffect(SFX_TR1_ATLANTEAN_BALL, &item->Pose); } break; case NATLA_STATE_AIM: + creature->MaxTurn = NATLA_FLY_ANGLE_SPEED; + if (item->Animation.RequiredState != NO_STATE) + { item->Animation.TargetState = item->Animation.RequiredState; + } else if (shoot) + { item->Animation.TargetState = NATLA_STATE_SHOOT; + } else + { item->Animation.TargetState = NATLA_STATE_IDLE; + } break; case NATLA_STATE_SHOOT: - if (item->Animation.RequiredState == NO_STATE) + creature->MaxTurn = NATLA_FLY_ANGLE_SPEED; + + if (item->Animation.RequiredState == NO_STATE && ai.ahead) { - short FXNumber = CreatureEffect(item, NatlaGunBite, BombGun); - if (FXNumber != NO_ITEM) - gun = EffectList[FXNumber].pos.Orientation.x; - - FXNumber = CreatureEffect(item, NatlaGunBite, BombGun); - if (FXNumber != NO_ITEM) - EffectList[FXNumber].pos.Orientation.y += (short)((GetRandomControl() - 0x4000) / 4); - - FXNumber = CreatureEffect(item, NatlaGunBite, BombGun); - if (FXNumber != NO_ITEM) - EffectList[FXNumber].pos.Orientation.y += (short)((GetRandomControl() - 0x4000) / 4); + CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle, BombGun); + CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle + (GetRandomControl() - ANGLE(45.0f)) / 4, BombGun); + CreatureEffect2(item, NatlaGunBite, NATLA_GUN_VELOCITY, ai.angle + (GetRandomControl() - ANGLE(45.0f)) / 4, BombGun); + SoundEffect(SFX_TR1_ATLANTEAN_BALL, &item->Pose); item->Animation.RequiredState = NATLA_STATE_IDLE; } @@ -292,17 +333,22 @@ namespace TEN::Entities::Creatures::TR1 } } - CreatureTilt(item, tilt); - CreatureJoint(item, 0, -head); - - if (gun) - CreatureJoint(item, 0, gun); + CreatureTilt(item, tiltAngle); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); + CreatureJoint(item, 2, extraHeadRot.y); + CreatureJoint(item, 3, extraHeadRot.x); timer++; - creature->Flags = (creature->Flags & NATLA_FLYMODE) + timer; + creature->Flags &= ~NATLA_TIMER; + creature->Flags |= timer & NATLA_TIMER; - item->Pose.Orientation.y -= facing; - CreatureAnimation(itemNumber, angle, tilt); - item->Pose.Orientation.y += facing; + if (item->ItemFlags[1] == 0) + item->Pose.Orientation.y -= item->ItemFlags[0]; + + CreatureAnimation(itemNumber, headingAngle, 0); + + if (item->ItemFlags[1] == 0) + item->Pose.Orientation.y += item->ItemFlags[0]; } } diff --git a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp index 8e626ce08..cc6c852e3 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp @@ -20,29 +20,33 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR1 { constexpr auto WINGED_MUTANT_IDLE_JUMP_ATTACK_DAMAGE = 150; - constexpr auto WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE = 100; - constexpr auto WINGED_MUTANT_SWIPE_ATTACK_DAMAGE = 200; + constexpr auto WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE = 100; + constexpr auto WINGED_MUTANT_SWIPE_ATTACK_DAMAGE = 200; - constexpr auto WINGED_MUTANT_WALK_RANGE = SQUARE(BLOCK(4.5f)); - constexpr auto WINGED_MUTANT_SWIPE_ATTACK_RANGE = SQUARE(CLICK(1.17f)); - constexpr auto WINGED_MUTANT_RUN_JUMP_ATTACK_RANGE = SQUARE(CLICK(2.34f)); - constexpr auto WINGED_MUTANT_IDLE_JUMP_ATTACK_RANGE = SQUARE(BLOCK(2.5f)); - constexpr auto WINGED_MUTANT_ATTACK_RANGE = SQUARE(BLOCK(3.75f)); + constexpr auto WINGED_MUTANT_WALK_RANGE = SQUARE(BLOCK(4.5f)); + constexpr auto WINGED_MUTANT_SWIPE_ATTACK_RANGE = SQUARE(BLOCK(0.3f)); + constexpr auto WINGED_MUTANT_RUN_JUMP_ATTACK_RANGE = SQUARE(BLOCK(0.65f)); + constexpr auto WINGED_MUTANT_IDLE_JUMP_ATTACK_RANGE = SQUARE(BLOCK(2.5f)); + constexpr auto WINGED_MUTANT_PROJECTILE_ATTACK_RANGE = SQUARE(BLOCK(3.0f)); + constexpr auto WINGED_MUTANT_POSE_RANGE = SQUARE(BLOCK(4.5f)); constexpr auto WINGED_MUTANT_POSE_CHANCE = 1 / 400.0f; constexpr auto WINGED_MUTANT_UNPOSE_CHANCE = 1 / 164.0f; - constexpr auto WINGED_MUTANT_FLY_VELOCITY = CLICK(1 / 8.0f); + constexpr auto WINGED_MUTANT_FLY_VELOCITY = BLOCK(1 / 32.0f); constexpr auto WINGED_MUTANT_SHARD_VELOCITY = 250; - constexpr auto WINGED_MUTANT_BOMB_VELOCITY = 220; + constexpr auto WINGED_MUTANT_BOMB_VELOCITY = 220; - constexpr auto WINGED_MUTANT_WALK_FORWARD_TURN_RATE_MAX = ANGLE(2.0f); - constexpr auto WINGED_MUTANT_RUN_FORWARD_TURN_RATE_MAX = ANGLE(6.0f); + constexpr auto WINGED_MUTANT_WALK_TURN_RATE_MAX = ANGLE(2.0f); + constexpr auto WINGED_MUTANT_RUN_TURN_RATE_MAX = ANGLE(6.0f); - const auto WingedMutantBite = CreatureBiteInfo(Vector3i(-27, 98, 0), 10); - const auto WingedMutantRocketBite = CreatureBiteInfo(Vector3i(51, 213, 0), 14); - const auto WingedMutantShardBite = CreatureBiteInfo(Vector3i(-35, 269, 0), 9); - const auto WingedMutantJoints = std::vector{ 9, 10, 14 }; + const auto WingedMutantBiteLeftHand = CreatureBiteInfo(Vector3(0, 0, 0), 7); + const auto WingedMutantBiteRightHand = CreatureBiteInfo(Vector3(0, 0, 0), 10); + const auto WingedMutantRocketBite = CreatureBiteInfo(Vector3(0, 200, 20), 6); + const auto WingedMutantShardBite = CreatureBiteInfo(Vector3(0, 200, 20), 9); + const auto WingedMutantHeadJoints = std::vector{ 3 }; + const auto WingedMutantHandsJoints = std::vector{ 7, 10 }; + const auto WingedMutantWingsJoints = std::vector{ 15, 16, 17, 18, 19, 20 }; enum WingedMutantState { @@ -127,7 +131,7 @@ namespace TEN::Entities::Creatures::TR1 WMUTANT_CONF_DISABLE_BOMB_WEAPON }; - void SwitchPathfinding(CreatureInfo* creature, WingedMutantPathFinding path) + static void SwitchPathfinding(CreatureInfo* creature, WingedMutantPathFinding path) { switch (path) { @@ -135,27 +139,30 @@ namespace TEN::Entities::Creatures::TR1 creature->LOT.Step = CLICK(1); creature->LOT.Drop = -CLICK(1); creature->LOT.Fly = NO_FLYING; + creature->LOT.Zone = ZoneType::Basic; break; case WMUTANT_PATH_AERIAL: - creature->LOT.Step = SECTOR(30); - creature->LOT.Drop = -SECTOR(30); - creature->LOT.Fly = (int)round(WINGED_MUTANT_FLY_VELOCITY); + creature->LOT.Step = BLOCK(20); + creature->LOT.Drop = -BLOCK(20); + creature->LOT.Fly = WINGED_MUTANT_FLY_VELOCITY; + creature->LOT.Zone = ZoneType::Flyer; break; } } - WingedMutantProjectileType CanTargetLara(ItemInfo* item, CreatureInfo* creature, AI_INFO* AI) + static WingedMutantProjectileType CanTargetLara(ItemInfo* item, CreatureInfo* creature, AI_INFO* AI) { - if (Targetable(item, AI) && (AI->zoneNumber != AI->enemyZone || AI->distance > WINGED_MUTANT_ATTACK_RANGE)) + if (Targetable(item, AI) && + (AI->zoneNumber != AI->enemyZone || AI->distance > WINGED_MUTANT_PROJECTILE_ATTACK_RANGE)) { if ((AI->angle > 0 && AI->angle < ANGLE(45.0f)) && - item->TestFlagField(WMUTANT_OCB_DISABLE_DART_WEAPON, false)) + item->TestFlagField(WMUTANT_CONF_DISABLE_DART_WEAPON, false)) { return WMUTANT_PROJ_DART; } else if ((AI->angle < 0 && AI->angle > -ANGLE(45.0f)) && - item->TestFlagField(WMUTANT_OCB_DISABLE_BOMB_WEAPON, false)) + item->TestFlagField(WMUTANT_CONF_DISABLE_BOMB_WEAPON, false)) { return WMUTANT_PROJ_BOMB; } @@ -165,7 +172,7 @@ namespace TEN::Entities::Creatures::TR1 return WMUTANT_PROJ_NONE; } - void WingedInitOCB(ItemInfo* item, CreatureInfo* creature) + static void WingedInitOCB(ItemInfo* item, CreatureInfo* creature) { if (item->TestOcb(WMUTANT_OCB_START_AERIAL)) { @@ -186,16 +193,17 @@ namespace TEN::Entities::Creatures::TR1 item->SetFlagField(WMUTANT_CONF_PATHFINDING_MODE, WMUTANT_PATH_GROUND); } - // Remove OCBs since we don't need them anymore. + // Remove unnecessary OCBs. if (item->TestOcb(WMUTANT_OCB_START_AERIAL)) item->RemoveOcb(WMUTANT_OCB_START_AERIAL); + if (item->TestOcb(WMUTANT_OCB_START_INACTIVE)) item->RemoveOcb(WMUTANT_OCB_START_INACTIVE); + if (item->TestOcb(WMUTANT_OCB_START_POSE)) item->RemoveOcb(WMUTANT_OCB_START_POSE); } - // NOTE: Doesn't exist in the original game. -- TokyoSU 5/8/2022 void InitializeWingedMutant(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; @@ -207,13 +215,16 @@ namespace TEN::Entities::Creatures::TR1 if (item->TestOcb(WMUTANT_OCB_NO_WINGS)) { item->SetFlagField(WMUTANT_CONF_CAN_FLY, false); - item->MeshBits = 0xFFE07FFF; + item->MeshBits.Clear(WingedMutantWingsJoints); } else + { item->SetFlagField(WMUTANT_CONF_CAN_FLY, true); + } if (item->TestOcb(WMUTANT_OCB_DISABLE_BOMB_WEAPON)) item->SetFlagField(WMUTANT_CONF_DISABLE_BOMB_WEAPON, true); + if (item->TestOcb(WMUTANT_OCB_DISABLE_DART_WEAPON)) item->SetFlagField(WMUTANT_CONF_DISABLE_DART_WEAPON, true); @@ -246,130 +257,156 @@ namespace TEN::Entities::Creatures::TR1 if (item->HitPoints <= 0) { - CreatureDie(itemNumber, true); + CreatureDie(itemNumber, true, BODY_DO_EXPLOSION | BODY_PART_EXPLODE | BODY_NO_SMOKE | BODY_NO_SHATTER_EFFECT); + + auto pos = item->Pose; + pos.Position.y -= CLICK(3); + TriggerExplosionSparks(pos.Position.x, pos.Position.y, pos.Position.z, 3, -2, 0, item->RoomNumber); + TriggerExplosionSparks(pos.Position.x, pos.Position.y, pos.Position.z, 3, -1, 0, item->RoomNumber); + TriggerShockwave(&pos, 48, 304, (GetRandomControl() & 0x1F) + 112, 128, 32, 32, 32, EulerAngles(2048, 0.0f, 0.0f), 0, true, false, (int)ShockwaveStyle::Normal); + SoundEffect(SFX_TR1_ATLANTEAN_EXPLODE, &item->Pose); return; } else { - AI_INFO AI; + AI_INFO ai; SwitchPathfinding(creature, WMUTANT_PATH_GROUND); - CreatureAIInfo(item, &AI); + CreatureAIInfo(item, &ai); - if (AI.ahead) - head = AI.angle; + bool isSameZoneInGroundMode = (ai.zoneNumber == ai.enemyZone); + auto projectileType = CanTargetLara(item, creature, &ai); + + if (flyEnabled && item->Animation.ActiveState == WMUTANT_STATE_FLY) + { + SwitchPathfinding(creature, WMUTANT_PATH_AERIAL); + CreatureAIInfo(item, &ai); + } + + if (ai.ahead) + { + head = ai.angle; + } else { head = 0; torso = 0; } - GetCreatureMood(item, &AI, flyStatus); - CreatureMood(item, &AI, flyStatus); + GetCreatureMood(item, &ai, flyStatus); + CreatureMood(item, &ai, flyStatus); angle = CreatureTurn(item, creature->MaxTurn); - auto shootType = CanTargetLara(item, creature, &AI); - if (flyEnabled) - { - if (item->Animation.ActiveState == WMUTANT_STATE_FLY) - { - if (flyStatus && creature->Mood != MoodType::Escape && - AI.zoneNumber == AI.enemyZone) - { - item->SetFlagField(WMUTANT_CONF_PATHFINDING_MODE, WMUTANT_PATH_GROUND); - } - - SwitchPathfinding(creature, WMUTANT_PATH_AERIAL); - CreatureAIInfo(item, &AI); - } - else if ((AI.zoneNumber != AI.enemyZone && - !flyStatus && shootType == WMUTANT_PROJ_NONE && - (!AI.ahead || creature->Mood == MoodType::Bored)) || - creature->Mood == MoodType::Escape) - { - item->SetFlagField(WMUTANT_CONF_PATHFINDING_MODE, WMUTANT_PATH_AERIAL); - } - } - switch (item->Animation.ActiveState) { case WMUTANT_STATE_INACTIVE: creature->MaxTurn = 0; + creature->Flags = 0; - if (TargetVisible(item, &AI) || creature->HurtByLara) + if (TargetVisible(item, &ai) || creature->HurtByLara) item->Animation.TargetState = WMUTANT_STATE_IDLE; break; case WMUTANT_STATE_IDLE: - torso = 0; - creature->MaxTurn = 0; item->SetFlagField(WMUTANT_CONF_PATHFINDING_MODE, WMUTANT_PROJ_NONE); + creature->MaxTurn = 0; + creature->Flags = 0; + torso = 0; - if (flyStatus && flyEnabled) + if (flyEnabled && !isSameZoneInGroundMode) + { item->Animation.TargetState = WMUTANT_STATE_FLY; - else if (item->TouchBits.Test(WingedMutantJoints[1])) + item->SetFlagField(WMUTANT_CONF_PATHFINDING_MODE, WMUTANT_PATH_AERIAL); + } + else if (item->TouchBits.Test(WingedMutantHeadJoints)) + { item->Animation.TargetState = WMUTANT_STATE_SWIPE_ATTACK; - else if (AI.bite && AI.distance < WINGED_MUTANT_IDLE_JUMP_ATTACK_RANGE) + } + else if (ai.bite && ai.distance < WINGED_MUTANT_IDLE_JUMP_ATTACK_RANGE) + { item->Animation.TargetState = WMUTANT_STATE_IDLE_JUMP_ATTACK; - else if (AI.bite && AI.distance < WINGED_MUTANT_SWIPE_ATTACK_RANGE) + } + else if (ai.bite && ai.distance < WINGED_MUTANT_SWIPE_ATTACK_RANGE) + { item->Animation.TargetState = WMUTANT_STATE_SWIPE_ATTACK; - else if (shootType == WMUTANT_PROJ_DART) + } + else if (projectileType == WMUTANT_PROJ_DART) + { item->Animation.TargetState = WMUTANT_STATE_AIM_DART; - else if (shootType == WMUTANT_PROJ_BOMB) + } + else if (projectileType == WMUTANT_PROJ_BOMB) + { item->Animation.TargetState = WMUTANT_STATE_AIM_BOMB; + } else if (creature->Mood == MoodType::Bored || - (creature->Mood == MoodType::Stalk && AI.distance < WINGED_MUTANT_WALK_RANGE)) + (creature->Mood == MoodType::Stalk && ai.distance < WINGED_MUTANT_POSE_RANGE)) { item->Animation.TargetState = WMUTANT_STATE_POSE; } else + { item->Animation.TargetState = WMUTANT_STATE_RUN_FORWARD; + } break; case WMUTANT_STATE_POSE: - head = 0; // Pose has an animation for the head. + creature->Flags = 0; creature->MaxTurn = 0; + head = 0; // NOTE: Pose has animation for head. - if (shootType != WMUTANT_PROJ_NONE || (flyStatus && flyEnabled)) + if (projectileType != WMUTANT_PROJ_NONE || (flyStatus && flyEnabled)) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } else if (creature->Mood == MoodType::Stalk) { - if (AI.distance < WINGED_MUTANT_WALK_RANGE) + if (ai.distance < WINGED_MUTANT_WALK_RANGE) { - if (AI.zoneNumber == AI.enemyZone || + if (isSameZoneInGroundMode || Random::TestProbability(WINGED_MUTANT_UNPOSE_CHANCE)) { item->Animation.TargetState = WMUTANT_STATE_WALK_FORWARD; } } else + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } } else if (creature->Mood == MoodType::Bored && Random::TestProbability(WINGED_MUTANT_UNPOSE_CHANCE)) + { item->Animation.TargetState = WMUTANT_STATE_WALK_FORWARD; + } else if (creature->Mood == MoodType::Attack || creature->Mood == MoodType::Escape) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } break; case WMUTANT_STATE_WALK_FORWARD: - creature->MaxTurn = WINGED_MUTANT_WALK_FORWARD_TURN_RATE_MAX; + creature->MaxTurn = WINGED_MUTANT_WALK_TURN_RATE_MAX; + creature->Flags = 0; - if (shootType != WMUTANT_PROJ_NONE || (flyStatus && flyEnabled)) + if (projectileType != WMUTANT_PROJ_NONE || (flyStatus && flyEnabled)) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } else if (creature->Mood == MoodType::Attack || creature->Mood == MoodType::Escape) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } else if (creature->Mood == MoodType::Bored || - (creature->Mood == MoodType::Stalk && AI.zoneNumber != AI.enemyZone)) + (creature->Mood == MoodType::Stalk && !isSameZoneInGroundMode)) { if (Random::TestProbability(WINGED_MUTANT_POSE_CHANCE)) item->Animation.TargetState = WMUTANT_STATE_POSE; } else if (creature->Mood == MoodType::Stalk && - AI.distance > WINGED_MUTANT_WALK_RANGE) + ai.distance > WINGED_MUTANT_WALK_RANGE) { item->Animation.TargetState = WMUTANT_STATE_IDLE; } @@ -377,22 +414,35 @@ namespace TEN::Entities::Creatures::TR1 break; case WMUTANT_STATE_RUN_FORWARD: - creature->MaxTurn = WINGED_MUTANT_RUN_FORWARD_TURN_RATE_MAX; + creature->MaxTurn = WINGED_MUTANT_RUN_TURN_RATE_MAX; + creature->Flags = 0; - if (flyStatus && flyEnabled) + if (flyEnabled && !isSameZoneInGroundMode) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; - else if (item->TouchBits.Test(WingedMutantJoints[1])) + } + else if (projectileType != WMUTANT_PROJ_NONE) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; - else if (AI.bite && AI.distance < WINGED_MUTANT_RUN_JUMP_ATTACK_RANGE) + } + else if (item->TouchBits.Test(WingedMutantHeadJoints)) + { + item->Animation.TargetState = WMUTANT_STATE_IDLE; + } + else if (ai.bite && ai.distance < WINGED_MUTANT_RUN_JUMP_ATTACK_RANGE) + { item->Animation.TargetState = WMUTANT_STATE_RUN_JUMP_ATTACK; - else if (AI.bite && AI.distance < WINGED_MUTANT_SWIPE_ATTACK_RANGE) + } + else if (ai.bite && ai.distance < WINGED_MUTANT_SWIPE_ATTACK_RANGE) + { item->Animation.TargetState = WMUTANT_STATE_SWIPE_ATTACK; - else if (AI.ahead && AI.distance < WINGED_MUTANT_SWIPE_ATTACK_RANGE) + } + else if (ai.ahead && ai.distance < WINGED_MUTANT_SWIPE_ATTACK_RANGE) + { item->Animation.TargetState = WMUTANT_STATE_SWIPE_ATTACK; - else if (shootType != WMUTANT_PROJ_NONE) - item->Animation.TargetState = WMUTANT_STATE_IDLE; + } else if (creature->Mood == MoodType::Bored || - (creature->Mood == MoodType::Stalk && AI.distance < WINGED_MUTANT_WALK_RANGE)) + (creature->Mood == MoodType::Stalk && ai.distance < WINGED_MUTANT_POSE_RANGE)) { item->Animation.TargetState = WMUTANT_STATE_IDLE; } @@ -401,81 +451,114 @@ namespace TEN::Entities::Creatures::TR1 case WMUTANT_STATE_IDLE_JUMP_ATTACK: if (item->Animation.RequiredState == NO_STATE && - item->TouchBits.Test(WingedMutantJoints[1])) + (item->TouchBits.Test(WingedMutantHandsJoints) || item->TouchBits.Test(WingedMutantHeadJoints)) && creature->Flags == 0) { - DoDamage(creature->Enemy, WINGED_MUTANT_IDLE_JUMP_ATTACK_DAMAGE); - CreatureEffect(item, WingedMutantBite, DoBloodSplat); + DoDamage(creature->Enemy, WINGED_MUTANT_IDLE_JUMP_ATTACK_DAMAGE / 2); + CreatureEffect(item, WingedMutantBiteLeftHand, DoBloodSplat); + + DoDamage(creature->Enemy, WINGED_MUTANT_IDLE_JUMP_ATTACK_DAMAGE / 2); + CreatureEffect(item, WingedMutantBiteRightHand, DoBloodSplat); + item->Animation.TargetState = WMUTANT_STATE_IDLE; + creature->Flags = 1; } break; case WMUTANT_STATE_RUN_JUMP_ATTACK: if (item->Animation.RequiredState == NO_STATE && - item->TouchBits.Test(WingedMutantJoints[1])) + (item->TouchBits.Test(WingedMutantHandsJoints) || item->TouchBits.Test(WingedMutantHeadJoints)) && creature->Flags == 0) { - DoDamage(creature->Enemy, WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE); - CreatureEffect(item, WingedMutantBite, DoBloodSplat); + DoDamage(creature->Enemy, WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE / 2); + CreatureEffect(item, WingedMutantBiteLeftHand, DoBloodSplat); + + DoDamage(creature->Enemy, WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE / 2); + CreatureEffect(item, WingedMutantBiteRightHand, DoBloodSplat); + item->Animation.TargetState = WMUTANT_STATE_RUN_FORWARD; + creature->Flags = 1; } break; case WMUTANT_STATE_SWIPE_ATTACK: if (item->Animation.RequiredState == NO_STATE && - item->TouchBits.Test(WingedMutantJoints[1])) + item->TouchBits.Test(WingedMutantHandsJoints) && creature->Flags == 0) { - DoDamage(creature->Enemy, WINGED_MUTANT_SWIPE_ATTACK_DAMAGE); - CreatureEffect(item, WingedMutantBite, DoBloodSplat); + DoDamage(creature->Enemy, WINGED_MUTANT_SWIPE_ATTACK_DAMAGE / 2); + CreatureEffect(item, WingedMutantBiteLeftHand, DoBloodSplat); + + DoDamage(creature->Enemy, WINGED_MUTANT_SWIPE_ATTACK_DAMAGE / 2); + CreatureEffect(item, WingedMutantBiteRightHand, DoBloodSplat); + item->Animation.TargetState = WMUTANT_STATE_IDLE; + creature->Flags = 1; } break; case WMUTANT_STATE_AIM_DART: - torso = AI.angle / 2; - creature->MaxTurn = 0; item->SetFlagField(WMUTANT_CONF_PROJECTILE_MODE, WMUTANT_PROJ_DART); + creature->MaxTurn = 0; + creature->Flags = 0; + torso = ai.angle / 2; - if (shootType == WMUTANT_PROJ_DART) + if (projectileType == WMUTANT_PROJ_DART) + { item->Animation.TargetState = WMUTANT_STATE_SHOOT; + } else + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } break; case WMUTANT_STATE_AIM_BOMB: - torso = AI.angle / 2; - creature->MaxTurn = 0; item->SetFlagField(WMUTANT_CONF_PROJECTILE_MODE, WMUTANT_PROJ_BOMB); + creature->MaxTurn = 0; + creature->Flags = 0; + torso = ai.angle / 2; - if (shootType == WMUTANT_PROJ_BOMB) + if (projectileType == WMUTANT_PROJ_BOMB) + { item->Animation.TargetState = WMUTANT_STATE_SHOOT; + } else + { item->Animation.TargetState = WMUTANT_STATE_IDLE; + } break; case WMUTANT_STATE_SHOOT: - { - torso = AI.angle / 2; creature->MaxTurn = 0; + torso = ai.angle / 2; - bool isDart = item->TestFlagField(WMUTANT_CONF_PROJECTILE_MODE, WMUTANT_PROJ_DART); - bool isBomb = item->TestFlagField(WMUTANT_CONF_PROJECTILE_MODE, WMUTANT_PROJ_BOMB); - - if (isDart) - CreatureEffect2(item, WingedMutantShardBite, WINGED_MUTANT_SHARD_VELOCITY, torso, ShardGun); - else if (isBomb) - CreatureEffect2(item, WingedMutantRocketBite, WINGED_MUTANT_BOMB_VELOCITY, torso, BombGun); + if (creature->Flags == 0) + { + if (projectileType == WMUTANT_PROJ_DART) + { + CreatureEffect2(item, WingedMutantShardBite, WINGED_MUTANT_SHARD_VELOCITY, torso, ShardGun); + } + else if (projectileType == WMUTANT_PROJ_BOMB) + { + CreatureEffect2(item, WingedMutantRocketBite, WINGED_MUTANT_BOMB_VELOCITY, torso, BombGun); + } + creature->Flags = 1; + } + item->SetFlagField(WMUTANT_CONF_PROJECTILE_MODE, WMUTANT_PROJ_NONE); break; - } case WMUTANT_STATE_FLY: - if (!flyStatus && item->Pose.Position.y == item->Floor) + if (creature->Mood != MoodType::Escape && isSameZoneInGroundMode) + { item->Animation.TargetState = WMUTANT_STATE_IDLE; // Switch to ground mode. + item->Pose.Position.y = item->Floor; + item->SetFlagField(WMUTANT_CONF_PATHFINDING_MODE, WMUTANT_PATH_GROUND); + } break; } diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp index 1452a99d0..a8531d95d 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp @@ -32,7 +32,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto WOLF_RUN_TURN_RATE_MAX = ANGLE(5.0f); constexpr auto WOLF_STALK_TURN_RATE_MAX = ANGLE(2.0f); - const auto WolfBite = CreatureBiteInfo(Vector3i(0, -14, 174), 6); + const auto WolfBite = CreatureBiteInfo(Vector3(0, -14, 174), 6); const auto WolfAttackJoints = std::vector{ 0, 1, 2, 3, 6, 8, 9, 10, 12, 13, 14 }; enum WolfState @@ -165,11 +165,11 @@ namespace TEN::Entities::Creatures::TR1 item->Animation.TargetState = WOLF_STATE_RUN; else if (AI.distance < pow(345, 2) && AI.bite) item->Animation.TargetState = WOLF_STATE_BITE; - else if (AI.distance > pow(SECTOR(3), 2)) + else if (AI.distance > pow(BLOCK(3), 2)) item->Animation.TargetState = WOLF_STATE_RUN; else if (creature->Mood == MoodType::Attack) { - if (!AI.ahead || AI.distance > pow(SECTOR(1.5f), 2) || + if (!AI.ahead || AI.distance > pow(BLOCK(1.5f), 2) || (AI.enemyFacing < FRONT_ARC && AI.enemyFacing > -FRONT_ARC)) { item->Animation.TargetState = WOLF_STATE_RUN; diff --git a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp index b2de4d97e..25290c7c3 100644 --- a/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp +++ b/TombEngine/Objects/TR1/Trap/DamoclesSword.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math; namespace TEN::Entities::Traps::TR1 { // NOTES: - // ItemFlags[0] = random turn rate. + // ItemFlags[0] = random turn rate when active. // ItemFlags[1] = calculated forward velocity. constexpr auto DAMOCLES_SWORD_DAMAGE = 100; @@ -28,14 +28,17 @@ namespace TEN::Entities::Traps::TR1 constexpr auto DAMOCLES_SWORD_ACTIVATE_RANGE_VERTICAL = BLOCK(3); constexpr auto DAMOCLES_SWORD_TURN_RATE_MAX = ANGLE(5.0f); + constexpr auto DAMOCLES_SWORD_TURN_RATE_MIN = ANGLE(1.0f); void InitializeDamoclesSword(short itemNumber) { auto& item = g_Level.Items[itemNumber]; + int sign = Random::TestProbability(0.5f) ? 1 : -1; + item.Pose.Orientation.y = Random::GenerateAngle(); item.Animation.Velocity.y = DAMOCLES_SWORD_VELOCITY_MIN; - item.ItemFlags[0] = Random::GenerateAngle(-DAMOCLES_SWORD_TURN_RATE_MAX, DAMOCLES_SWORD_TURN_RATE_MAX); + item.ItemFlags[0] = Random::GenerateAngle(DAMOCLES_SWORD_TURN_RATE_MIN, DAMOCLES_SWORD_TURN_RATE_MAX) * sign; } void ControlDamoclesSword(short itemNumber) diff --git a/TombEngine/Objects/TR1/tr1_objects.cpp b/TombEngine/Objects/TR1/tr1_objects.cpp index 1e821d0e0..e5f1d580e 100644 --- a/TombEngine/Objects/TR1/tr1_objects.cpp +++ b/TombEngine/Objects/TR1/tr1_objects.cpp @@ -105,7 +105,9 @@ static void StartEntity(ObjectInfo* obj) obj->HitPoints = 400; obj->radius = 204; obj->intelligent = true; - obj->SetBoneRotationFlags(2, ROT_X | ROT_Z); + obj->LotType = LotType::Flyer; + obj->SetBoneRotationFlags(0, ROT_X | ROT_Y); // Torso + obj->SetBoneRotationFlags(1, ROT_X | ROT_Y); // Head obj->SetupHitEffect(); } @@ -200,7 +202,7 @@ static void StartEntity(ObjectInfo* obj) obj->shadowType = ShadowMode::All; obj->pivotLength = 0; obj->radius = 102; - obj->HitPoints = 1; + obj->HitPoints = 200; obj->intelligent = true; obj->SetBoneRotationFlags(1, ROT_Y); obj->SetBoneRotationFlags(0, ROT_X | ROT_Y); @@ -215,7 +217,7 @@ static void StartEntity(ObjectInfo* obj) obj->collision = CreatureCollision; obj->shadowType = ShadowMode::All; obj->pivotLength = 0; - obj->radius = 102; + obj->radius = 256; obj->HitPoints = 125; obj->intelligent = true; obj->SetBoneRotationFlags(7, ROT_Y); // Head. @@ -226,7 +228,7 @@ static void StartEntity(ObjectInfo* obj) static void StartObject(ObjectInfo* obj) { - obj = &Objects[ID_BACON_REFERENCE]; + obj = &Objects[ID_DOPPELGANGER_ORIGIN]; if (obj->loaded) { obj->collision = AIPickupCollision; @@ -260,7 +262,7 @@ static void StartTrap(ObjectInfo* obj) static void StartProjectiles(ObjectInfo* obj) { InitProjectile(obj, ControlMissile, ID_PROJ_SHARD); - InitProjectile(obj, ControlMissile, ID_PROJ_NATLA); + InitProjectile(obj, ControlMissile, ID_PROJ_BOMB); InitProjectile(obj, ControlMissile, ID_PROJ_BOMB); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp b/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp index 788471499..3ec372423 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp @@ -16,7 +16,7 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto BARRACUDA_IDLE_ATTACK_RANGE = SQUARE(BLOCK(0.67f)); constexpr auto BARRACUDA_SWIM_FAST_ATTACK_RANGE = SQUARE(BLOCK(0.34f)); - const auto BarracudaBite = CreatureBiteInfo(Vector3i(2, -60, 121), 7); + const auto BarracudaBite = CreatureBiteInfo(Vector3(2, -60, 121), 7); const auto BarracudaAttackJoints = std::vector{ 5, 6, 7 }; enum BarracudaState diff --git a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp index 1f717da55..e4f45bcc3 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp @@ -21,8 +21,8 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto BIRD_MONSTER_WALK_TURN_RATE_MAX = ANGLE(4.0f); - const auto BirdMonsterBiteLeft = CreatureBiteInfo(Vector3i(0, 224, 0), 19); - const auto BirdMonsterBiteRight = CreatureBiteInfo(Vector3i(0, 224, 0), 22); + const auto BirdMonsterBiteLeft = CreatureBiteInfo(Vector3(0, 224, 0), 19); + const auto BirdMonsterBiteRight = CreatureBiteInfo(Vector3(0, 224, 0), 22); const auto BirdMonsterAttackLeftJoints = std::vector{ 18, 19 }; const auto BirdMonsterAttackRightJoints = std::vector{ 21, 22 }; diff --git a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp index 0dcd284ee..f0fe2071d 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp @@ -24,14 +24,14 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto DRAGON_SWIPE_ATTACK_DAMAGE = 250; constexpr auto DRAGON_CONTACT_DAMAGE = 10; - const auto DragonMouthBite = CreatureBiteInfo(Vector3i(35, 171, 1168), 12); + const auto DragonMouthBite = CreatureBiteInfo(Vector3(35, 171, 1168), 12); const auto DragonSwipeAttackJointsLeft = std::vector{ 24, 25, 26, 27, 28, 29, 30 }; const auto DragonSwipeAttackJointsRight = std::vector{ 1, 2, 3, 4, 5, 6, 7 }; // TODO: Organise. #define DRAGON_LIVE_TIME (30 * 11) - #define DRAGON_CLOSE_RANGE pow(SECTOR(3), 2) - #define DRAGON_STATE_IDLE_RANGE pow(SECTOR(6), 2) + #define DRAGON_CLOSE_RANGE pow(BLOCK(3), 2) + #define DRAGON_STATE_IDLE_RANGE pow(BLOCK(6), 2) #define DRAGON_FLAME_SPEED 200 #define DRAGON_ALMOST_LIVE 100 @@ -39,7 +39,7 @@ namespace TEN::Entities::Creatures::TR2 #define BOOM_TIME_MIDDLE 140 #define BOOM_TIME_END 150 - #define BARTOLI_RANGE SECTOR(9) + #define BARTOLI_RANGE BLOCK(9) #define DRAGON_CLOSE 900 #define DRAGON_FAR 2300 #define DRAGON_MID ((DRAGON_CLOSE + DRAGON_FAR) / 2) @@ -200,7 +200,7 @@ namespace TEN::Entities::Creatures::TR2 laraItem->Animation.Velocity.z = 0.0f; if (item->RoomNumber != laraItem->RoomNumber) - ItemNewRoom(Lara.ItemNumber, item->RoomNumber); + ItemNewRoom(laraItem->Index, item->RoomNumber); AnimateItem(LaraItem); diff --git a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp index 067b718d3..4dba5a129 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp @@ -13,8 +13,8 @@ namespace TEN::Entities::Creatures::TR2 { - const auto EagleBite = CreatureBiteInfo(Vector3i(15, 46, 21), 6); - const auto CrowBite = CreatureBiteInfo(Vector3i(2, 10, 60), 14); + const auto EagleBite = CreatureBiteInfo(Vector3(15, 46, 21), 6); + const auto CrowBite = CreatureBiteInfo(Vector3(2, 10, 60), 14); enum EagleOrCrowState { @@ -134,7 +134,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = item->Animation.RequiredState; if (creature->Mood == MoodType::Bored) item->Animation.TargetState = 2; - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) item->Animation.TargetState = 6; else item->Animation.TargetState = 3; @@ -147,7 +147,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.RequiredState = 2; item->Animation.TargetState = 1; } - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) item->Animation.TargetState = 6; break; diff --git a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp index 77638e4ab..898beb8c8 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp @@ -25,8 +25,8 @@ namespace TEN::Entities::Creatures::TR2 // TODO: Ranges. - const auto KnifeBiteLeft = CreatureBiteInfo(Vector3i::Zero, 5); - const auto KnifeBiteRight = CreatureBiteInfo(Vector3i::Zero, 8); + const auto KnifeBiteLeft = CreatureBiteInfo(Vector3::Zero, 5); + const auto KnifeBiteRight = CreatureBiteInfo(Vector3::Zero, 8); enum KnifeThrowerState { diff --git a/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp b/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp index 6760ed0ef..ed1f2cdc5 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp @@ -13,8 +13,8 @@ namespace TEN::Entities::Creatures::TR2 { - const auto MercenaryUziBite = CreatureBiteInfo(Vector3i(0, 200, 19), 17); - const auto MercenaryAutoPistolBite = CreatureBiteInfo(Vector3i(0, 230, 9), 17); + const auto MercenaryUziBite = CreatureBiteInfo(Vector3(0, 200, 19), 17); + const auto MercenaryAutoPistolBite = CreatureBiteInfo(Vector3(0, 230, 9), 17); // TODO enum MercenaryState diff --git a/TombEngine/Objects/TR2/Entity/tr2_monk.cpp b/TombEngine/Objects/TR2/Entity/tr2_monk.cpp index ac586f50f..a7dced7c6 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_monk.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_monk.cpp @@ -13,7 +13,7 @@ namespace TEN::Entities::Creatures::TR2 { - const auto MonkBite = CreatureBiteInfo(Vector3i(-23, 16, 265), 14); + const auto MonkBite = CreatureBiteInfo(Vector3(-23, 16, 265), 14); bool MonksAttackLara; @@ -79,16 +79,16 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 2; else if (creature->Mood == MoodType::Escape) item->Animation.TargetState = 3; - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) { if (GetRandomControl() < 0x7000) item->Animation.TargetState = 4; else item->Animation.TargetState = 11; } - else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = 7; - else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(2), 2)) item->Animation.TargetState = 2; else item->Animation.TargetState = 3; @@ -104,7 +104,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 2; else if (creature->Mood == MoodType::Escape) item->Animation.TargetState = 3; - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) { auto random = GetRandomControl(); if (random < 0x3000) @@ -114,7 +114,7 @@ namespace TEN::Entities::Creatures::TR2 else item->Animation.TargetState = 1; } - else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(2), 2)) item->Animation.TargetState = 2; else item->Animation.TargetState = 3; @@ -136,14 +136,14 @@ namespace TEN::Entities::Creatures::TR2 } else if (creature->Mood == MoodType::Escape) item->Animation.TargetState = 3; - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) { if (GetRandomControl() < 0x4000) item->Animation.TargetState = 1; else item->Animation.TargetState = 11; } - else if (!AI.ahead || AI.distance > pow(SECTOR(2), 2)) + else if (!AI.ahead || AI.distance > pow(BLOCK(2), 2)) item->Animation.TargetState = 3; break; @@ -160,16 +160,16 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 1; else if (creature->Mood == MoodType::Escape) break; - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) { if (GetRandomControl() < 0x4000) item->Animation.TargetState = 1; else item->Animation.TargetState = 11; } - else if (AI.ahead && AI.distance < pow(SECTOR(3), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(3), 2)) item->Animation.TargetState = 10; - else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(2), 2)) { if (GetRandomControl() < 0x4000) item->Animation.TargetState = 1; @@ -180,7 +180,7 @@ namespace TEN::Entities::Creatures::TR2 break; case 8: - if (!AI.ahead || AI.distance > pow(SECTOR(0.5f), 2)) + if (!AI.ahead || AI.distance > pow(BLOCK(0.5f), 2)) item->Animation.TargetState = 11; else item->Animation.TargetState = 6; diff --git a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp index d10499e9d..398a74d3c 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp @@ -25,7 +25,7 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto RAT_TURN_RATE_MAX = ANGLE(6.0f); - const auto RatBite = CreatureBiteInfo(Vector3i(0, 0, 57), 2); + const auto RatBite = CreatureBiteInfo(Vector3(0, 0, 57), 2); enum RatState { diff --git a/TombEngine/Objects/TR2/Entity/tr2_shark.cpp b/TombEngine/Objects/TR2/Entity/tr2_shark.cpp index d9947cc8f..657a9a268 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_shark.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_shark.cpp @@ -15,7 +15,7 @@ namespace TEN::Entities::Creatures::TR2 { constexpr auto SHARK_BITE_ATTACK_DAMAGE = 400; - const auto SharkBite = CreatureBiteInfo(Vector3i(17, -22, 344), 12); + const auto SharkBite = CreatureBiteInfo(Vector3(17, -22, 344), 12); const auto SharkBiteAttackJoints = std::vector{ 10, 12, 13 }; void SharkControl(short itemNumber) @@ -52,7 +52,7 @@ namespace TEN::Entities::Creatures::TR2 creature->MaxTurn = 0; creature->Flags = 0; - if (AI.ahead && AI.distance < pow(SECTOR(0.75f), 2) && AI.zoneNumber == AI.enemyZone) + if (AI.ahead && AI.distance < pow(BLOCK(0.75f), 2) && AI.zoneNumber == AI.enemyZone) item->Animation.TargetState = 3; else item->Animation.TargetState = 1; @@ -64,9 +64,9 @@ namespace TEN::Entities::Creatures::TR2 if (creature->Mood == MoodType::Bored) break; - else if (AI.ahead && AI.distance < pow(SECTOR(0.75f), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.75f), 2)) item->Animation.TargetState = 0; - else if (creature->Mood == MoodType::Escape || AI.distance > pow(SECTOR(3), 2) || !AI.ahead) + else if (creature->Mood == MoodType::Escape || AI.distance > pow(BLOCK(3), 2) || !AI.ahead) item->Animation.TargetState = 2; break; @@ -83,7 +83,7 @@ namespace TEN::Entities::Creatures::TR2 { if (GetRandomControl() < 0x800) item->Animation.TargetState = 0; - else if (AI.distance < pow(SECTOR(0.75f), 2)) + else if (AI.distance < pow(BLOCK(0.75f), 2)) item->Animation.TargetState = 4; } diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp index a0e547216..1f3dcc11d 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp @@ -25,10 +25,10 @@ namespace TEN::Entities::Creatures::TR2 { constexpr auto SMAN_WAIT_RANGE = SQUARE(BLOCK(4)); - const auto SkidooBiteLeft = CreatureBiteInfo(Vector3i(240, -80, 540), 0); - const auto SkidooBiteRight = CreatureBiteInfo(Vector3i(-240, -80, 540), 0); - const auto SkidooBiteSmokeLeft = CreatureBiteInfo(Vector3i(240, -80, 450), 0); - const auto SkidooBiteSmokeRight = CreatureBiteInfo(Vector3i(-240, -80, 450), 0); + const auto SkidooBiteLeft = CreatureBiteInfo(Vector3(240, -80, 540), 0); + const auto SkidooBiteRight = CreatureBiteInfo(Vector3(-240, -80, 540), 0); + const auto SkidooBiteSmokeLeft = CreatureBiteInfo(Vector3(240, -80, 450), 0); + const auto SkidooBiteSmokeRight = CreatureBiteInfo(Vector3(-240, -80, 450), 0); constexpr auto SKIDOO_MAN_TURN_RATE_MIN = ANGLE(2.0f); constexpr auto SKIDOO_MAN_TARGET_ANGLE = ANGLE(30.0f); diff --git a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp index 275d58593..efeb54dd2 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp @@ -34,8 +34,8 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto SPEAR_GUARDIAN_SWAPMESH_TIME = 3; - const auto SpearGuardianBiteLeft = CreatureBiteInfo(Vector3i(0, 0, 920), 11); - const auto SpearGuardianBiteRight = CreatureBiteInfo(Vector3i(0, 0, 920), 18); + const auto SpearGuardianBiteLeft = CreatureBiteInfo(Vector3(0, 0, 920), 11); + const auto SpearGuardianBiteRight = CreatureBiteInfo(Vector3(0, 0, 920), 18); enum SpearGuardianState { diff --git a/TombEngine/Objects/TR2/Entity/tr2_spider.cpp b/TombEngine/Objects/TR2/Entity/tr2_spider.cpp index 39552d5ab..0dcf4c9ea 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spider.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spider.cpp @@ -30,7 +30,7 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto SMALL_SPIDER_TURN_RATE_MAX = ANGLE(8.0f); constexpr auto BIG_SPIDER_TURN_RATE_MAX = ANGLE(4.0f); - const auto SpiderBite = CreatureBiteInfo(Vector3i(0, 0, 41), 1); + const auto SpiderBite = CreatureBiteInfo(Vector3(0, 0, 41), 1); enum SpiderState { diff --git a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp index 2298cbb86..500c6f1ad 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::Creatures::TR2 constexpr auto SWORD_GUARDIAN_MESH_SWAP_TIME = 3; - const auto SwordBite = CreatureBiteInfo(Vector3i(0, 37, 550), 15); + const auto SwordBite = CreatureBiteInfo(Vector3(0, 37, 550), 15); enum SwordGuardianState { diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp index e1ea5b005..f6fac976c 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp @@ -12,8 +12,8 @@ namespace TEN::Entities::Creatures::TR2 { - const auto WorkerDualGunBiteLeft = CreatureBiteInfo(Vector3i(-2, 340, 23), 6); - const auto WorkerDualGunBiteRight = CreatureBiteInfo(Vector3i(2, 340, 23), 10); + const auto WorkerDualGunBiteLeft = CreatureBiteInfo(Vector3(-2, 340, 23), 6); + const auto WorkerDualGunBiteRight = CreatureBiteInfo(Vector3(2, 340, 23), 10); // TODO enum WorkerDualGunState @@ -81,7 +81,7 @@ namespace TEN::Entities::Creatures::TR2 { if (Targetable(item, &ai)) { - if (ai.distance <= pow(SECTOR(3), 2)) + if (ai.distance <= pow(BLOCK(3), 2)) { item->Animation.TargetState = 9; } @@ -95,7 +95,7 @@ namespace TEN::Entities::Creatures::TR2 switch (creature->Mood) { case MoodType::Attack: - if (ai.distance > pow(SECTOR(20), 2) || !ai.ahead) + if (ai.distance > pow(BLOCK(20), 2) || !ai.ahead) { item->Animation.TargetState = 4; } @@ -140,7 +140,7 @@ namespace TEN::Entities::Creatures::TR2 if (Targetable(item, &ai)) { - if (ai.distance < pow(SECTOR(3), 2) || ai.zoneNumber != ai.enemyZone) + if (ai.distance < pow(BLOCK(3), 2) || ai.zoneNumber != ai.enemyZone) { item->Animation.TargetState = 1; } @@ -163,7 +163,7 @@ namespace TEN::Entities::Creatures::TR2 } else if (creature->Mood == MoodType::Attack || creature->Mood == MoodType::Stalk) { - if (ai.distance > pow(SECTOR(20), 2) || !ai.ahead) + if (ai.distance > pow(BLOCK(20), 2) || !ai.ahead) item->Animation.TargetState = 4; } else if (LaraItem->HitPoints > 0) @@ -208,7 +208,7 @@ namespace TEN::Entities::Creatures::TR2 } else if (creature->Mood == MoodType::Attack) { - if (ai.ahead && ai.distance < pow(SECTOR(20), 2)) + if (ai.ahead && ai.distance < pow(BLOCK(20), 2)) item->Animation.TargetState = 3; } else if (LaraItem->HitPoints > 0) diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp index 88fca6057..e860263b5 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp @@ -17,10 +17,10 @@ namespace TEN::Entities::Creatures::TR2 { - constexpr auto WORKER_FLAME_ATTACK_RANGE = SQUARE(SECTOR(2)); - constexpr auto WORKER_FLAME_IDLE_RANGE = SQUARE(SECTOR(2)); - constexpr auto WORKER_FLAME_WALK_RANGE = SQUARE(SECTOR(2)); - constexpr auto WORKER_FLAME_RUN_RANGE = SQUARE(SECTOR(4)); + constexpr auto WORKER_FLAME_ATTACK_RANGE = SQUARE(BLOCK(2)); + constexpr auto WORKER_FLAME_IDLE_RANGE = SQUARE(BLOCK(2)); + constexpr auto WORKER_FLAME_WALK_RANGE = SQUARE(BLOCK(2)); + constexpr auto WORKER_FLAME_RUN_RANGE = SQUARE(BLOCK(4)); constexpr auto WORKER_FLAME_WALK_TURN_RATE_MAX = ANGLE(5.0f); constexpr auto WORKER_FLAME_RUN_TURN_RATE_MAX = ANGLE(10.0f); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp index 0e3d71d39..467b15ec5 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp @@ -13,7 +13,7 @@ namespace TEN::Entities::Creatures::TR2 { - const auto WorkerMachineGunBite = CreatureBiteInfo(Vector3i(0, 380, 37), 9); + const auto WorkerMachineGunBite = CreatureBiteInfo(Vector3(0, 380, 37), 9); // TODO enum WorkerMachineGunState diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp index 02a4b8ee9..380e35b89 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp @@ -16,7 +16,7 @@ namespace TEN::Entities::Creatures::TR2 { constexpr auto WORKER_SHOTGUN_NUM_SHOTS = 6; - const auto WorkerShotgunBite = CreatureBiteInfo(Vector3i(0, 350, 40), 9); + const auto WorkerShotgunBite = CreatureBiteInfo(Vector3(0, 350, 40), 9); // TODO enum ShotgunWorkerState diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp index 0e236f325..58565a9bc 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp @@ -16,8 +16,8 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR2 { - const auto YetiBiteLeft = CreatureBiteInfo(Vector3i(12, 101, 19), 13); - const auto YetiBiteRight = CreatureBiteInfo(Vector3i(12, 101, 19), 10); + const auto YetiBiteLeft = CreatureBiteInfo(Vector3(12, 101, 19), 13); + const auto YetiBiteRight = CreatureBiteInfo(Vector3(12, 101, 19), 10); const auto YetiAttackJoints1 = std::vector{ 10, 12 }; // TODO: Rename. const auto YetiAttackJoints2 = std::vector{ 8, 9, 10 }; @@ -97,7 +97,7 @@ namespace TEN::Entities::Creatures::TR2 else if (Random::TestProbability(0.025f)) item->Animation.TargetState = 3; } - else if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2) && Random::TestProbability(1 / 2.0f)) + else if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2) && Random::TestProbability(1 / 2.0f)) item->Animation.TargetState = 4; else if (AI.ahead && AI.distance < pow(CLICK(1), 2)) item->Animation.TargetState = 5; @@ -184,7 +184,7 @@ namespace TEN::Entities::Creatures::TR2 { if (AI.ahead && AI.distance < pow(CLICK(1), 2)) item->Animation.TargetState = 2; - else if (AI.distance < pow(SECTOR(2), 2)) + else if (AI.distance < pow(BLOCK(2), 2)) item->Animation.TargetState = 1; } @@ -204,7 +204,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 3; else if (AI.ahead && AI.distance < pow(CLICK(1), 2)) item->Animation.TargetState = 2; - else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(2), 2)) item->Animation.TargetState = 6; else if (info->Mood == MoodType::Stalk) item->Animation.TargetState = 3; diff --git a/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp b/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp index 89936dd9b..9bad3ef5b 100644 --- a/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp +++ b/TombEngine/Objects/TR2/Trap/tr2_killerstatue.cpp @@ -31,10 +31,10 @@ void KillerStatueControl(short itemNumber) { DoDamage(LaraItem, 20); - int x = LaraItem->Pose.Position.x + (GetRandomControl() - SECTOR(16)) / CLICK(1); - int z = LaraItem->Pose.Position.z + (GetRandomControl() - SECTOR(16)) / CLICK(1); + int x = LaraItem->Pose.Position.x + (GetRandomControl() - BLOCK(16)) / CLICK(1); + int z = LaraItem->Pose.Position.z + (GetRandomControl() - BLOCK(16)) / CLICK(1); int y = LaraItem->Pose.Position.y - GetRandomControl() / 44; - int d = (GetRandomControl() - SECTOR(16)) / 8 + LaraItem->Pose.Orientation.y; + int d = (GetRandomControl() - BLOCK(16)) / 8 + LaraItem->Pose.Orientation.y; DoBloodSplat(x, y, z, LaraItem->Animation.Velocity.z, d, LaraItem->RoomNumber); } diff --git a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp index 6cf0f0120..9c16dfea7 100644 --- a/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp +++ b/TombEngine/Objects/TR2/Trap/tr2_spinningblade.cpp @@ -27,8 +27,8 @@ void SpinningBladeControl(short itemNumber) { if (item->Animation.TargetState != 1) { - int x = item->Pose.Position.x + SECTOR(3) * phd_sin(item->Pose.Orientation.y) / 2; - int z = item->Pose.Position.z + SECTOR(3) * phd_cos(item->Pose.Orientation.y) / 2; + int x = item->Pose.Position.x + BLOCK(3) * phd_sin(item->Pose.Orientation.y) / 2; + int z = item->Pose.Position.z + BLOCK(3) * phd_cos(item->Pose.Orientation.y) / 2; int floorHeight = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).Position.Floor; if (floorHeight == NO_HEIGHT) diff --git a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp index 5f63aaf35..8a94a096f 100644 --- a/TombEngine/Objects/TR2/Vehicles/skidoo.cpp +++ b/TombEngine/Objects/TR2/Vehicles/skidoo.cpp @@ -61,8 +61,6 @@ namespace TEN::Entities::Vehicles #define SKIDOO_MOMENTUM_TURN_RATE_ACCEL ANGLE(3.0f) #define SKIDOO_MOMENTUM_TURN_RATE_MAX ANGLE(150.0f) - constexpr auto IN_SKIDOO_FIRE = IN_DRAW; - const std::vector SkidooMountTypes = { VehicleMountType::LevelStart, @@ -365,7 +363,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != skidooItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } AnimateItem(laraItem); @@ -381,7 +379,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != skidooItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } if (laraItem->Animation.ActiveState != SKIDOO_STATE_FALLOFF) @@ -435,10 +433,10 @@ namespace TEN::Entities::Vehicles if (TrInput & IN_LOOK && skidooItem->Animation.Velocity.z == 0) LookUpDown(laraItem); - if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) ModulateVehicleTurnRateY(&skidoo->TurnRate, SKIDOO_TURN_RATE_ACCEL, -SKIDOO_TURN_RATE_MAX, SKIDOO_TURN_RATE_MAX); - if (TrInput & VEHICLE_IN_REVERSE) + if (IsHeld(In::Reverse)) { if (skidooItem->Animation.Velocity.z > 0) skidooItem->Animation.Velocity.z -= SKIDOO_VELOCITY_BRAKE_DECEL; @@ -450,11 +448,11 @@ namespace TEN::Entities::Vehicles drive = true; } } - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { - if (TrInput & VEHICLE_IN_SPEED) + if (IsHeld(In::Speed)) maxVelocity = SKIDOO_FAST_VELOCITY_MAX; - else if (TrInput & VEHICLE_IN_SLOW) + else if (IsHeld(In::Slow)) maxVelocity = SKIDOO_SLOW_VELOCITY_MAX; else maxVelocity = SKIDOO_NORMAL_VELOCITY_MAX; @@ -466,7 +464,7 @@ namespace TEN::Entities::Vehicles drive = true; } - else if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) && + else if (IsHeld(In::Left) || IsHeld(In::Right) && skidooItem->Animation.Velocity.z >= 0 && skidooItem->Animation.Velocity.z < SKIDOO_TURN_VELOCITY_MAX) { @@ -483,7 +481,7 @@ namespace TEN::Entities::Vehicles else skidooItem->Animation.Velocity.z = 0; } - else if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE)) + else if (IsHeld(In::Accelerate) || IsHeld(In::Reverse)) { *pitch = skidoo->Pitch + 50; drive = true; @@ -530,36 +528,36 @@ namespace TEN::Entities::Vehicles laraItem->Animation.TargetState = SKIDOO_STATE_IDLE; - if (TrInput & VEHICLE_IN_DISMOUNT) + if (IsHeld(In::Brake)) { - if (TrInput & VEHICLE_IN_RIGHT && + if (IsHeld(In::Right) && TestSkidooDismountOK(skidooItem, SKIDOO_STATE_DISMOUNT_RIGHT)) { laraItem->Animation.TargetState = SKIDOO_STATE_DISMOUNT_RIGHT; skidooItem->Animation.Velocity.z = 0; } - else if (TrInput & VEHICLE_IN_LEFT && + else if (IsHeld(In::Left) && TestSkidooDismountOK(skidooItem, SKIDOO_STATE_DISMOUNT_LEFT)) { laraItem->Animation.TargetState = SKIDOO_STATE_DISMOUNT_LEFT; skidooItem->Animation.Velocity.z = 0; } } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) { if (skidooItem->Animation.Velocity.z >= 0) laraItem->Animation.TargetState = SKIDOO_STATE_LEFT; else laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { if (skidooItem->Animation.Velocity.z >= 0) laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT; else laraItem->Animation.TargetState = SKIDOO_STATE_LEFT; } - else if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE)) + else if (IsHeld(In::Accelerate) || IsHeld(In::Reverse)) laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE; break; @@ -570,14 +568,14 @@ namespace TEN::Entities::Vehicles if (dead) laraItem->Animation.TargetState = SKIDOO_STATE_FALLOFF; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) { if (skidooItem->Animation.Velocity.z >= 0) laraItem->Animation.TargetState = SKIDOO_STATE_LEFT; else laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { if (skidooItem->Animation.Velocity.z >= 0) laraItem->Animation.TargetState = SKIDOO_STATE_RIGHT; @@ -590,12 +588,12 @@ namespace TEN::Entities::Vehicles case SKIDOO_STATE_LEFT: if (skidooItem->Animation.Velocity.z >= 0) { - if (!(TrInput & VEHICLE_IN_LEFT)) + if (!IsHeld(In::Left)) laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE; } else { - if (!(TrInput & VEHICLE_IN_RIGHT)) + if (!IsHeld(In::Right)) laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE; } @@ -604,12 +602,12 @@ namespace TEN::Entities::Vehicles case SKIDOO_STATE_RIGHT: if (skidooItem->Animation.Velocity.z >= 0) { - if (!(TrInput & VEHICLE_IN_RIGHT)) + if (!IsHeld(In::Right)) laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE; } else { - if (!(TrInput & VEHICLE_IN_LEFT)) + if (!IsHeld(In::Left)) laraItem->Animation.TargetState = SKIDOO_STATE_DRIVE; } @@ -672,7 +670,7 @@ namespace TEN::Entities::Vehicles FindNewTarget(*laraItem, weapon); AimWeapon(*laraItem, lara->RightArm, weapon); - if (TrInput & IN_SKIDOO_FIRE && !skidooItem->ItemFlags[0]) + if (IsHeld(In::Fire) && !skidooItem->ItemFlags[0]) { auto angles = EulerAngles( lara->RightArm.Orientation.x, @@ -730,10 +728,10 @@ namespace TEN::Entities::Vehicles short DoSkidooShift(ItemInfo* skidooItem, Vector3i* pos, Vector3i* old) { - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); - int xOld = old->x / SECTOR(1); - int zOld = old->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); + int xOld = old->x / BLOCK(1); + int zOld = old->z / BLOCK(1); int shiftX = pos->x & WALL_MASK; int shiftZ = pos->z & WALL_MASK; @@ -751,7 +749,7 @@ namespace TEN::Entities::Vehicles } else { - skidooItem->Pose.Position.z += SECTOR(1) - shiftZ; + skidooItem->Pose.Position.z += BLOCK(1) - shiftZ; return (skidooItem->Pose.Position.x - pos->x); } } @@ -764,7 +762,7 @@ namespace TEN::Entities::Vehicles } else { - skidooItem->Pose.Position.x += SECTOR(1) - shiftX; + skidooItem->Pose.Position.x += BLOCK(1) - shiftX; return (pos->z - skidooItem->Pose.Position.z); } } @@ -779,7 +777,7 @@ namespace TEN::Entities::Vehicles if (pos->z > old->z) z = -shiftZ - 1; else - z = SECTOR(1) - shiftZ; + z = BLOCK(1) - shiftZ; } probe = GetCollision(pos->x, pos->y, old->z, skidooItem->RoomNumber); @@ -788,7 +786,7 @@ namespace TEN::Entities::Vehicles if (pos->x > old->x) x = -shiftX - 1; else - x = SECTOR(1) - shiftX; + x = BLOCK(1) - shiftX; } if (x && z) diff --git a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp index 8bddf2ba7..b81b554e0 100644 --- a/TombEngine/Objects/TR2/Vehicles/speedboat.cpp +++ b/TombEngine/Objects/TR2/Vehicles/speedboat.cpp @@ -28,7 +28,7 @@ namespace TEN::Entities::Vehicles constexpr auto SPEEDBOAT_SLIP = 10; constexpr auto SPEEDBOAT_SLIP_SIDE = 30; constexpr auto SPEEDBOAT_MOUNT_DISTANCE = CLICK(2.25f); - constexpr auto SPEEDBOAT_DISMOUNT_DISTANCE = SECTOR(1); + constexpr auto SPEEDBOAT_DISMOUNT_DISTANCE = BLOCK(1); constexpr auto SPEEDBOAT_VELOCITY_ACCEL = 5; constexpr auto SPEEDBOAT_VELOCITY_DECEL = 1; @@ -42,7 +42,7 @@ namespace TEN::Entities::Vehicles constexpr auto SPEEDBOAT_REVERSE_VELOCITY_MAX = 20; constexpr auto SPEEDBOAT_STEP_HEIGHT_MAX = CLICK(1); // Unused. - constexpr auto SPEEDBOAT_SOUND_CEILING = SECTOR(5); // Unused. + constexpr auto SPEEDBOAT_SOUND_CEILING = BLOCK(5); // Unused. constexpr auto SPEEDBOAT_TIP = SPEEDBOAT_FRONT + 250; constexpr auto SPEEDBOAT_WAKE_OFFSET = Vector3(SPEEDBOAT_SIDE * 1.2f, 0.0f, SPEEDBOAT_FRONT / 8); @@ -213,7 +213,7 @@ namespace TEN::Entities::Vehicles laraItem->Animation.FrameNumber = GetAnimData(laraItem).frameBase; if (laraItem->RoomNumber != speedboatItem->RoomNumber) - ItemNewRoom(lara->ItemNumber, speedboatItem->RoomNumber); + ItemNewRoom(laraItem->Index, speedboatItem->RoomNumber); laraItem->Pose.Position = speedboatItem->Pose.Position; laraItem->Pose.Position.y -= 5; @@ -289,7 +289,7 @@ namespace TEN::Entities::Vehicles laraItem->Pose.Position.z = z; if (probe.RoomNumber != laraItem->RoomNumber) - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose.Position.y = y; @@ -328,11 +328,11 @@ namespace TEN::Entities::Vehicles short SpeedboatDoShift(ItemInfo* speedboatItem, Vector3i* pos, Vector3i* old) { - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); - int xOld = old->x / SECTOR(1); - int zOld = old->z / SECTOR(1); + int xOld = old->x / BLOCK(1); + int zOld = old->z / BLOCK(1); int shiftX = pos->x & WALL_MASK; int shiftZ = pos->z & WALL_MASK; @@ -351,7 +351,7 @@ namespace TEN::Entities::Vehicles } else { - speedboatItem->Pose.Position.z += SECTOR(1) - shiftZ; + speedboatItem->Pose.Position.z += BLOCK(1) - shiftZ; return (speedboatItem->Pose.Position.x - pos->x); } } @@ -364,7 +364,7 @@ namespace TEN::Entities::Vehicles } else { - speedboatItem->Pose.Position.x += SECTOR(1) - shiftX; + speedboatItem->Pose.Position.x += BLOCK(1) - shiftX; return (pos->z - speedboatItem->Pose.Position.z); } } @@ -379,7 +379,7 @@ namespace TEN::Entities::Vehicles if (pos->z > old->z) z = -shiftZ - 1; else - z = SECTOR(1) - shiftZ; + z = BLOCK(1) - shiftZ; } probe = GetCollision(pos->x, pos->y, old->z, speedboatItem->RoomNumber); @@ -388,7 +388,7 @@ namespace TEN::Entities::Vehicles if (pos->x > old->x) x = -shiftX - 1; else - x = SECTOR(1) - shiftX; + x = BLOCK(1) - shiftX; } if (x && z) @@ -604,11 +604,11 @@ namespace TEN::Entities::Vehicles if (speedboatItem->Pose.Position.y >= speedboat->Water - CLICK(0.5f) && speedboat->Water != NO_HEIGHT) { - if (!(TrInput & VEHICLE_IN_DISMOUNT) && !(TrInput & IN_LOOK) || + if (!IsHeld(In::Brake) && !(TrInput & IN_LOOK) || speedboatItem->Animation.Velocity.z) { - if (TrInput & VEHICLE_IN_LEFT && !(TrInput & VEHICLE_IN_REVERSE) || - TrInput & VEHICLE_IN_RIGHT && TrInput & VEHICLE_IN_REVERSE) + if (IsHeld(In::Left) && !IsHeld(In::Reverse) || + IsHeld(In::Right) && IsHeld(In::Reverse)) { if (speedboat->TurnRate > 0) speedboat->TurnRate -= SPEEDBOAT_TURN_RATE_DECEL; @@ -621,8 +621,8 @@ namespace TEN::Entities::Vehicles noTurn = false; } - else if (TrInput & VEHICLE_IN_RIGHT && !(TrInput & VEHICLE_IN_REVERSE) || - TrInput & VEHICLE_IN_LEFT && TrInput & VEHICLE_IN_REVERSE) + else if (IsHeld(In::Right) && !IsHeld(In::Reverse) || + IsHeld(In::Left) && IsHeld(In::Reverse)) { if (speedboat->TurnRate < 0) speedboat->TurnRate += SPEEDBOAT_TURN_RATE_DECEL; @@ -636,30 +636,30 @@ namespace TEN::Entities::Vehicles noTurn = false; } - if (TrInput & VEHICLE_IN_REVERSE) + if (IsHeld(In::Reverse)) { if (speedboatItem->Animation.Velocity.z > 0) speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_BRAKE_DECEL; else if (speedboatItem->Animation.Velocity.z > -SPEEDBOAT_REVERSE_VELOCITY_MAX) speedboatItem->Animation.Velocity.z -= SPEEDBOAT_REVERSE_VELOCITY_DECEL; } - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { - if (TrInput & VEHICLE_IN_SPEED) + if (IsHeld(In::Speed)) maxVelocity = SPEEDBOAT_FAST_VELOCITY_MAX; else - maxVelocity = (TrInput & VEHICLE_IN_SLOW) ? SPEEDBOAT_SLOW_VELOCITY_MAX : SPEEDBOAT_NORMAL_VELOCITY_MAX; + maxVelocity = (IsHeld(In::Slow)) ? SPEEDBOAT_SLOW_VELOCITY_MAX : SPEEDBOAT_NORMAL_VELOCITY_MAX; if (speedboatItem->Animation.Velocity.z < maxVelocity) speedboatItem->Animation.Velocity.z += (SPEEDBOAT_VELOCITY_ACCEL / 2) + (SPEEDBOAT_VELOCITY_ACCEL * (speedboatItem->Animation.Velocity.z / (maxVelocity * 2))); else if (speedboatItem->Animation.Velocity.z > (maxVelocity + SPEEDBOAT_VELOCITY_DECEL)) speedboatItem->Animation.Velocity.z -= SPEEDBOAT_VELOCITY_DECEL; } - else if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) && + else if (IsHeld(In::Left) || IsHeld(In::Right) && speedboatItem->Animation.Velocity.z >= 0 && speedboatItem->Animation.Velocity.z < SPEEDBOAT_VELOCITY_MIN) { - if (!(TrInput & VEHICLE_IN_DISMOUNT) && + if (!IsHeld(In::Brake) && speedboatItem->Animation.Velocity.z == 0) speedboatItem->Animation.Velocity.z = SPEEDBOAT_VELOCITY_MIN; } @@ -670,11 +670,11 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) && + if ((IsHeld(In::Left) || IsHeld(In::Right)) && speedboatItem->Animation.Velocity.z >= 0 && speedboatItem->Animation.Velocity.z < SPEEDBOAT_VELOCITY_MIN) { - if (speedboatItem->Animation.Velocity.z == 0 && !(TrInput & VEHICLE_IN_DISMOUNT)) + if (speedboatItem->Animation.Velocity.z == 0 && !IsHeld(In::Brake)) speedboatItem->Animation.Velocity.z = SPEEDBOAT_VELOCITY_MIN; } else if (speedboatItem->Animation.Velocity.z > SPEEDBOAT_VELOCITY_DECEL) @@ -720,13 +720,13 @@ namespace TEN::Entities::Vehicles switch (laraItem->Animation.ActiveState) { case SPEEDBOAT_STATE_IDLE: - if (TrInput & VEHICLE_IN_DISMOUNT) + if (IsHeld(In::Brake)) { if (speedboatItem->Animation.Velocity.z == 0) { - if (TrInput & VEHICLE_IN_RIGHT && TestSpeedboatDismount(speedboatItem, speedboatItem->Pose.Orientation.y + ANGLE(90.0f))) + if (IsHeld(In::Right) && TestSpeedboatDismount(speedboatItem, speedboatItem->Pose.Orientation.y + ANGLE(90.0f))) laraItem->Animation.TargetState = SPEEDBOAT_STATE_DISMOUNT_RIGHT; - else if (TrInput & VEHICLE_IN_LEFT && TestSpeedboatDismount(speedboatItem, speedboatItem->Pose.Orientation.y - ANGLE(90.0f))) + else if (IsHeld(In::Left) && TestSpeedboatDismount(speedboatItem, speedboatItem->Pose.Orientation.y - ANGLE(90.0f))) laraItem->Animation.TargetState = SPEEDBOAT_STATE_DISMOUNT_LEFT; } } @@ -737,11 +737,11 @@ namespace TEN::Entities::Vehicles break; case SPEEDBOAT_STATE_MOVING: - if (TrInput & VEHICLE_IN_DISMOUNT) + if (IsHeld(In::Brake)) { - if (TrInput & VEHICLE_IN_RIGHT) + if (IsHeld(In::Right)) laraItem->Animation.TargetState = SPEEDBOAT_STATE_DISMOUNT_RIGHT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = SPEEDBOAT_STATE_DISMOUNT_LEFT; } else if (speedboatItem->Animation.Velocity.z <= 0) @@ -756,7 +756,7 @@ namespace TEN::Entities::Vehicles //case SPEEDBOAT_TURN_RATE_ACCELR: if (speedboatItem->Animation.Velocity.z <= 0) laraItem->Animation.TargetState = SPEEDBOAT_STATE_IDLE; - else if (!(TrInput & VEHICLE_IN_RIGHT)) + else if (!IsHeld(In::Right)) laraItem->Animation.TargetState = SPEEDBOAT_STATE_MOVING; break; @@ -764,7 +764,7 @@ namespace TEN::Entities::Vehicles case SPEEDBOAT_STATE_TURN_LEFT: if (speedboatItem->Animation.Velocity.z <= 0) laraItem->Animation.TargetState = SPEEDBOAT_STATE_IDLE; - else if (!(TrInput & VEHICLE_IN_LEFT)) + else if (!IsHeld(In::Left)) laraItem->Animation.TargetState = SPEEDBOAT_STATE_MOVING; break; @@ -901,7 +901,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != speedboatItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose = speedboatItem->Pose; @@ -913,7 +913,7 @@ namespace TEN::Entities::Vehicles SyncVehicleAnimation(*speedboatItem, *laraItem); Camera.targetElevation = -ANGLE(20.0f); - Camera.targetDistance = SECTOR(2); + Camera.targetDistance = BLOCK(2); auto pitch = speedboatItem->Animation.Velocity.z; speedboat->Pitch += (pitch - speedboat->Pitch) / 4; diff --git a/TombEngine/Objects/TR3/Entity/Compsognathus.cpp b/TombEngine/Objects/TR3/Entity/Compsognathus.cpp index 5e2553027..0f418aadc 100644 --- a/TombEngine/Objects/TR3/Entity/Compsognathus.cpp +++ b/TombEngine/Objects/TR3/Entity/Compsognathus.cpp @@ -35,7 +35,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto COMPY_PLAYER_ALERT_VELOCITY = 15; constexpr auto COMPY_HIT_FLAG = 1; - const auto CompyBite = CreatureBiteInfo(Vector3i::Zero, 2); + const auto CompyBite = CreatureBiteInfo(Vector3::Zero, 2); const auto CompyAttackJoints = std::vector{ 1, 2 }; enum CompyState @@ -120,7 +120,7 @@ namespace TEN::Entities::Creatures::TR3 float shortestDistance = INFINITY; for (auto& targetItem : g_Level.Items) { - if (targetItem.ObjectNumber == NO_ITEM || targetItem.Index == itemNumber || targetItem.RoomNumber == NO_ROOM) + if (!Objects.CheckID(targetItem.ObjectNumber) || targetItem.Index == itemNumber || targetItem.RoomNumber == NO_ROOM) continue; if (SameZone(creature, &targetItem)) diff --git a/TombEngine/Objects/TR3/Entity/Lizard.cpp b/TombEngine/Objects/TR3/Entity/Lizard.cpp index 7fe6eb5f9..f8d28e84c 100644 --- a/TombEngine/Objects/TR3/Entity/Lizard.cpp +++ b/TombEngine/Objects/TR3/Entity/Lizard.cpp @@ -27,9 +27,9 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto LIZARD_VAULT_SHIFT = 260; - const auto LizardBiteAttackBite = CreatureBiteInfo(Vector3i(0, -120, 120), 10); - const auto LizardSwipeAttackBite = CreatureBiteInfo(Vector3i::Zero, 5); - const auto LizardGasBite = CreatureBiteInfo(Vector3i(0, -64, 56), 9); + const auto LizardBiteAttackBite = CreatureBiteInfo(Vector3(0, -120, 120), 10); + const auto LizardSwipeAttackBite = CreatureBiteInfo(Vector3::Zero, 5); + const auto LizardGasBite = CreatureBiteInfo(Vector3(0, -64, 56), 9); const auto LizardSwipeAttackJoints = std::vector{ 5 }; const auto LizardBiteAttackJoints = std::vector{ 10 }; diff --git a/TombEngine/Objects/TR3/Entity/PunaBoss.cpp b/TombEngine/Objects/TR3/Entity/PunaBoss.cpp index e4eca8867..db3ad0745 100644 --- a/TombEngine/Objects/TR3/Entity/PunaBoss.cpp +++ b/TombEngine/Objects/TR3/Entity/PunaBoss.cpp @@ -36,8 +36,8 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto PUNA_EXPLOSION_MAIN_COLOR = Vector4(0.0f, 0.7f, 0.3f, 0.5f); constexpr auto PUNA_EXPLOSION_SECOND_COLOR = Vector4(0.1f, 0.3f, 0.7f, 0.5f); - const auto PunaBossHeadBite = CreatureBiteInfo(Vector3i::Zero, 8); - const auto PunaBossHandBite = CreatureBiteInfo(Vector3i::Zero, 14); + const auto PunaBossHeadBite = CreatureBiteInfo(Vector3::Zero, 8); + const auto PunaBossHandBite = CreatureBiteInfo(Vector3::Zero, 14); enum PunaState { @@ -260,7 +260,7 @@ namespace TEN::Entities::Creatures::TR3 auto hitPos = Vector3i::Zero; MESH_INFO* mesh = nullptr; - if (ObjectOnLOS2(&origin, &target, &hitPos, &mesh, ID_LARA) == GetLaraInfo(creature.Enemy)->ItemNumber) + if (ObjectOnLOS2(&origin, &target, &hitPos, &mesh, ID_LARA) == creature.Enemy->Index) { if (creature.Enemy->HitPoints <= PUNA_LIGHTNING_DAMAGE) { diff --git a/TombEngine/Objects/TR3/Entity/Shiva.cpp b/TombEngine/Objects/TR3/Entity/Shiva.cpp index c94a5f6d8..07bebbc8b 100644 --- a/TombEngine/Objects/TR3/Entity/Shiva.cpp +++ b/TombEngine/Objects/TR3/Entity/Shiva.cpp @@ -33,8 +33,8 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto SHIVA_SWAPMESH_TIME = 3; constexpr auto PLAYER_ANIM_SHIVA_DEATH = 7; // TODO: Move to LaraExtraAnims enum. - const auto ShivaBiteLeft = CreatureBiteInfo(Vector3i(0, 0, 920), 13); - const auto ShivaBiteRight = CreatureBiteInfo(Vector3i(0, 0, 920), 22); + const auto ShivaBiteLeft = CreatureBiteInfo(Vector3(0, 0, 920), 13); + const auto ShivaBiteRight = CreatureBiteInfo(Vector3(0, 0, 920), 22); const auto ShivaAttackLeftJoints = std::vector{ 10, 13 }; const auto ShivaAttackRightJoints = std::vector{ 22, 25 }; diff --git a/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp b/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp index dcf338306..40fe84005 100644 --- a/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp +++ b/TombEngine/Objects/TR3/Entity/SophiaLeigh.cpp @@ -63,9 +63,9 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto SOPHIALEIGH_VAULT_SHIFT = 96; - const auto SophiaLeighStaffBite = CreatureBiteInfo(Vector3i(-28, 56, 356), 10); - const auto SophiaLeighLeftBite = CreatureBiteInfo(Vector3i(-72, 48, 356), 10); - const auto SophiaLeighRightBite = CreatureBiteInfo(Vector3i(16, 48, 304), 10); + const auto SophiaLeighStaffBite = CreatureBiteInfo(Vector3(-28, 56, 356), 10); + const auto SophiaLeighLeftBite = CreatureBiteInfo(Vector3(-72, 48, 356), 10); + const auto SophiaLeighRightBite = CreatureBiteInfo(Vector3(16, 48, 304), 10); struct SophiaData { diff --git a/TombEngine/Objects/TR3/Entity/WaspMutant.cpp b/TombEngine/Objects/TR3/Entity/WaspMutant.cpp index bff9585d7..7bf1c57b7 100644 --- a/TombEngine/Objects/TR3/Entity/WaspMutant.cpp +++ b/TombEngine/Objects/TR3/Entity/WaspMutant.cpp @@ -28,8 +28,8 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto WaspVenomSackLightColor = Vector4(0.0f, 0.35f, 0.0f, 1.0f); - const auto WaspBite = CreatureBiteInfo(Vector3i(0, 0, -260), 12); - const auto WaspVenomSackBite = CreatureBiteInfo(Vector3i::Zero, 10); + const auto WaspBite = CreatureBiteInfo(Vector3(0, 0, -260), 12); + const auto WaspVenomSackBite = CreatureBiteInfo(Vector3::Zero, 10); enum WaspMutantState { diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp index 9867ccc93..b2469bcfc 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp @@ -36,8 +36,8 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto CIVVY_TARGET_ALERT_VELOCITY = 10.0f; constexpr auto CIVVY_VAULT_SHIFT = 260; - const auto CivvyBiteLeft = CreatureBiteInfo(Vector3i::Zero, 10); - const auto CivvyBiteRight = CreatureBiteInfo(Vector3i::Zero, 13); + const auto CivvyBiteLeft = CreatureBiteInfo(Vector3::Zero, 10); + const auto CivvyBiteRight = CreatureBiteInfo(Vector3::Zero, 13); const auto CivvyAttackJoints = std::vector{ 10, 13 }; const auto CivvyExcludedTargets = std::vector diff --git a/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp b/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp index 043d53a2b..1529a3e4b 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_claw_mutant.cpp @@ -35,9 +35,9 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto CLAW_MUTANT_WALK_TURN_RATE_MAX = ANGLE(3.0f); constexpr auto CLAW_MUTANT_RUN_TURN_RATE_MAX = ANGLE(4.0f); - const auto ClawMutantLeftBite = CreatureBiteInfo(Vector3i(19, -13, 3), 7); - const auto ClawMutantRightBite = CreatureBiteInfo(Vector3i(19, -13, 3), 4); - const auto ClawMutantTailBite = CreatureBiteInfo(Vector3i(-32, -16, -119), 13); + const auto ClawMutantLeftBite = CreatureBiteInfo(Vector3(19, -13, 3), 7); + const auto ClawMutantRightBite = CreatureBiteInfo(Vector3(19, -13, 3), 4); + const auto ClawMutantTailBite = CreatureBiteInfo(Vector3(-32, -16, -119), 13); enum ClawMutantState { diff --git a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp index fdbf30a81..2ca929e2b 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp @@ -24,7 +24,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto COBRA_DISTURBANCE_VELOCITY = 15.0f; constexpr auto COBRA_SLEEP_FRAME = 45; - const auto CobraBite = CreatureBiteInfo(Vector3i::Zero, 13); + const auto CobraBite = CreatureBiteInfo(Vector3::Zero, 13); const auto CobraAttackJoints = std::vector{ 13 }; enum CobraState diff --git a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp index c13655010..b1e1107a4 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp @@ -410,7 +410,7 @@ namespace TEN::Entities::Creatures::TR3 int y = abs(pos->Position.y - item->Pose.Position.y); int z = pos->Position.z - item->Pose.Position.z; - if (x < -distance || x > distance || z < -distance || z > distance || y < -SECTOR(3) || y > SECTOR(3)) + if (x < -distance || x > distance || z < -distance || z > distance || y < -BLOCK(3) || y > BLOCK(3)) return false; if ((pow(x, 2) + pow(z, 2)) > pow(distance, 2)) diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index 9d0899b71..92f05df6d 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -21,13 +21,13 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR3 { - constexpr auto FLAMETHROWER_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); - constexpr auto FLAMETHROWER_IDLE_RANGE = SQUARE(SECTOR(2)); - constexpr auto FLAMETHROWER_AWARE_RANGE = SQUARE(SECTOR(8)); + constexpr auto FLAMETHROWER_ATTACK_RANGE = SQUARE(BLOCK(1.5f)); + constexpr auto FLAMETHROWER_IDLE_RANGE = SQUARE(BLOCK(2)); + constexpr auto FLAMETHROWER_AWARE_RANGE = SQUARE(BLOCK(8)); constexpr auto FLAMETHROWER_WALK_TURN_RATE_MAX = ANGLE(5.0f); - const auto FlamethrowerBite = CreatureBiteInfo(Vector3i(0, 340, 64), 7); + const auto FlamethrowerBite = CreatureBiteInfo(Vector3(0, 340, 64), 7); // TODO enum FlamethrowerState diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index a1b19057e..8e895d943 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -23,7 +23,7 @@ namespace TEN::Entities::Creatures::TR3 // TODO: Range constants. - const auto MonkeyBite = CreatureBiteInfo(Vector3i(10, 10, 11), 13); + const auto MonkeyBite = CreatureBiteInfo(Vector3(10, 10, 11), 13); const auto MonkeyAttackJoints = std::vector{ 10, 13 }; enum MonkeyState @@ -244,7 +244,7 @@ namespace TEN::Entities::Creatures::TR3 } } else if ((item->AIBits & FOLLOW) && - (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2))) { if (item->Animation.RequiredState != NO_STATE) item->Animation.TargetState = item->Animation.RequiredState; @@ -305,7 +305,7 @@ namespace TEN::Entities::Creatures::TR3 } } else if (item->AIBits & FOLLOW && - (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2))) { if (item->Animation.RequiredState != NO_STATE) item->Animation.TargetState = item->Animation.RequiredState; @@ -333,7 +333,7 @@ namespace TEN::Entities::Creatures::TR3 { item->Animation.TargetState = MONKEY_STATE_BITE_ATTACK; } - else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD_ROLL; else item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; @@ -357,8 +357,8 @@ namespace TEN::Entities::Creatures::TR3 } else { - item->CarriedItem = creature->Enemy - g_Level.Items.data(); - RemoveDrawnItem(creature->Enemy - g_Level.Items.data()); + item->CarriedItem = creature->Enemy->Index; + RemoveDrawnItem(creature->Enemy->Index); creature->Enemy->RoomNumber = NO_ROOM; creature->Enemy->CarriedItem = NO_ITEM; @@ -448,7 +448,7 @@ namespace TEN::Entities::Creatures::TR3 break; } else if ((item->AIBits & FOLLOW) && - (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2))) { item->Animation.TargetState = MONKEY_STATE_IDLE; } @@ -456,7 +456,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD_ROLL; else if (AI.distance < pow(682, 2)) item->Animation.TargetState = MONKEY_STATE_IDLE; - else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD_ROLL; break; diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index 227f8cf94..d28853496 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -21,7 +21,7 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR3 { - const auto MPGunBite = CreatureBiteInfo(Vector3i(0, 225, 50), 13); + const auto MPGunBite = CreatureBiteInfo(Vector3(0, 225, 50), 13); enum MPGunState { @@ -159,17 +159,17 @@ namespace TEN::Entities::Creatures::TR3 angle = CreatureTurn(item, creature->MaxTurn); - int x = item->Pose.Position.x + SECTOR(1) * phd_sin(item->Pose.Orientation.y + laraAI.angle); + int x = item->Pose.Position.x + BLOCK(1) * phd_sin(item->Pose.Orientation.y + laraAI.angle); int y = item->Pose.Position.y; - int z = item->Pose.Position.z + SECTOR(1) * phd_cos(item->Pose.Orientation.y + laraAI.angle); + int z = item->Pose.Position.z + BLOCK(1) * phd_cos(item->Pose.Orientation.y + laraAI.angle); int height = GetCollision(x, y, z, item->RoomNumber).Position.Floor; - bool cover = (item->Pose.Position.y > (height + CLICK(3)) && item->Pose.Position.y < (height + CLICK(4.5f)) && laraAI.distance > pow(SECTOR(1), 2)); + bool cover = (item->Pose.Position.y > (height + CLICK(3)) && item->Pose.Position.y < (height + CLICK(4.5f)) && laraAI.distance > pow(BLOCK(1), 2)); auto* enemy = creature->Enemy; creature->Enemy = LaraItem; - if (laraAI.distance < pow(SECTOR(1), 2) || item->HitStatus || TargetVisible(item, &laraAI)) + if (laraAI.distance < pow(BLOCK(1), 2) || item->HitStatus || TargetVisible(item, &laraAI)) { if (!creature->Alerted) SoundEffect(SFX_TR3_AMERCAN_HOY, &item->Pose); @@ -242,7 +242,7 @@ namespace TEN::Entities::Creatures::TR3 } } else if (creature->Mood == MoodType::Bored || - (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2)))) + (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2)))) { if (AI.ahead) { @@ -328,7 +328,7 @@ namespace TEN::Entities::Creatures::TR3 break; } else if (Targetable(item, &AI) || - (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2)))) + (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2)))) { item->Animation.TargetState = MPGUN_STATE_WAIT; } @@ -451,7 +451,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MPGUN_STATE_WAIT; } - if (AI.distance < pow(SECTOR(1.5f), 2)) + if (AI.distance < pow(BLOCK(1.5f), 2)) item->Animation.RequiredState = MPGUN_STATE_WALK; break; @@ -476,7 +476,7 @@ namespace TEN::Entities::Creatures::TR3 creature->MuzzleFlash[0].Delay = 2; } - if (AI.distance < pow(SECTOR(1.5f), 2)) + if (AI.distance < pow(BLOCK(1.5f), 2)) item->Animation.TargetState = MPGUN_STATE_WALK; break; diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index ddaa5d22b..ec5c198d4 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -18,8 +18,8 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR3 { - const auto MPStickBite1 = CreatureBiteInfo(Vector3i(247, 10, 11), 13); - const auto MPStickBite2 = CreatureBiteInfo(Vector3i(0, 0, 100), 6); + const auto MPStickBite1 = CreatureBiteInfo(Vector3(247, 10, 11), 13); + const auto MPStickBite2 = CreatureBiteInfo(Vector3(0, 0, 100), 6); const auto MPStickPunchAttackJoints = std::vector{ 10, 13 }; const auto MPStickKickAttackJoints = std::vector{ 5, 6 }; @@ -117,8 +117,8 @@ namespace TEN::Entities::Creatures::TR3 dx = target->Pose.Position.x - item->Pose.Position.x; dz = target->Pose.Position.z - item->Pose.Position.z; - if (dz > SECTOR(31.25f) || dz < -SECTOR(31.25f) || - dx > SECTOR(31.25f) || dx < -SECTOR(31.25f)) + if (dz > BLOCK(31.25f) || dz < -BLOCK(31.25f) || + dx > BLOCK(31.25f) || dx < -BLOCK(31.25f)) { continue; } @@ -156,8 +156,8 @@ namespace TEN::Entities::Creatures::TR3 auto* enemy = creature->Enemy; creature->Enemy = LaraItem; - if (item->HitStatus || ((laraAI.distance < pow(SECTOR(1), 2) || - TargetVisible(item, &laraAI)) && abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < SECTOR(1))) + if (item->HitStatus || ((laraAI.distance < pow(BLOCK(1), 2) || + TargetVisible(item, &laraAI)) && abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < BLOCK(1))) { if (!creature->Alerted) SoundEffect(SFX_TR3_AMERCAN_HOY, &item->Pose); @@ -205,7 +205,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MPSTICK_STATE_RUN; } else if (creature->Mood == MoodType::Bored || - (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2)))) + (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2)))) { if (item->Animation.RequiredState != NO_STATE) item->Animation.TargetState = item->Animation.RequiredState; @@ -214,11 +214,11 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = MPSTICK_STATE_RUN; } - else if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) item->Animation.TargetState = MPSTICK_STATE_AIM0; - else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = MPSTICK_STATE_AIM1; - else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = MPSTICK_STATE_WALK; else item->Animation.TargetState = MPSTICK_STATE_RUN; @@ -245,11 +245,11 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MPSTICK_STATE_STOP; } } - else if (AI.bite && AI.distance < pow(SECTOR(1.5f), 2) && AI.xAngle < 0) + else if (AI.bite && AI.distance < pow(BLOCK(1.5f), 2) && AI.xAngle < 0) item->Animation.TargetState = MPSTICK_STATE_KICK; - else if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) item->Animation.TargetState = MPSTICK_STATE_STOP; - else if (AI.bite && AI.distance < pow(SECTOR(1.25f), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(1.25f), 2)) item->Animation.TargetState = MPSTICK_STATE_AIM2; else item->Animation.TargetState = MPSTICK_STATE_RUN; @@ -272,11 +272,11 @@ namespace TEN::Entities::Creatures::TR3 break; } - else if (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + else if (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(BLOCK(2), 2))) item->Animation.TargetState = MPSTICK_STATE_STOP; else if (creature->Mood == MoodType::Bored) item->Animation.TargetState = MPSTICK_STATE_WALK; - else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = MPSTICK_STATE_WALK; break; @@ -291,7 +291,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) item->Animation.TargetState = MPSTICK_STATE_PUNCH0; else item->Animation.TargetState = MPSTICK_STATE_STOP; @@ -308,7 +308,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) + if (AI.ahead && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = MPSTICK_STATE_PUNCH1; else item->Animation.TargetState = MPSTICK_STATE_STOP; @@ -325,7 +325,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if (AI.bite && AI.distance < pow(SECTOR(1.25f), 2)) + if (AI.bite && AI.distance < pow(BLOCK(1.25f), 2)) item->Animation.TargetState = MPSTICK_STATE_PUNCH2; else item->Animation.TargetState = MPSTICK_STATE_WALK; @@ -355,7 +355,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!creature->Flags && enemy != nullptr) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.25f)) { DoDamage(enemy, 5); CreatureEffect(item, MPStickBite1, DoBloodSplat); @@ -390,7 +390,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!creature->Flags && creature->Enemy != nullptr) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.25f)) { DoDamage(creature->Enemy, 5); CreatureEffect(item, MPStickBite1, DoBloodSplat); @@ -400,7 +400,7 @@ namespace TEN::Entities::Creatures::TR3 } } - if (AI.ahead && AI.distance > pow(SECTOR(1), 2) && AI.distance < pow(SECTOR(1.25f), 2)) + if (AI.ahead && AI.distance > pow(BLOCK(1), 2) && AI.distance < pow(BLOCK(1.25f), 2)) item->Animation.TargetState = MPSTICK_STATE_PUNCH2; break; @@ -428,7 +428,7 @@ namespace TEN::Entities::Creatures::TR3 { if (creature->Flags != 2 && creature->Enemy) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.25f)) { DoDamage(creature->Enemy, 6); CreatureEffect(item, MPStickBite1, DoBloodSplat); @@ -462,7 +462,7 @@ namespace TEN::Entities::Creatures::TR3 if (!creature->Flags != 1 && creature->Enemy && item->Animation.FrameNumber > GetAnimData(item).frameBase + 8) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.25f)) { DoDamage(creature->Enemy, 9); CreatureEffect(item, MPStickBite2, DoBloodSplat); diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index 9bc22f61f..7387baab4 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -30,7 +30,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto RAPTOR_RUN_TURN_RATE_MAX = ANGLE(2.0f); constexpr auto RAPTOR_ATTACK_TURN_RATE_MAX = ANGLE(2.0f); - const auto RaptorBite = CreatureBiteInfo(Vector3i(0, 66, 318), 22); + const auto RaptorBite = CreatureBiteInfo(Vector3(0, 66, 318), 22); const auto RaptorAttackJoints = std::vector{ 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 22, 23 }; enum RaptorState @@ -114,7 +114,7 @@ namespace TEN::Entities::Creatures::TR3 if (nearestItem != nullptr && (nearestItem->ObjectNumber != ID_RAPTOR || - (Random::TestProbability(1 / 30.0f) && minDistance < SQUARE(SECTOR(2))))) + (Random::TestProbability(1 / 30.0f) && minDistance < SQUARE(BLOCK(2))))) { creature->Enemy = nearestItem; } @@ -249,7 +249,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!(creature->Flags & 1) && creature->Enemy != nullptr) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.5f)) { if (creature->Enemy->HitPoints <= 0) creature->Flags |= 2; @@ -286,7 +286,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!(creature->Flags & 1) && creature->Enemy != nullptr) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.5f)) { if (creature->Enemy->HitPoints <= 0) creature->Flags |= 2; @@ -322,7 +322,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!(creature->Flags & 1) && creature->Enemy != nullptr) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.5f)) { if (creature->Enemy->HitPoints <= 0) creature->Flags |= 2; diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp index 5f2251c44..0cd3f0306 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp @@ -18,7 +18,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto SCUBA_DIVER_ATTACK_DAMAGE = 50; constexpr auto SCUBA_DIVER_SWIM_TURN_RATE_MAX = ANGLE(3.0f); - const auto ScubaGunBite = CreatureBiteInfo(Vector3i(17, 164, 44), 18); + const auto ScubaGunBite = CreatureBiteInfo(Vector3(17, 164, 44), 18); enum ScubaDiverState { @@ -165,7 +165,7 @@ namespace TEN::Entities::Creatures::TR3 } angle = CreatureTurn(item, creature->MaxTurn); - waterHeight = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber) + SECTOR(0.5f); + waterHeight = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber) + BLOCK(0.5f); switch (item->Animation.ActiveState) { diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp index e5495ccf2..e894a11e9 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp @@ -34,7 +34,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto TIGER_PLAYER_ALERT_VELOCITY = 10.0f; - const auto TigerBite = CreatureBiteInfo(Vector3i(19, -13, 3), 26); + const auto TigerBite = CreatureBiteInfo(Vector3(19, -13, 3), 26); const auto TigerSwipeAttackJoints = std::vector{ 14, 15, 16 }; const auto TigerBiteAttackJoints = std::vector{ 22, 25, 26 }; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp index ad4e049f5..b5aaa2f20 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp @@ -29,8 +29,8 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto TONY_EXPLOSION_COUNT_MAX = 60; constexpr auto TONY_EFFECT_COLOR = Vector4(0.8f, 0.4f, 0.0f, 0.5f); - const auto TonyLeftHandBite = CreatureBiteInfo(Vector3i::Zero, 10); - const auto TonyRightHandBite = CreatureBiteInfo(Vector3i::Zero, 13); + const auto TonyLeftHandBite = CreatureBiteInfo(Vector3::Zero, 10); + const auto TonyRightHandBite = CreatureBiteInfo(Vector3::Zero, 13); // I can't set it to the TonyFlame struct since the control of the // flame use fxNumber as argument or that FX_INFO have no void* to hold custom data. diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp index 97ac69557..67c2e4419 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp @@ -59,7 +59,7 @@ namespace TEN::Entities::Creatures::TR3 tRexItem->Animation.TargetState = TREX_STATE_KILL; if (laraItem->RoomNumber != tRexItem->RoomNumber) - ItemNewRoom(Lara.ItemNumber, tRexItem->RoomNumber); + ItemNewRoom(laraItem->Index, tRexItem->RoomNumber); laraItem->Pose = Pose( tRexItem->Pose.Position, @@ -114,7 +114,7 @@ namespace TEN::Entities::Creatures::TR3 creature->Flags = (creature->Mood != MoodType::Escape && !ai.ahead && ai.enemyFacing > -FRONT_ARC && ai.enemyFacing < FRONT_ARC); if (ai.distance > pow(1500, 2) && - ai.distance < pow(SECTOR(4), 2) && + ai.distance < pow(BLOCK(4), 2) && ai.bite && !creature->Flags) { creature->Flags = 1; @@ -150,7 +150,7 @@ namespace TEN::Entities::Creatures::TR3 case TREX_STATE_RUN_FORWARD: creature->MaxTurn = TREX_RUN_TURN_RATE_MAX; - if (ai.distance < pow(SECTOR(5), 2) && ai.bite) + if (ai.distance < pow(BLOCK(5), 2) && ai.bite) item->Animation.TargetState = TREX_STATE_IDLE; else if (creature->Flags) item->Animation.TargetState = TREX_STATE_IDLE; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index c8fcd8f31..7ec9fadcd 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -24,9 +24,9 @@ namespace TEN::Entities::Creatures::TR3 { constexpr auto TRIBESMAN_DART_DAMAGE = -25; // NOTE: Negative value gives poison. - const auto TribesmanAxeBite = CreatureBiteInfo(Vector3i(0, 56, 265), 13); - const auto TribesmanDartBite1 = CreatureBiteInfo(Vector3i(0, 0, -200), 13); - const auto TribesmanDartBite2 = CreatureBiteInfo(Vector3i(8, 40, -248), 13); + const auto TribesmanAxeBite = CreatureBiteInfo(Vector3(0, 56, 265), 13); + const auto TribesmanDartBite1 = CreatureBiteInfo(Vector3(0, 0, -200), 13); + const auto TribesmanDartBite2 = CreatureBiteInfo(Vector3(8, 40, -248), 13); const auto TribesmanAxeAttackJoints = std::vector{ 13 }; const auto TribesmanDartAttackJoints = std::vector{ 10, 13 }; // TODO: Check. @@ -132,7 +132,7 @@ namespace TEN::Entities::Creatures::TR3 GetCreatureMood(item, &AI, true); if (creature->Enemy == LaraItem && - creature->HurtByLara && AI.distance > pow(SECTOR(3), 2) && + creature->HurtByLara && AI.distance > pow(BLOCK(3), 2) && AI.enemyFacing < ANGLE(67.0f) && AI.enemyFacing > -ANGLE(67.0f)) { creature->Mood = MoodType::Escape; @@ -174,14 +174,14 @@ namespace TEN::Entities::Creatures::TR3 { item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_AXE_ATTACK; } - else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(1), 2)) { if (Random::TestProbability(1 / 2.0f)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; else item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_AXE_ATTACK; } - else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) + else if (AI.ahead && AI.distance < pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } @@ -217,7 +217,7 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = TRIBESMAN_STATE_AXE_ATTACK_HIGH_START; } - else if (AI.distance < pow(SECTOR(2), 2)) + else if (AI.distance < pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } @@ -256,7 +256,7 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = TRIBESMAN_STATE_IDLE; } - else if (AI.distance > pow(SECTOR(2), 2)) + else if (AI.distance > pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_RUN_FORWARD; } @@ -284,7 +284,7 @@ namespace TEN::Entities::Creatures::TR3 { item->Animation.TargetState = TRIBESMAN_STATE_IDLE; } - else if (AI.bite || AI.distance < pow(SECTOR(2), 2)) + else if (AI.bite || AI.distance < pow(BLOCK(2), 2)) { if (Random::TestProbability(1 / 2.0f)) { @@ -338,7 +338,7 @@ namespace TEN::Entities::Creatures::TR3 { if (creature->Enemy != nullptr) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f) && + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.5f) && creature->Flags >= TribesmanAxeHit[item->Animation.ActiveState][0] && creature->Flags <= TribesmanAxeHit[item->Animation.ActiveState][1]) { @@ -446,8 +446,8 @@ namespace TEN::Entities::Creatures::TR3 } if (item->HitStatus || - (creature->Enemy == LaraItem && (AI.distance < pow(SECTOR(1), 2) || - TargetVisible(item, &AI)) && (abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < SECTOR(2)))) + (creature->Enemy == LaraItem && (AI.distance < pow(BLOCK(1), 2) || + TargetVisible(item, &AI)) && (abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < BLOCK(2)))) { AlertAllGuards(itemNumber); } @@ -483,11 +483,11 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = TRIBESMAN_STATE_RUN_FORWARD; } - else if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_IDLE; } - else if (AI.bite && AI.distance < pow(SECTOR(2), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } @@ -532,11 +532,11 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = TRIBESMAN_STATE_RUN_FORWARD; } - else if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_AXE_ATTACK_HIGH_CONTINUE; } - else if (AI.bite && AI.distance < pow(SECTOR(2), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } @@ -558,11 +558,11 @@ namespace TEN::Entities::Creatures::TR3 case TRIBESMAN_STATE_WALK_FORWARD: creature->MaxTurn = ANGLE(9.0f); - if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_IDLE; } - else if (AI.bite && AI.distance < pow(SECTOR(2), 2)) + else if (AI.bite && AI.distance < pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } @@ -589,7 +589,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; } } - else if (AI.distance > pow(SECTOR(2), 2)) + else if (AI.distance > pow(BLOCK(2), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_RUN_FORWARD; } @@ -601,7 +601,7 @@ namespace TEN::Entities::Creatures::TR3 creature->Flags &= 0x0FFF; tilt = angle / 4; - if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) + if (AI.bite && AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = TRIBESMAN_STATE_IDLE; } @@ -626,7 +626,7 @@ namespace TEN::Entities::Creatures::TR3 break; case TRIBESMAN_STATE_AXE_ATTACK_HIGH_START: - if (!AI.bite || AI.distance > pow(SECTOR(0.5f), 2)) + if (!AI.bite || AI.distance > pow(BLOCK(0.5f), 2)) item->Animation.TargetState = TRIBESMAN_STATE_IDLE; else item->Animation.TargetState = TRIBESMAN_STATE_AXE_ATTACK_HIGH_CONTINUE; @@ -679,7 +679,7 @@ namespace TEN::Entities::Creatures::TR3 { if (creature->Enemy != nullptr && !(creature->Flags & 0xf000)) { - if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) + if (Vector3i::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= BLOCK(0.5f)) { DoDamage(creature->Enemy, 5); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp index 72f3bc5a3..3611e0177 100644 --- a/TombEngine/Objects/TR3/Trap/train.cpp +++ b/TombEngine/Objects/TR3/Trap/train.cpp @@ -53,7 +53,7 @@ void TrainControl(short itemNumber) item->Pose.Position.z += item->ItemFlags[1] * cosY; short roomNumber; - long rh = TrainTestHeight(item, 0, SECTOR(5), &roomNumber); + long rh = TrainTestHeight(item, 0, BLOCK(5), &roomNumber); long floorHeight = TrainTestHeight(item, 0, 0, &roomNumber); item->Pose.Position.y = floorHeight; @@ -71,7 +71,7 @@ void TrainControl(short itemNumber) item->Pose.Orientation.x = -(rh - floorHeight) * 2; - TriggerDynamicLight(item->Pose.Position.x + SECTOR(3) * sinY, item->Pose.Position.y, item->Pose.Position.z + SECTOR(3) * cosY, 16, 31, 31, 31); + TriggerDynamicLight(item->Pose.Position.x + BLOCK(3) * sinY, item->Pose.Position.y, item->Pose.Position.z + BLOCK(3) * cosY, 16, 31, 31, 31); if (item->ItemFlags[1] != TRAIN_VEL) { @@ -81,8 +81,8 @@ void TrainControl(short itemNumber) if (!UseForcedFixedCamera) { - ForcedFixedCamera.x = item->Pose.Position.x + SECTOR(8) * sinY; - ForcedFixedCamera.z = item->Pose.Position.z + SECTOR(8) * cosY; + ForcedFixedCamera.x = item->Pose.Position.x + BLOCK(8) * sinY; + ForcedFixedCamera.z = item->Pose.Position.z + BLOCK(8) * cosY; ForcedFixedCamera.y = GetCollision(ForcedFixedCamera.x, item->Pose.Position.y - CLICK(2), ForcedFixedCamera.z, item->RoomNumber).Position.Floor; @@ -133,5 +133,5 @@ void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) long x = laraItem->Pose.Position.x + CLICK(1) * sinY; long z = laraItem->Pose.Position.z + CLICK(1) * cosY; - DoLotsOfBlood(x, laraItem->Pose.Position.y - CLICK(2), z, SECTOR(1), item->Pose.Orientation.y, laraItem->RoomNumber, 15); + DoLotsOfBlood(x, laraItem->Pose.Position.y - CLICK(2), z, BLOCK(1), item->Pose.Orientation.y, laraItem->RoomNumber, 15); } diff --git a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp index 8a32ce91b..4d2b74942 100644 --- a/TombEngine/Objects/TR3/Vehicles/big_gun.cpp +++ b/TombEngine/Objects/TR3/Vehicles/big_gun.cpp @@ -47,7 +47,7 @@ namespace TEN::Entities::Vehicles VehicleMountType::Back }; - const auto BigGunBite = CreatureBiteInfo(Vector3i(0, 0, BGUN_ROCKET_SPAWN_DISTANCE), 2); + const auto BigGunBite = CreatureBiteInfo(Vector3(0, 0, BGUN_ROCKET_SPAWN_DISTANCE), 2); enum BigGunState { @@ -105,7 +105,7 @@ namespace TEN::Entities::Vehicles int z = laraItem->Pose.Position.z - bigGunItem->Pose.Position.z; int distance = SQUARE(x) + SQUARE(y) + SQUARE(z); - if (distance > SECTOR(30)) + if (distance > BLOCK(30)) return false; short deltaAngle = abs(laraItem->Pose.Orientation.y - bigGunItem->Pose.Orientation.y); @@ -188,11 +188,11 @@ namespace TEN::Entities::Vehicles if (!bigGun->BarrelRotation) bigGun->IsBarrelRotating = false; - if (TrInput & VEHICLE_IN_DISMOUNT || laraItem->HitPoints <= 0) + if (IsHeld(In::Brake) || laraItem->HitPoints <= 0) bigGun->Flags = BGUN_FLAG_AUTO_ROT; else { - if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_FIRE) && !bigGun->FireCount) + if ((IsHeld(In::Accelerate) || IsHeld(In::Fire)) && !bigGun->FireCount) { BigGunFire(bigGunItem, laraItem); bigGun->FireCount = BGUN_RECOIL_TIME; @@ -200,7 +200,7 @@ namespace TEN::Entities::Vehicles bigGun->IsBarrelRotating = true; } - if (TrInput & VEHICLE_IN_UP) + if (IsHeld(In::Forward)) { if (bigGun->TurnRate.x < 0) bigGun->TurnRate.x /= 2; @@ -209,7 +209,7 @@ namespace TEN::Entities::Vehicles if (bigGun->TurnRate.x > (BGUN_TURN_RATE_MAX / 2)) bigGun->TurnRate.x = (BGUN_TURN_RATE_MAX / 2); } - else if (TrInput & VEHICLE_IN_DOWN) + else if (IsHeld(In::Back)) { if (bigGun->TurnRate.x > 0) bigGun->TurnRate.x /= 2; @@ -225,7 +225,7 @@ namespace TEN::Entities::Vehicles bigGun->TurnRate.x = 0; } - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) { if (bigGun->TurnRate.y > 0) bigGun->TurnRate.y /= 2; @@ -234,7 +234,7 @@ namespace TEN::Entities::Vehicles if (bigGun->TurnRate.y < -BGUN_TURN_RATE_MAX) bigGun->TurnRate.y = -BGUN_TURN_RATE_MAX; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { if (bigGun->TurnRate.y < 0) bigGun->TurnRate.y /= 2; diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp index 6e75e802e..6d3f69475 100644 --- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp +++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp @@ -62,15 +62,6 @@ namespace TEN::Entities::Vehicles constexpr auto KAYAK_MAX_KICK = -80; constexpr auto KAYAK_MIN_BOUNCE = (KAYAK_VELOCITY_MAX / 2) / VEHICLE_VELOCITY_SCALE; - // TODO: Kayak control is fairly unique. Keep this? @Sezz 2022.06.25 - constexpr auto KAYAK_IN_FORWARD = IN_FORWARD; - constexpr auto KAYAK_IN_BACK = IN_BACK; - constexpr auto KAYAK_IN_LEFT = IN_LEFT; - constexpr auto KAYAK_IN_RIGHT = IN_RIGHT; - constexpr auto KAYAK_IN_HOLD = IN_WALK; - constexpr auto KAYAK_IN_HOLD_LEFT = IN_LSTEP; - constexpr auto KAYAK_IN_HOLD_RIGHT = IN_RSTEP; - const std::vector KayakLaraLegJoints = { LM_HIPS, LM_LTHIGH, LM_LSHIN, LM_LFOOT, LM_RTHIGH, LM_RSHIN, LM_RFOOT }; const std::vector KayakMountTypes = { @@ -193,7 +184,7 @@ namespace TEN::Entities::Vehicles } if (laraItem->RoomNumber != kayakItem->RoomNumber) - ItemNewRoom(lara->ItemNumber, kayakItem->RoomNumber); + ItemNewRoom(laraItem->Index, kayakItem->RoomNumber); DoVehicleFlareDiscard(laraItem); laraItem->Pose.Position = kayakItem->Pose.Position; @@ -364,11 +355,11 @@ namespace TEN::Entities::Vehicles int KayakDoShift(ItemInfo* kayakItem, Vector3i* pos, Vector3i* old) { - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); - int xOld = old->x / SECTOR(1); - int zOld = old->z / SECTOR(1); + int xOld = old->x / BLOCK(1); + int zOld = old->z / BLOCK(1); int xShift = pos->x & WALL_MASK; int zShift = pos->z & WALL_MASK; @@ -389,7 +380,7 @@ namespace TEN::Entities::Vehicles } else { - kayakItem->Pose.Position.z += SECTOR(1) - zShift; + kayakItem->Pose.Position.z += BLOCK(1) - zShift; return (kayakItem->Pose.Position.x - pos->x); } } @@ -405,7 +396,7 @@ namespace TEN::Entities::Vehicles else { - kayakItem->Pose.Position.x += SECTOR(1) - xShift; + kayakItem->Pose.Position.x += BLOCK(1) - xShift; return (pos->z - kayakItem->Pose.Position.z); } } @@ -420,7 +411,7 @@ namespace TEN::Entities::Vehicles if (pos->z > old->z) z = -zShift - 1; else - z = SECTOR(1) - zShift; + z = BLOCK(1) - zShift; } probe = GetCollision(pos->x, pos->y, old->z, kayakItem->RoomNumber); @@ -429,7 +420,7 @@ namespace TEN::Entities::Vehicles if (pos->x > old->x) x = -xShift - 1; else - x = SECTOR(1) - xShift; + x = BLOCK(1) - xShift; } if (x && z) @@ -623,30 +614,30 @@ namespace TEN::Entities::Vehicles switch (laraItem->Animation.ActiveState) { case KAYAK_STATE_IDLE: - if (TrInput & VEHICLE_IN_DISMOUNT && + if (IsHeld(In::Brake) && !lara->Context.WaterCurrentActive && !lara->Context.WaterCurrentPull.x && !lara->Context.WaterCurrentPull.z) { - if (TrInput & KAYAK_IN_LEFT && !(TrInput & KAYAK_IN_HOLD) && KayakCanGetOut(kayakItem, -1)) + if (IsHeld(In::Left) && !IsHeld(In::Walk) && KayakCanGetOut(kayakItem, -1)) { laraItem->Animation.TargetState = KAYAK_STATE_DISMOUNT; laraItem->Animation.RequiredState = KAYAK_STATE_DISMOUNT_LEFT; } - else if (TrInput & KAYAK_IN_RIGHT && !(TrInput & KAYAK_IN_HOLD) && KayakCanGetOut(kayakItem, 1)) + else if (IsHeld(In::Right) && !IsHeld(In::Walk) && KayakCanGetOut(kayakItem, 1)) { laraItem->Animation.TargetState = KAYAK_STATE_DISMOUNT; laraItem->Animation.RequiredState = KAYAK_STATE_DISMOUNT_RIGHT; } } - else if (TrInput & KAYAK_IN_FORWARD) + else if (IsHeld(In::Forward)) { laraItem->Animation.TargetState = KAYAK_STATE_TURN_RIGHT; kayak->Turn = false; kayak->Forward = true; } - else if (TrInput & KAYAK_IN_BACK) + else if (IsHeld(In::Back)) laraItem->Animation.TargetState = KAYAK_STATE_BACK; - else if (TrInput & KAYAK_IN_LEFT && !(TrInput & KAYAK_IN_HOLD)) + else if (IsHeld(In::Left) && !IsHeld(In::Walk)) { laraItem->Animation.TargetState = KAYAK_STATE_TURN_LEFT; @@ -658,7 +649,7 @@ namespace TEN::Entities::Vehicles kayak->Forward = false; } - else if (TrInput & KAYAK_IN_RIGHT && !(TrInput & KAYAK_IN_HOLD)) + else if (IsHeld(In::Right) && !IsHeld(In::Walk)) { laraItem->Animation.TargetState = KAYAK_STATE_TURN_RIGHT; @@ -669,13 +660,13 @@ namespace TEN::Entities::Vehicles kayak->Forward = false; } - else if ((TrInput & KAYAK_IN_HOLD_LEFT || (TrInput & KAYAK_IN_HOLD && TrInput & KAYAK_IN_LEFT)) && + else if ((IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left))) && (kayak->Velocity || lara->Context.WaterCurrentPull.x || lara->Context.WaterCurrentPull.z)) { laraItem->Animation.TargetState = KAYAK_STATE_HOLD_LEFT; } - else if ((TrInput & KAYAK_IN_HOLD_RIGHT || (TrInput & KAYAK_IN_HOLD && TrInput & KAYAK_IN_RIGHT)) && + else if ((IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right))) && (kayak->Velocity || lara->Context.WaterCurrentPull.x || lara->Context.WaterCurrentPull.z)) { @@ -697,9 +688,9 @@ namespace TEN::Entities::Vehicles else if (frame > 2) kayak->LeftRightPaddleCount &= ~0x80; - if (TrInput & KAYAK_IN_FORWARD) + if (IsHeld(In::Forward)) { - if (TrInput & KAYAK_IN_LEFT && !(TrInput & KAYAK_IN_HOLD)) + if (IsHeld(In::Left) && !IsHeld(In::Walk)) { if ((kayak->LeftRightPaddleCount & ~0x80) >= 2) laraItem->Animation.TargetState = KAYAK_STATE_TURN_RIGHT; @@ -710,7 +701,7 @@ namespace TEN::Entities::Vehicles else laraItem->Animation.TargetState = KAYAK_STATE_IDLE; } - else if (!(TrInput & KAYAK_IN_LEFT)) + else if (!IsHeld(In::Left)) laraItem->Animation.TargetState = KAYAK_STATE_IDLE; if (frame == 7) @@ -756,9 +747,9 @@ namespace TEN::Entities::Vehicles else if (frame > 2) kayak->LeftRightPaddleCount &= ~0x80; - if (TrInput & KAYAK_IN_FORWARD) + if (IsHeld(In::Forward)) { - if (TrInput & KAYAK_IN_RIGHT && !(TrInput & KAYAK_IN_HOLD)) + if (IsHeld(In::Right) && !IsHeld(In::Walk)) { if ((kayak->LeftRightPaddleCount & ~0x80) >= 2) laraItem->Animation.TargetState = KAYAK_STATE_TURN_LEFT; @@ -770,7 +761,7 @@ namespace TEN::Entities::Vehicles laraItem->Animation.TargetState = KAYAK_STATE_IDLE; } - else if (!(TrInput & KAYAK_IN_RIGHT)) + else if (!IsHeld(In::Right)) laraItem->Animation.TargetState = KAYAK_STATE_IDLE; if (frame == 7) @@ -805,7 +796,7 @@ namespace TEN::Entities::Vehicles break; case KAYAK_STATE_BACK: - if (!(TrInput & KAYAK_IN_BACK)) + if (!IsHeld(In::Back)) laraItem->Animation.TargetState = KAYAK_STATE_IDLE; if (TestAnimNumber(*laraItem, KAYAK_ANIM_PADDLE_BACK)) @@ -832,7 +823,7 @@ namespace TEN::Entities::Vehicles break; case KAYAK_STATE_HOLD_LEFT: - if (!(TrInput & KAYAK_IN_HOLD_LEFT || (TrInput & KAYAK_IN_HOLD && TrInput & KAYAK_IN_LEFT)) || + if (!(IsHeld(In::StepLeft) || (IsHeld(In::Walk) && IsHeld(In::Left))) || (!kayak->Velocity && !lara->Context.WaterCurrentPull.x && !lara->Context.WaterCurrentPull.z)) @@ -868,7 +859,7 @@ namespace TEN::Entities::Vehicles break; case KAYAK_STATE_HOLD_RIGHT: - if (!(TrInput & KAYAK_IN_HOLD_RIGHT || (TrInput & KAYAK_IN_HOLD && TrInput & KAYAK_IN_RIGHT)) || + if (!(IsHeld(In::StepRight) || (IsHeld(In::Walk) && IsHeld(In::Right))) || (!kayak->Velocity && !lara->Context.WaterCurrentPull.x && !lara->Context.WaterCurrentPull.z)) @@ -1119,7 +1110,7 @@ namespace TEN::Entities::Vehicles if (kayakItem->RoomNumber != probe.RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose.Position = kayakItem->Pose.Position; diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp index 8cfc31b2b..3efcfbb67 100644 --- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp +++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp @@ -58,9 +58,6 @@ namespace TEN::Entities::Vehicles constexpr auto MINECART_WAKE_OFFSET = Vector3(BLOCK(1 / 6.0f), 0.0f, BLOCK(0.5f)); - constexpr auto MINECART_IN_DUCK = IN_CROUCH; - constexpr auto MINECART_IN_SWIPE = IN_ACTION | IN_DRAW; - int Wheels[4] = { 2, 3, 1, 4 }; const auto MinecartMountTypes = std::vector { @@ -604,11 +601,11 @@ namespace TEN::Entities::Vehicles switch (laraItem->Animation.ActiveState) { case MINECART_STATE_MOVE: - if (TrInput & MINECART_IN_SWIPE) + if (IsHeld(In::Action) || IsHeld(In::Draw)) laraItem->Animation.TargetState = MINECART_STATE_SWIPE; - else if (TrInput & MINECART_IN_DUCK) + else if (IsHeld(In::Crouch)) laraItem->Animation.TargetState = MINECART_STATE_DUCK; - else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) + else if (IsHeld(In::Brake) || IsHeld(In::Slow)) laraItem->Animation.TargetState = MINECART_STATE_BRAKE; else if (minecart->Velocity <= MINECART_STOP_VELOCITY_MIN || minecart->Flags & MINECART_FLAG_STOPPED) laraItem->Animation.TargetState = MINECART_STATE_IDLE; @@ -616,19 +613,19 @@ namespace TEN::Entities::Vehicles laraItem->Animation.TargetState = MINECART_STATE_FORWARD; else if (minecart->Gradient > MINECART_BACK_GRADIENT) laraItem->Animation.TargetState = MINECART_STATE_BACK; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = MINECART_STATE_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = MINECART_STATE_RIGHT; break; case MINECART_STATE_FORWARD: - if (TrInput & MINECART_IN_SWIPE) + if (IsHeld(In::Action) || IsHeld(In::Draw)) laraItem->Animation.TargetState = MINECART_STATE_SWIPE; - else if (TrInput & MINECART_IN_DUCK) + else if (IsHeld(In::Crouch)) laraItem->Animation.TargetState = MINECART_STATE_DUCK; - else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) + else if (IsHeld(In::Brake) || IsHeld(In::Slow)) laraItem->Animation.TargetState = MINECART_STATE_BRAKE; else if (minecart->Gradient > MINECART_FORWARD_GRADIENT) laraItem->Animation.TargetState = MINECART_STATE_MOVE; @@ -636,11 +633,11 @@ namespace TEN::Entities::Vehicles break; case MINECART_STATE_BACK: - if (TrInput & MINECART_IN_SWIPE) + if (IsHeld(In::Action) || IsHeld(In::Draw)) laraItem->Animation.TargetState = MINECART_STATE_SWIPE; - else if (TrInput & MINECART_IN_DUCK) + else if (IsHeld(In::Crouch)) laraItem->Animation.TargetState = MINECART_STATE_DUCK; - else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) + else if (IsHeld(In::Brake) || IsHeld(In::Slow)) laraItem->Animation.TargetState = MINECART_STATE_BRAKE; else if (minecart->Gradient < MINECART_BACK_GRADIENT) laraItem->Animation.TargetState = MINECART_STATE_MOVE; @@ -648,27 +645,27 @@ namespace TEN::Entities::Vehicles break; case MINECART_STATE_LEFT: - if (TrInput & MINECART_IN_SWIPE) + if (IsHeld(In::Action) || IsHeld(In::Draw)) laraItem->Animation.TargetState = MINECART_STATE_SWIPE; - else if (TrInput & MINECART_IN_DUCK) + else if (IsHeld(In::Crouch)) laraItem->Animation.TargetState = MINECART_STATE_DUCK; - else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) + else if (IsHeld(In::Brake) || IsHeld(In::Slow)) laraItem->Animation.TargetState = MINECART_STATE_BRAKE; - if (!(TrInput & VEHICLE_IN_LEFT)) + if (!IsHeld(In::Left)) laraItem->Animation.TargetState = MINECART_STATE_MOVE; break; case MINECART_STATE_RIGHT: - if (TrInput & MINECART_IN_SWIPE) + if (IsHeld(In::Action) || IsHeld(In::Draw)) laraItem->Animation.TargetState = MINECART_STATE_SWIPE; - else if (TrInput & MINECART_IN_DUCK) + else if (IsHeld(In::Crouch)) laraItem->Animation.TargetState = MINECART_STATE_DUCK; - else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) + else if (IsHeld(In::Brake) || IsHeld(In::Slow)) laraItem->Animation.TargetState = MINECART_STATE_BRAKE; - if (!(TrInput & VEHICLE_IN_RIGHT)) + if (!IsHeld(In::Right)) laraItem->Animation.TargetState = MINECART_STATE_MOVE; break; @@ -681,14 +678,14 @@ namespace TEN::Entities::Vehicles minecart->StopDelayTime = 64; } - if (TrInput & VEHICLE_IN_DISMOUNT && minecart->Flags & MINECART_FLAG_STOPPED) + if (IsHeld(In::Brake) && minecart->Flags & MINECART_FLAG_STOPPED) { - if (TrInput & VEHICLE_IN_LEFT && TestMinecartDismount(laraItem, -1)) + if (IsHeld(In::Left) && TestMinecartDismount(laraItem, -1)) { laraItem->Animation.TargetState = MINECART_STATE_DISMOUNT; minecart->Flags &= ~MINECART_FLAG_DISMOUNT_RIGHT; } - else if (TrInput & VEHICLE_IN_RIGHT && TestMinecartDismount(laraItem, 1)) + else if (IsHeld(In::Right) && TestMinecartDismount(laraItem, 1)) { laraItem->Animation.TargetState = MINECART_STATE_DISMOUNT; minecart->Flags |= MINECART_FLAG_DISMOUNT_RIGHT; @@ -697,7 +694,7 @@ namespace TEN::Entities::Vehicles if (minecart->Velocity > 0) { - if (TrInput & MINECART_IN_DUCK) + if (IsHeld(In::Crouch)) laraItem->Animation.TargetState = MINECART_STATE_DUCK; else laraItem->Animation.TargetState = MINECART_STATE_MOVE; @@ -706,11 +703,11 @@ namespace TEN::Entities::Vehicles break; case MINECART_STATE_DUCK: - if (TrInput & MINECART_IN_SWIPE) + if (IsHeld(In::Action) || IsHeld(In::Draw)) laraItem->Animation.TargetState = MINECART_STATE_SWIPE; - else if (TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) + else if (IsHeld(In::Brake) || IsHeld(In::Slow)) laraItem->Animation.TargetState = MINECART_STATE_BRAKE; - else if (!(TrInput & MINECART_IN_DUCK)) + else if (!(IsHeld(In::Crouch))) laraItem->Animation.TargetState = MINECART_STATE_IDLE; break; @@ -720,12 +717,12 @@ namespace TEN::Entities::Vehicles break; case MINECART_STATE_BRAKING: - if (TrInput & MINECART_IN_DUCK) + if (IsHeld(In::Crouch)) { laraItem->Animation.TargetState = MINECART_STATE_DUCK; StopSoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE); } - else if (!(TrInput & (VEHICLE_IN_BRAKE | VEHICLE_IN_SLOW)) || minecart->Flags & MINECART_FLAG_STOPPED) + else if (!(IsHeld(In::Brake) || IsHeld(In::Slow)) || minecart->Flags & MINECART_FLAG_STOPPED) { laraItem->Animation.TargetState = MINECART_STATE_MOVE; StopSoundEffect(SFX_TR3_VEHICLE_MINECART_BRAKE); @@ -975,7 +972,7 @@ namespace TEN::Entities::Vehicles if (probedRoomNumber != minecartItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probedRoomNumber); - ItemNewRoom(lara->ItemNumber, probedRoomNumber); + ItemNewRoom(laraItem->Index, probedRoomNumber); } TestTriggers(minecartItem, false); diff --git a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp index 69b9db9c2..58cf85cab 100644 --- a/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp +++ b/TombEngine/Objects/TR3/Vehicles/quad_bike.cpp @@ -29,12 +29,12 @@ namespace TEN::Entities::Vehicles { const CreatureBiteInfo QuadBikeEffectsPositions[6] = { - CreatureBiteInfo(Vector3i(-56, -32, -380), 0), - CreatureBiteInfo(Vector3i(56, -32, -380), 0), - CreatureBiteInfo(Vector3i(-8, 180, -48), 3), - CreatureBiteInfo(Vector3i(8, 180, -48), 4), - CreatureBiteInfo(Vector3i(90, 180, -32), 6), - CreatureBiteInfo(Vector3i(-90, 180, -32), 7) + CreatureBiteInfo(Vector3(-56, -32, -380), 0), + CreatureBiteInfo(Vector3(56, -32, -380), 0), + CreatureBiteInfo(Vector3(-8, 180, -48), 3), + CreatureBiteInfo(Vector3(8, 180, -48), 4), + CreatureBiteInfo(Vector3(90, 180, -32), 6), + CreatureBiteInfo(Vector3(-90, 180, -32), 7) }; const std::vector QuadBikeMountTypes = @@ -344,10 +344,10 @@ namespace TEN::Entities::Vehicles static int DoQuadShift(ItemInfo* quadBikeItem, Vector3i* pos, Vector3i* old) { CollisionResult probe; - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); - int oldX = old->x / SECTOR(1); - int oldZ = old->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); + int oldX = old->x / BLOCK(1); + int oldZ = old->z / BLOCK(1); int shiftX = pos->x & WALL_MASK; int shiftZ = pos->z & WALL_MASK; @@ -365,7 +365,7 @@ namespace TEN::Entities::Vehicles } else { - quadBikeItem->Pose.Position.z += SECTOR(1) - shiftZ; + quadBikeItem->Pose.Position.z += BLOCK(1) - shiftZ; return (quadBikeItem->Pose.Position.x - pos->x); } } @@ -378,7 +378,7 @@ namespace TEN::Entities::Vehicles } else { - quadBikeItem->Pose.Position.x += SECTOR(1) - shiftX; + quadBikeItem->Pose.Position.x += BLOCK(1) - shiftX; return (pos->z - quadBikeItem->Pose.Position.z); } } @@ -393,7 +393,7 @@ namespace TEN::Entities::Vehicles if (pos->z > old->z) z = -shiftZ - 1; else - z = SECTOR(1) - shiftZ; + z = BLOCK(1) - shiftZ; } probe = GetCollision(pos->x, pos->y, old->z, quadBikeItem->RoomNumber); @@ -402,7 +402,7 @@ namespace TEN::Entities::Vehicles if (pos->x > old->x) x = -shiftX - 1; else - x = SECTOR(1) - shiftX; + x = BLOCK(1) - shiftX; } if (x && z) @@ -506,7 +506,7 @@ namespace TEN::Entities::Vehicles quadBikeItem->Pose.Orientation.y += quadBike->TurnRate + quadBike->ExtraRotation; short momentum = QBIKE_MOMENTUM_TURN_RATE_MIN - (((((QBIKE_MOMENTUM_TURN_RATE_MIN - QBIKE_MOMENTUM_TURN_RATE_MAX) * 256) / MAX_VELOCITY) * quadBike->Velocity) / 256); - if (!(TrInput & VEHICLE_IN_ACCELERATE) && quadBike->Velocity > 0) + if (!IsHeld(In::Accelerate) && quadBike->Velocity > 0) momentum += momentum / 4; short rot = quadBikeItem->Pose.Orientation.y - quadBike->MomentumAngle; @@ -719,16 +719,16 @@ namespace TEN::Entities::Vehicles case QBIKE_STATE_IDLE: if (dead) laraItem->Animation.TargetState = QBIKE_STATE_BIKE_DEATH; - else if (TrInput & VEHICLE_IN_DISMOUNT && + else if (IsHeld(In::Brake) && quadBike->Velocity == 0 && !quadBike->NoDismount) { - if (TrInput & VEHICLE_IN_LEFT && CanQuadbikeGetOff(laraItem, -1)) + if (IsHeld(In::Left) && CanQuadbikeGetOff(laraItem, -1)) laraItem->Animation.TargetState = QBIKE_STATE_DISMOUNT_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT && CanQuadbikeGetOff(laraItem, 1)) + else if (IsHeld(In::Right) && CanQuadbikeGetOff(laraItem, 1)) laraItem->Animation.TargetState = QBIKE_STATE_DISMOUNT_RIGHT; } - else if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE)) + else if (IsHeld(In::Accelerate) || IsHeld(In::Reverse)) laraItem->Animation.TargetState = QBIKE_STATE_DRIVE; break; @@ -741,22 +741,22 @@ namespace TEN::Entities::Vehicles else laraItem->Animation.TargetState = QBIKE_STATE_BIKE_DEATH; } - else if (!(TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE)) && + else if (!IsHeld(In::Accelerate) && !IsHeld(In::Reverse) && (quadBike->Velocity / VEHICLE_VELOCITY_SCALE) == 0) { laraItem->Animation.TargetState = QBIKE_STATE_IDLE; } - else if (TrInput & VEHICLE_IN_LEFT && + else if (IsHeld(In::Left) && !quadBike->DriftStarting) { laraItem->Animation.TargetState = QBIKE_STATE_TURN_LEFT; } - else if (TrInput & VEHICLE_IN_RIGHT && + else if (IsHeld(In::Right) && !quadBike->DriftStarting) { laraItem->Animation.TargetState = QBIKE_STATE_TURN_RIGHT; } - else if (TrInput & (VEHICLE_IN_REVERSE | VEHICLE_IN_BRAKE)) + else if (IsHeld(In::Reverse) || IsHeld(In::Brake)) { if (quadBike->Velocity > (MAX_VELOCITY / 3 * 2)) laraItem->Animation.TargetState = QBIKE_STATE_BRAKE; @@ -771,9 +771,9 @@ namespace TEN::Entities::Vehicles case QBIKE_STATE_STOP_SLOWLY: if ((quadBike->Velocity / VEHICLE_VELOCITY_SCALE) == 0) laraItem->Animation.TargetState = QBIKE_STATE_IDLE; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = QBIKE_STATE_TURN_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = QBIKE_STATE_TURN_RIGHT; break; @@ -781,11 +781,11 @@ namespace TEN::Entities::Vehicles case QBIKE_STATE_TURN_LEFT: if ((quadBike->Velocity / VEHICLE_VELOCITY_SCALE) == 0) laraItem->Animation.TargetState = QBIKE_STATE_IDLE; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { SetAnimation(*laraItem, ID_QUAD_LARA_ANIMS, QBIKE_ANIM_TURN_RIGHT_START); } - else if (!(TrInput & VEHICLE_IN_LEFT)) + else if (!IsHeld(In::Left)) laraItem->Animation.TargetState = QBIKE_STATE_DRIVE; break; @@ -793,11 +793,11 @@ namespace TEN::Entities::Vehicles case QBIKE_STATE_TURN_RIGHT: if ((quadBike->Velocity / VEHICLE_VELOCITY_SCALE) == 0) laraItem->Animation.TargetState = QBIKE_STATE_IDLE; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) { SetAnimation(*laraItem, ID_QUAD_LARA_ANIMS, QBIKE_ANIM_TURN_LEFT_START); } - else if (!(TrInput & VEHICLE_IN_RIGHT)) + else if (!IsHeld(In::Right)) laraItem->Animation.TargetState = QBIKE_STATE_DRIVE; break; @@ -817,7 +817,7 @@ namespace TEN::Entities::Vehicles case QBIKE_STATE_HIT_BACK: case QBIKE_STATE_HIT_LEFT: case QBIKE_STATE_HIT_RIGHT: - if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE)) + if (IsHeld(In::Accelerate) || IsHeld(In::Reverse)) laraItem->Animation.TargetState = QBIKE_STATE_DRIVE; break; @@ -831,7 +831,7 @@ namespace TEN::Entities::Vehicles bool drive = false; // Never changes? - if (!(TrInput & VEHICLE_IN_SPEED) && + if (!IsHeld(In::Speed) && !quadBike->Velocity && !quadBike->CanStartDrift) { quadBike->CanStartDrift = true; @@ -839,7 +839,7 @@ namespace TEN::Entities::Vehicles else if (quadBike->Velocity) quadBike->CanStartDrift = false; - if (!(TrInput & VEHICLE_IN_SPEED)) + if (!IsHeld(In::Speed)) quadBike->DriftStarting = false; if (!quadBike->DriftStarting) @@ -861,17 +861,17 @@ namespace TEN::Entities::Vehicles // Driving forward. if (quadBike->Velocity > 0) { - if (TrInput & VEHICLE_IN_SPEED && + if (IsHeld(In::Speed) && !quadBike->DriftStarting && quadBike->Velocity > MIN_DRIFT_VELOCITY) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) { quadBike->TurnRate -= QBIKE_DRIFT_TURN_RATE_ACCEL; if (quadBike->TurnRate < -QBIKE_DRIFT_TURN_RATE_MAX) quadBike->TurnRate = -QBIKE_DRIFT_TURN_RATE_MAX; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { quadBike->TurnRate += QBIKE_DRIFT_TURN_RATE_ACCEL; if (quadBike->TurnRate > QBIKE_DRIFT_TURN_RATE_MAX) @@ -880,13 +880,13 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) { quadBike->TurnRate -= QBIKE_TURN_RATE_ACCEL; if (quadBike->TurnRate < -QBIKE_TURN_RATE_MAX) quadBike->TurnRate = -QBIKE_TURN_RATE_MAX; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { quadBike->TurnRate += QBIKE_TURN_RATE_ACCEL; if (quadBike->TurnRate > QBIKE_TURN_RATE_MAX) @@ -897,17 +897,17 @@ namespace TEN::Entities::Vehicles // Driving back. else if (quadBike->Velocity < 0) { - if (TrInput & VEHICLE_IN_SPEED && + if (IsHeld(In::Speed) && !quadBike->DriftStarting && quadBike->Velocity < (-MIN_DRIFT_VELOCITY + 0x800)) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) { quadBike->TurnRate -= QBIKE_DRIFT_TURN_RATE_ACCEL; if (quadBike->TurnRate < -QBIKE_DRIFT_TURN_RATE_MAX) quadBike->TurnRate = -QBIKE_DRIFT_TURN_RATE_MAX; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { quadBike->TurnRate += QBIKE_DRIFT_TURN_RATE_ACCEL; if (quadBike->TurnRate > QBIKE_DRIFT_TURN_RATE_MAX) @@ -916,13 +916,13 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & VEHICLE_IN_RIGHT) + if (IsHeld(In::Right)) { quadBike->TurnRate -= QBIKE_TURN_RATE_ACCEL; if (quadBike->TurnRate < -QBIKE_TURN_RATE_MAX) quadBike->TurnRate = -QBIKE_TURN_RATE_MAX; } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) { quadBike->TurnRate += QBIKE_TURN_RATE_ACCEL; if (quadBike->TurnRate > QBIKE_TURN_RATE_MAX) @@ -932,9 +932,9 @@ namespace TEN::Entities::Vehicles } // Driving back / braking. - if (TrInput & VEHICLE_IN_REVERSE) + if (IsHeld(In::Reverse)) { - if (TrInput & VEHICLE_IN_SPEED && + if (IsHeld(In::Speed) && (quadBike->CanStartDrift || quadBike->DriftStarting)) { quadBike->DriftStarting = true; @@ -950,9 +950,9 @@ namespace TEN::Entities::Vehicles quadBike->Velocity += REVERSE_ACCELERATION; } } - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { - if (TrInput & VEHICLE_IN_SPEED && + if (IsHeld(In::Speed) && (quadBike->CanStartDrift || quadBike->DriftStarting)) { quadBike->DriftStarting = true; @@ -982,7 +982,7 @@ namespace TEN::Entities::Vehicles else quadBike->Velocity = 0; - if (!(TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_REVERSE)) && + if (!IsHeld(In::Accelerate) && !IsHeld(In::Reverse) && quadBike->DriftStarting && quadBike->Revs) { @@ -1176,7 +1176,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != quadBikeItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose = quadBikeItem->Pose; diff --git a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp index 9cf334868..d483d2e8a 100644 --- a/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp +++ b/TombEngine/Objects/TR3/Vehicles/rubber_boat.cpp @@ -161,7 +161,7 @@ namespace TEN::Entities::Vehicles } if (laraItem->RoomNumber != rBoatItem->RoomNumber) - ItemNewRoom(lara->ItemNumber, rBoatItem->RoomNumber); + ItemNewRoom(laraItem->Index, rBoatItem->RoomNumber); laraItem->Pose.Position = rBoatItem->Pose.Position; laraItem->Pose.Position.y -= 5; @@ -217,11 +217,11 @@ namespace TEN::Entities::Vehicles static int DoRubberBoatShift2(ItemInfo* rBoatItem, Vector3i* pos, Vector3i* old) { - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); - int xOld = old->x / SECTOR(1); - int zOld = old->z / SECTOR(1); + int xOld = old->x / BLOCK(1); + int zOld = old->z / BLOCK(1); int xShift = pos->x & WALL_MASK; int zShift = pos->z & WALL_MASK; @@ -240,7 +240,7 @@ namespace TEN::Entities::Vehicles } else { - rBoatItem->Pose.Position.z += SECTOR(1) - zShift; + rBoatItem->Pose.Position.z += BLOCK(1) - zShift; return (rBoatItem->Pose.Position.x - pos->x); } } @@ -253,7 +253,7 @@ namespace TEN::Entities::Vehicles } else { - rBoatItem->Pose.Position.x += SECTOR(1) - xShift; + rBoatItem->Pose.Position.x += BLOCK(1) - xShift; return (pos->z - rBoatItem->Pose.Position.z); } } @@ -268,7 +268,7 @@ namespace TEN::Entities::Vehicles if (pos->z > old->z) z = -zShift - 1; else - z = SECTOR(1) - zShift; + z = BLOCK(1) - zShift; } height = GetCollision(pos->x, pos->y, old->z, rBoatItem->RoomNumber).Position.Floor; @@ -277,7 +277,7 @@ namespace TEN::Entities::Vehicles if (pos->x > old->x) x = -xShift - 1; else - x = SECTOR(1) - xShift; + x = BLOCK(1) - xShift; } if (x && z) @@ -503,10 +503,10 @@ namespace TEN::Entities::Vehicles if (rBoatItem->Pose.Position.y >= (rBoat->Water - 128) && rBoat->Water != NO_HEIGHT) { - if (!(TrInput & VEHICLE_IN_DISMOUNT) && !(TrInput & IN_LOOK) || rBoatItem->Animation.Velocity.z) + if (!IsHeld(In::Brake) && !(TrInput & IN_LOOK) || rBoatItem->Animation.Velocity.z) { - if ((TrInput & VEHICLE_IN_LEFT && !(TrInput & VEHICLE_IN_REVERSE)) || - (TrInput & VEHICLE_IN_RIGHT && TrInput & VEHICLE_IN_REVERSE)) + if ((IsHeld(In::Left) && !IsHeld(In::Reverse)) || + (IsHeld(In::Right) && IsHeld(In::Reverse))) { if (rBoat->TurnRate > 0) rBoat->TurnRate -= RBOAT_TURN_RATE_DECEL; @@ -519,8 +519,8 @@ namespace TEN::Entities::Vehicles noTurn = false; } - else if ((TrInput & VEHICLE_IN_RIGHT && !(TrInput & VEHICLE_IN_REVERSE)) || - (TrInput & VEHICLE_IN_LEFT && TrInput & VEHICLE_IN_REVERSE)) + else if ((IsHeld(In::Right) && !IsHeld(In::Reverse)) || + (IsHeld(In::Left) && IsHeld(In::Reverse))) { if (rBoat->TurnRate < 0) rBoat->TurnRate += RBOAT_TURN_RATE_DECEL; @@ -534,20 +534,20 @@ namespace TEN::Entities::Vehicles noTurn = false; } - if (TrInput & VEHICLE_IN_REVERSE) + if (IsHeld(In::Reverse)) { if (rBoatItem->Animation.Velocity.z > 0) rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_BRAKE_DECEL; else if (rBoatItem->Animation.Velocity.z > -RBOAT_REVERSE_VELOCITY_MAX) rBoatItem->Animation.Velocity.z -= RBOAT_REVERSE_VELOCITY_DECEL; } - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { int maxVelocity; - if (TrInput & VEHICLE_IN_SPEED) + if (IsHeld(In::Speed)) maxVelocity = RBOAT_FAST_VELOCITY_MAX; else - maxVelocity = (TrInput & VEHICLE_IN_SLOW) ? RBOAT_SLOW_VELOCITY_MAX : RBOAT_NORMAL_VELOCITY_MAX; + maxVelocity = (IsHeld(In::Slow)) ? RBOAT_SLOW_VELOCITY_MAX : RBOAT_NORMAL_VELOCITY_MAX; if (rBoatItem->Animation.Velocity.z < maxVelocity) rBoatItem->Animation.Velocity.z += (RBOAT_VELOCITY_ACCEL / 2 + 1) + (RBOAT_VELOCITY_ACCEL * rBoatItem->Animation.Velocity.z) / (maxVelocity * 2); @@ -555,11 +555,11 @@ namespace TEN::Entities::Vehicles rBoatItem->Animation.Velocity.z -= RBOAT_VELOCITY_DECEL; } - else if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) && + else if (IsHeld(In::Left) || IsHeld(In::Right) && rBoatItem->Animation.Velocity.z >= 0 && rBoatItem->Animation.Velocity.z < RBOAT_VELOCITY_MIN) { - if (!(TrInput & VEHICLE_IN_DISMOUNT) && rBoatItem->Animation.Velocity.z == 0) + if (!IsHeld(In::Brake) && rBoatItem->Animation.Velocity.z == 0) rBoatItem->Animation.Velocity.z = RBOAT_VELOCITY_MIN; } else if (rBoatItem->Animation.Velocity.z > RBOAT_VELOCITY_DECEL) @@ -569,11 +569,11 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT) && + if (IsHeld(In::Left) || IsHeld(In::Right) && rBoatItem->Animation.Velocity.z >= 0 && rBoatItem->Animation.Velocity.z < RBOAT_VELOCITY_MIN) { - if (!(TrInput & VEHICLE_IN_DISMOUNT) && rBoatItem->Animation.Velocity.z == 0) + if (!IsHeld(In::Brake) && rBoatItem->Animation.Velocity.z == 0) rBoatItem->Animation.Velocity.z = RBOAT_VELOCITY_MIN; } else if (rBoatItem->Animation.Velocity.z > RBOAT_VELOCITY_DECEL) @@ -600,9 +600,9 @@ namespace TEN::Entities::Vehicles else angle = sBoatItem->Pose.Orientation.y + ANGLE(90.0f); - int x = sBoatItem->Pose.Position.x + SECTOR(1) * phd_sin(angle); + int x = sBoatItem->Pose.Position.x + BLOCK(1) * phd_sin(angle); int y = sBoatItem->Pose.Position.y; - int z = sBoatItem->Pose.Position.z + SECTOR(1) * phd_cos(angle); + int z = sBoatItem->Pose.Position.z + BLOCK(1) * phd_cos(angle); auto collResult = GetCollision(x, y, z, sBoatItem->RoomNumber); @@ -646,7 +646,7 @@ namespace TEN::Entities::Vehicles switch (laraItem->Animation.ActiveState) { case RBOAT_STATE_IDLE: - if (TrInput & VEHICLE_IN_DISMOUNT) + if (IsHeld(In::Brake)) { if (rBoatItem->Animation.Velocity.z == 0) { @@ -666,9 +666,9 @@ namespace TEN::Entities::Vehicles if (rBoatItem->Animation.Velocity.z <= 0) laraItem->Animation.TargetState = RBOAT_STATE_IDLE; - if (TrInput & VEHICLE_IN_RIGHT) + if (IsHeld(In::Right)) laraItem->Animation.TargetState = RBOAT_STATE_TURN_RIGHT; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = RBOAT_STATE_TURN_LEFT; break; @@ -680,7 +680,7 @@ namespace TEN::Entities::Vehicles case RBOAT_STATE_TURN_RIGHT: if (rBoatItem->Animation.Velocity.z <= 0) laraItem->Animation.TargetState = RBOAT_STATE_IDLE; - else if (!(TrInput & VEHICLE_IN_RIGHT)) + else if (!IsHeld(In::Right)) laraItem->Animation.TargetState = RBOAT_STATE_MOVING; break; @@ -688,7 +688,7 @@ namespace TEN::Entities::Vehicles case RBOAT_STATE_TURN_LEFT: if (rBoatItem->Animation.Velocity.z <= 0) laraItem->Animation.TargetState = RBOAT_STATE_IDLE; - else if (!(TrInput & VEHICLE_IN_LEFT)) + else if (!IsHeld(In::Left)) laraItem->Animation.TargetState = RBOAT_STATE_MOVING; break; @@ -793,7 +793,7 @@ namespace TEN::Entities::Vehicles laraItem->Pose.Position.z = z; if (probe.RoomNumber != laraItem->RoomNumber) - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose.Position.y = y; @@ -898,7 +898,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != rBoatItem->RoomNumber) { ItemNewRoom(itemNumber, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } rBoatItem->Pose.Orientation.z += rBoat->LeanAngle; @@ -910,7 +910,7 @@ namespace TEN::Entities::Vehicles SyncVehicleAnimation(*rBoatItem, *laraItem); Camera.targetElevation = -ANGLE(20.0f); - Camera.targetDistance = SECTOR(2); + Camera.targetDistance = BLOCK(2); } else { diff --git a/TombEngine/Objects/TR3/Vehicles/upv.cpp b/TombEngine/Objects/TR3/Vehicles/upv.cpp index 530b8f7a9..31615c7d9 100644 --- a/TombEngine/Objects/TR3/Vehicles/upv.cpp +++ b/TombEngine/Objects/TR3/Vehicles/upv.cpp @@ -40,10 +40,10 @@ namespace TEN::Entities::Vehicles { constexpr auto UPV_RADIUS = 300; constexpr auto UPV_HEIGHT = 400; - constexpr auto UPV_LENGTH = SECTOR(1); + constexpr auto UPV_LENGTH = BLOCK(1); constexpr auto UPV_WATER_SURFACE_DISTANCE = 210; constexpr auto UPV_MOUNT_DISTANCE = CLICK(2); - constexpr auto UPV_DISMOUNT_DISTANCE = SECTOR(1); + constexpr auto UPV_DISMOUNT_DISTANCE = BLOCK(1); constexpr int UPV_VELOCITY_ACCEL = 4 * VEHICLE_VELOCITY_SCALE; constexpr int UPV_VELOCITY_FRICTION_DECEL = 1.5f * VEHICLE_VELOCITY_SCALE; @@ -86,12 +86,12 @@ namespace TEN::Entities::Vehicles const CreatureBiteInfo UPVBites[6] = { - CreatureBiteInfo(Vector3i(0, 0, 0), 3), - CreatureBiteInfo(Vector3i(0, 96, 256), 0), - CreatureBiteInfo(Vector3i(-128, 0, 64), 1), - CreatureBiteInfo(Vector3i(0, 0, -64), 1), - CreatureBiteInfo(Vector3i(128, 0, 64), 2), - CreatureBiteInfo(Vector3i(0, 0, -64), 2) + CreatureBiteInfo(Vector3(0, 0, 0), 3), + CreatureBiteInfo(Vector3(0, 96, 256), 0), + CreatureBiteInfo(Vector3(-128, 0, 64), 1), + CreatureBiteInfo(Vector3(0, 0, -64), 1), + CreatureBiteInfo(Vector3(128, 0, 64), 2), + CreatureBiteInfo(Vector3(0, 0, -64), 2) }; const std::vector UPVMountTypes = @@ -224,17 +224,16 @@ namespace TEN::Entities::Vehicles static void FireUPVHarpoon(ItemInfo* UPVItem, ItemInfo* laraItem) { - auto* harpoon = FireHarpoon(*laraItem); + auto& upv = *GetUPVInfo(UPVItem); - if (harpoon == nullptr) + auto harpoonPose = Pose(GetJointPosition(UPVItem, UPV_JOINT_TURBINE, Vector3i((upv.HarpoonLeft ? 22 : -22), 24, 230))); + if (!FireHarpoon(*laraItem, harpoonPose)) return; - auto UPV = GetUPVInfo(UPVItem); - harpoon->Pose.Position = GetJointPosition(UPVItem, UPV_JOINT_TURBINE, Vector3i((UPV->HarpoonLeft ? 22 : -22), 24, 230)); - harpoon->Pose.Orientation = EulerAngles(UPVItem->Pose.Orientation.x, UPVItem->Pose.Orientation.y, 0); + auto soundID = (upv.Flags & UPV_FLAG_SURFACE) ? SFX_TR4_HARPOON_FIRE_DRY : SFX_TR4_HARPOON_FIRE_UNDERWATER; + SoundEffect(soundID, &harpoonPose, SoundEnvironment::Always); - harpoon->ItemFlags[0] = 1; - UPV->HarpoonLeft = !UPV->HarpoonLeft; + upv.HarpoonLeft = !upv.HarpoonLeft; } static void TriggerUPVMist(long x, long y, long z, long velocity, short angle) @@ -420,8 +419,8 @@ namespace TEN::Entities::Vehicles int dz = target.z - laraItem->Pose.Position.z; int velocity = g_Level.Sinks[sinkVal].Strength; - dx = phd_sin(angle * 16) * velocity * SECTOR(1); - dz = phd_cos(angle * 16) * velocity * SECTOR(1); + dx = phd_sin(angle * 16) * velocity * BLOCK(1); + dz = phd_cos(angle * 16) * velocity * BLOCK(1); lara->Context.WaterCurrentPull.x += ((dx - lara->Context.WaterCurrentPull.x) / 16); lara->Context.WaterCurrentPull.z += ((dz - lara->Context.WaterCurrentPull.z) / 16); @@ -538,7 +537,7 @@ namespace TEN::Entities::Vehicles break; } - if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateVehicleTurnRateY(&UPV->TurnRate.y, UPV_Y_TURN_RATE_ACCEL, -UPV_Y_TURN_RATE_MAX, UPV_Y_TURN_RATE_MAX); ModulateVehicleLean(UPVItem, UPV_LEAN_RATE, UPV_LEAN_MAX); @@ -567,13 +566,13 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & (VEHICLE_IN_UP | VEHICLE_IN_DOWN)) + if (IsHeld(In::Forward) || IsHeld(In::Back)) ModulateVehicleTurnRateX(&UPV->TurnRate.x, UPV_X_TURN_RATE_ACCEL, -UPV_X_TURN_RATE_MAX, UPV_X_TURN_RATE_MAX); } - if (TrInput & VEHICLE_IN_ACCELERATE) + if (IsHeld(In::Accelerate)) { - if (TrInput & VEHICLE_IN_UP && + if (IsHeld(In::Forward) && UPV->Flags & UPV_FLAG_SURFACE && UPVItem->Pose.Orientation.x > -UPV_X_ORIENT_DIVE_MAX) { @@ -594,7 +593,7 @@ namespace TEN::Entities::Vehicles break; } - if (TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT)) + if (IsHeld(In::Left) || IsHeld(In::Right)) { ModulateVehicleTurnRateY(&UPV->TurnRate.y, UPV_Y_TURN_RATE_ACCEL, -UPV_Y_TURN_RATE_MAX, UPV_Y_TURN_RATE_MAX); ModulateVehicleLean(UPVItem, UPV_LEAN_RATE, UPV_LEAN_MAX); @@ -623,11 +622,11 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & (VEHICLE_IN_UP | VEHICLE_IN_DOWN)) + if (IsHeld(In::Forward) || IsHeld(In::Back)) ModulateVehicleTurnRateX(&UPV->TurnRate.x, UPV_X_TURN_RATE_ACCEL, -UPV_X_TURN_RATE_MAX, UPV_X_TURN_RATE_MAX); } - if (TrInput & VEHICLE_IN_DISMOUNT && TestUPVDismount(UPVItem, laraItem)) + if (IsHeld(In::Brake) && TestUPVDismount(UPVItem, laraItem)) { if (UPV->Velocity > 0) UPV->Velocity -= UPV_VELOCITY_ACCEL; @@ -644,9 +643,9 @@ namespace TEN::Entities::Vehicles SoundEffect(SFX_TR3_VEHICLE_UPV_STOP, (Pose*)&UPVItem->Pose.Position.x, SoundEnvironment::Always); } } - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { - if (TrInput & VEHICLE_IN_UP && + if (IsHeld(In::Forward) && UPVItem->Pose.Orientation.x > -UPV_X_ORIENT_DIVE_MAX && UPV->Flags & UPV_FLAG_SURFACE) { @@ -940,7 +939,7 @@ namespace TEN::Entities::Vehicles TestTriggers(UPVItem, false); UPVEffects(lara->Context.Vehicle); - if (UPV->Velocity || TrInput & (VEHICLE_IN_LEFT | VEHICLE_IN_RIGHT | VEHICLE_IN_UP | VEHICLE_IN_DOWN)) + if (UPV->Velocity || IsDirectionalActionHeld()) { waterHeight = GetWaterHeight(UPVItem); SpawnVehicleWake(*UPVItem, UPV_WAKE_OFFSET, waterHeight, true); @@ -951,7 +950,7 @@ namespace TEN::Entities::Vehicles { DoCurrent(UPVItem, laraItem); - if (TrInput & VEHICLE_IN_FIRE && + if (IsHeld(In::Fire) && UPV->Flags & UPV_FLAG_CONTROL && !UPV->HarpoonTimer) { @@ -967,7 +966,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != UPVItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose = UPVItem->Pose; diff --git a/TombEngine/Objects/TR4/Entity/Wraith.cpp b/TombEngine/Objects/TR4/Entity/Wraith.cpp index d050651b4..54c743083 100644 --- a/TombEngine/Objects/TR4/Entity/Wraith.cpp +++ b/TombEngine/Objects/TR4/Entity/Wraith.cpp @@ -715,7 +715,7 @@ namespace TEN::Entities::TR4 } } - item2->HitPoints = item - g_Level.Items.data(); + item2->HitPoints = item->Index; } FlipEffect = -1; diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp index f06adc089..8297d6689 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp @@ -35,9 +35,9 @@ namespace TEN::Entities::TR4 constexpr auto AHMET_VIEW_ANGLE = ANGLE(45.0f); constexpr auto AHMET_ENEMY_ANGLE = ANGLE(90.0f); - const auto AhmetBiteLeft = CreatureBiteInfo(Vector3i::Zero, 16); - const auto AhmetBiteRight = CreatureBiteInfo(Vector3i::Zero, 22); - const auto AhmetBiteJaw = CreatureBiteInfo(Vector3i::Zero, 11); + const auto AhmetBiteLeft = CreatureBiteInfo(Vector3::Zero, 16); + const auto AhmetBiteRight = CreatureBiteInfo(Vector3::Zero, 22); + const auto AhmetBiteJaw = CreatureBiteInfo(Vector3::Zero, 11); const auto AhmetSwipeAttackLeftJoints = std::vector{ 14, 15, 16, 17 }; const auto AhmetSwipeAttackRightJoints = std::vector{ 20, 21, 22, 23 }; @@ -109,9 +109,9 @@ namespace TEN::Entities::TR4 InitializeCreature(itemNumber); SetAnimation(item, AHMET_ANIM_IDLE); - item->ItemFlags[0] = item->Pose.Position.x / SECTOR(1); - item->ItemFlags[1] = (item->Pose.Position.y * 4) / SECTOR(1); - item->ItemFlags[2] = item->Pose.Position.z / SECTOR(1); + item->ItemFlags[0] = item->Pose.Position.x / BLOCK(1); + item->ItemFlags[1] = (item->Pose.Position.y * 4) / BLOCK(1); + item->ItemFlags[2] = item->Pose.Position.z / BLOCK(1); } void AhmetControl(short itemNumber) @@ -391,9 +391,9 @@ namespace TEN::Entities::TR4 Weather.Flash(255, 64, 0, 0.03f); - item->Pose.Position.x = (item->ItemFlags[0] * SECTOR(1)) + CLICK(2); + item->Pose.Position.x = (item->ItemFlags[0] * BLOCK(1)) + CLICK(2); item->Pose.Position.y = (item->ItemFlags[1] * CLICK(1)); - item->Pose.Position.z = (item->ItemFlags[2] * SECTOR(1)) + CLICK(2); + item->Pose.Position.z = (item->ItemFlags[2] * BLOCK(1)) + CLICK(2); auto outsideRoom = IsRoomOutside(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); if (item->RoomNumber != outsideRoom) diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp index 004b8a1c7..ea22508c9 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp @@ -39,7 +39,7 @@ namespace TEN::Entities::TR4 constexpr auto NO_BABOON_COUNT = -2; constexpr auto NO_CROWBAR_SWITCH_FOUND = -1; - const auto BaboonBite = CreatureBiteInfo(Vector3i(10, 10, 11), 4); + const auto BaboonBite = CreatureBiteInfo(Vector3(10, 10, 11), 4); const auto BaboonAttackJoints = std::vector{ 11, 12 }; const auto BaboonAttackRightJoints = std::vector{ 1, 2, 3, 5, 8, 9 }; const auto BaboonJumpAttackJoints = std::vector{ 3, 4, 8 }; @@ -491,23 +491,23 @@ namespace TEN::Entities::TR4 auto pos = Vector3i::Zero; if (item->Pose.Orientation.y == ANGLE(270.0f)) { - pos.x = item->Pose.Position.x - SECTOR(1); + pos.x = item->Pose.Position.x - BLOCK(1); pos.z = item->Pose.Position.z; } else if (item->Pose.Orientation.y == ANGLE(90.0f)) { - pos.x = item->Pose.Position.x + SECTOR(1); + pos.x = item->Pose.Position.x + BLOCK(1); pos.z = item->Pose.Position.z; } else if (item->Pose.Orientation.y == ANGLE(0.0f)) { pos.x = item->Pose.Position.x; - pos.z = item->Pose.Position.z + SECTOR(1); + pos.z = item->Pose.Position.z + BLOCK(1); } else if (item->Pose.Orientation.y == ANGLE(180.0f)) { pos.x = item->Pose.Position.x; - pos.z = item->Pose.Position.z - SECTOR(1); + pos.z = item->Pose.Position.z - BLOCK(1); } pos.y = item->Pose.Position.y; diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp index e27b37e04..2feee2dcb 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp @@ -54,8 +54,8 @@ namespace TEN::Entities::TR4 { constexpr auto BADDY_UZI_AMMO = 24; - const auto BaddyGunBite = CreatureBiteInfo(Vector3i(-5, 200, 50), 11); - const auto BaddySwordBite = CreatureBiteInfo(Vector3i::Zero, 15); + const auto BaddyGunBite = CreatureBiteInfo(Vector3(-5, 200, 50), 11); + const auto BaddySwordBite = CreatureBiteInfo(Vector3::Zero, 15); const auto BaddySwordAttackJoints = std::vector{ 14, 15, 16 }; enum BaddyState @@ -552,7 +552,7 @@ namespace TEN::Entities::TR4 // Is baddy alerted? if (item->HitStatus || - laraAI.distance < pow(SECTOR(1), 2) || + laraAI.distance < pow(BLOCK(1), 2) || TargetVisible(item, &laraAI) && abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < CLICK(4)) { @@ -699,7 +699,7 @@ namespace TEN::Entities::TR4 { short objectNumber = currentCreature->Enemy->ObjectNumber; if ((objectNumber == ID_SMALLMEDI_ITEM || objectNumber == ID_UZI_AMMO_ITEM || objectNumber == ID_BIGMEDI_ITEM) && - AI.distance < pow(SECTOR(0.5f), 2)) + AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = BADDY_STATE_STAND_TO_CROUCH; item->Animation.RequiredState = BADDY_STATE_CROUCH_PICKUP; @@ -758,12 +758,12 @@ namespace TEN::Entities::TR4 if (currentCreature->Enemy && currentCreature->Enemy->HitPoints > 0 && - AI.distance < pow(SECTOR(0.5f), 2) && - abs(AI.verticalDistance) < SECTOR(1)) + AI.distance < pow(BLOCK(0.5f), 2) && + abs(AI.verticalDistance) < BLOCK(1)) { if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN)) item->Animation.TargetState = BADDY_STATE_HOLSTER_GUN; - else if (AI.distance >= pow(SECTOR(0.5f), 2)) + else if (AI.distance >= pow(BLOCK(0.5f), 2)) item->Animation.TargetState = BADDY_STATE_SWORD_HIT_FRONT; else if (Random::TestProbability(1 / 2.0f)) item->Animation.TargetState = BADDY_STATE_SWORD_HIT_LEFT; @@ -817,7 +817,7 @@ namespace TEN::Entities::TR4 } } - if (AI.ahead && AI.distance < pow(SECTOR(0.5f), 2)) + if (AI.ahead && AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = BADDY_STATE_IDLE; break; @@ -831,7 +831,7 @@ namespace TEN::Entities::TR4 break; } - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = BADDY_STATE_WALK_SWORD_HIT_RIGHT; break; @@ -846,7 +846,7 @@ namespace TEN::Entities::TR4 if (currentCreature->Mood == MoodType::Attack && !(currentCreature->JumpAhead) && - AI.distance > pow(SECTOR(1), 2)) + AI.distance > pow(BLOCK(1), 2)) { item->Animation.TargetState = BADDY_STATE_RUN; } @@ -865,7 +865,7 @@ namespace TEN::Entities::TR4 item->Animation.FrameNumber == GetAnimData(item).frameBase + FRAME_BADDY_RUN_TO_SOMERSAULT && height3 == height1 && abs(height1 - item->Pose.Position.y) < CLICK(1.5f) && - (AI.angle > -ANGLE(22.5f) && AI.angle < ANGLE(22.5f) && AI.distance < pow(SECTOR(3), 2) || height2 >= (height1 + CLICK(2)))) + (AI.angle > -ANGLE(22.5f) && AI.angle < ANGLE(22.5f) && AI.distance < pow(BLOCK(3), 2) || height2 >= (height1 + CLICK(2)))) { item->Animation.TargetState = BADDY_STATE_SOMERSAULT; currentCreature->MaxTurn = 0; @@ -885,7 +885,7 @@ namespace TEN::Entities::TR4 break; } - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = BADDY_STATE_WALK; break; @@ -900,7 +900,7 @@ namespace TEN::Entities::TR4 currentCreature->MaxTurn = 0; if (item->Animation.ActiveState == BADDY_STATE_SWORD_HIT_RIGHT && - AI.distance < pow(SECTOR(0.5f), 2)) + AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = BADDY_STATE_SWORD_HIT_LEFT; } @@ -1048,7 +1048,7 @@ namespace TEN::Entities::TR4 if ((currentCreature->Enemy->ObjectNumber == ID_SMALLMEDI_ITEM || currentCreature->Enemy->ObjectNumber == ID_BIGMEDI_ITEM || currentCreature->Enemy->ObjectNumber == ID_UZI_AMMO_ITEM) && - AI.distance < pow(SECTOR(0.5f), 2)) + AI.distance < pow(BLOCK(0.5f), 2)) { item->Animation.TargetState = BADDY_STATE_CROUCH_PICKUP; break; @@ -1105,7 +1105,7 @@ namespace TEN::Entities::TR4 break; } - KillItem(currentCreature->Enemy - g_Level.Items.data()); + KillItem(currentCreature->Enemy->Index); // Cancel enemy pointer for other active baddys for (int i = 0; i < ActiveCreatures.size(); i++) diff --git a/TombEngine/Objects/TR4/Entity/tr4_bat.cpp b/TombEngine/Objects/TR4/Entity/tr4_bat.cpp index 48c437322..00eb32ec7 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_bat.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_bat.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math; namespace TEN::Entities::TR4 { - constexpr auto BAT_ATTACK_DAMAGE = 50; + constexpr auto BAT_ATTACK_DAMAGE = 2; constexpr auto BAT_UNFURL_HEIGHT_RANGE = BLOCK(0.87f); constexpr auto BAT_ATTACK_RANGE = SQUARE(BLOCK(1 / 4.0f)); @@ -24,7 +24,7 @@ namespace TEN::Entities::TR4 constexpr auto BAT_ANGLE = ANGLE(20.0f); - const auto BatBite = CreatureBiteInfo(Vector3i(0, 16, 45), 4); + const auto BatBite = CreatureBiteInfo(Vector3(0, 16, 45), 4); enum BatState { @@ -44,114 +44,105 @@ namespace TEN::Entities::TR4 BAT_ANIM_ATTACK = 2, BAT_ANIM_DEATH_FALL = 3, BAT_ANIM_DEATH = 4, - BAT_ANIM_IDLE = 5, + BAT_ANIM_IDLE = 5 // NOTE: TR1 bat don't have this animation, which bug the bat, you need to add the animation manually - TokyoSU: 18/6/2023 }; - bool IsBatCollideTarget(ItemInfo* item) - { - return (item->TouchBits.ToPackedBits() >= 0); - } - void InitializeBat(short itemNumber) { - auto* item = &g_Level.Items[itemNumber]; + auto& item = g_Level.Items[itemNumber]; InitializeCreature(itemNumber); SetAnimation(item, BAT_ANIM_IDLE); } + static bool BatCanAttackTarget(ItemInfo& item, const AI_INFO& ai) + { + const auto& creature = *GetCreatureInfo(&item); + + int deltaHeight = abs(item.Pose.Position.y - creature.Enemy->Pose.Position.y); + if (item.TouchBits.TestAny() || + (ai.distance < BAT_ATTACK_RANGE && ai.ahead && deltaHeight < BAT_UNFURL_HEIGHT_RANGE)) + { + return true; + } + + return false; + } + void BatControl(short itemNumber) { if (!CreatureActive(itemNumber)) return; - auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); + auto& item = g_Level.Items[itemNumber]; + auto& creature = *GetCreatureInfo(&item); - short angle = 0; + short headingAngle = 0; - if (item->HitPoints > 0) + if (item.HitPoints <= 0) { - if (item->AIBits) - GetAITarget(creature); - else - creature->Enemy = LaraItem; + if (item.Animation.ActiveState != BAT_STATE_DEATH_FALL && item.Animation.ActiveState != BAT_STATE_DEATH) + { + item.Animation.IsAirborne = true; + item.Animation.Velocity.z = 0; + SetAnimation(item, BAT_ANIM_DEATH_FALL); + } + else if (item.Pose.Position.y >= item.Floor && item.Animation.ActiveState != BAT_STATE_DEATH) + { + item.Animation.TargetState = BAT_STATE_DEATH; + item.Animation.IsAirborne = false; + item.Pose.Position.y = item.Floor; + } + } + else + { + if (item.AIBits) + GetAITarget(&creature); - // NOTE: Changed from false to true, otherwise the bat seems to ignore Lara. - // I feel fine with bat always true, - // but I will also inspect GetCreatureMood and CreatureMood functions for bugs. @TokyoSU + AI_INFO ai; + CreatureAIInfo(&item, &ai); + GetCreatureMood(&item, &ai, false); - AI_INFO AI; - CreatureAIInfo(item, &AI); - GetCreatureMood(item, &AI, true); + if (creature.Flags != 0) + creature.Mood = MoodType::Escape; - if (creature->Flags) - creature->Mood = MoodType::Escape; + CreatureMood(&item, &ai, false); + headingAngle = CreatureTurn(&item, BAT_ANGLE); - CreatureMood(item, &AI, true); - - angle = CreatureTurn(item, BAT_ANGLE); - - switch (item->Animation.ActiveState) + switch (item.Animation.ActiveState) { case BAT_STATE_IDLE: - if (AI.distance < BAT_AWARE_RANGE || item->HitStatus || creature->HurtByLara) - item->Animation.TargetState = BAT_STATE_DROP_FROM_CEILING; + if (ai.distance < BAT_AWARE_RANGE || item.HitStatus || creature.HurtByLara) + item.Animation.TargetState = BAT_STATE_DROP_FROM_CEILING; break; case BAT_STATE_FLY: - if (AI.distance < BAT_ATTACK_RANGE || Random::TestProbability(1 / 64.0f)) - creature->Flags = 0; + if (ai.distance < BAT_ATTACK_RANGE || Random::TestProbability(1 / 64.0f)) + creature.Flags = 0; - if (!creature->Flags) - { - if (item->TouchBits.TestAny() || - (!creature->Enemy->IsLara() && - AI.distance < BAT_ATTACK_RANGE && AI.ahead && - abs(item->Pose.Position.y - creature->Enemy->Pose.Position.y) < BAT_UNFURL_HEIGHT_RANGE)) - { - item->Animation.TargetState = BAT_STATE_ATTACK; - } - } + if (creature.Flags == 0 && BatCanAttackTarget(item, ai)) + item.Animation.TargetState = BAT_STATE_ATTACK; break; case BAT_STATE_ATTACK: - if (!creature->Flags && - (item->TouchBits.TestAny() || !creature->Enemy->IsLara()) && - AI.distance < BAT_ATTACK_RANGE && AI.ahead && - abs(item->Pose.Position.y - creature->Enemy->Pose.Position.y) < BAT_UNFURL_HEIGHT_RANGE) + if (creature.Flags == 0 && BatCanAttackTarget(item, ai)) { - DoDamage(creature->Enemy, BAT_ATTACK_DAMAGE); - CreatureEffect(item, BatBite, DoBloodSplat); - creature->Flags = 1; + DoDamage(creature.Enemy, BAT_ATTACK_DAMAGE); + CreatureEffect(&item, BatBite, DoBloodSplat); + creature.Flags = 1; } else { - item->Animation.TargetState = BAT_STATE_FLY; - creature->Mood = MoodType::Bored; + item.Animation.TargetState = BAT_STATE_FLY; + creature.Mood = MoodType::Bored; } break; } } - else if (item->Animation.ActiveState == BAT_STATE_ATTACK) - SetAnimation(item, BAT_ANIM_FLY); - else - { - if (item->Pose.Position.y >= item->Floor) - { - item->Animation.TargetState = BAT_STATE_DEATH; - item->Animation.IsAirborne = false; - item->Pose.Position.y = item->Floor; - } - else - SetAnimation(item, BAT_ANIM_DEATH_FALL); - item->Animation.IsAirborne = true; - item->Animation.Velocity.z = 0; - } - CreatureAnimation(itemNumber, angle, 0); + CreatureAnimation(itemNumber, headingAngle, 0); } } diff --git a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp index b91ef2c1f..71b8e94f0 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_beetle_swarm.cpp @@ -167,7 +167,7 @@ namespace TEN::Entities::TR4 if (beetle->Flags) { - if (abs(dx) + abs(dz) <= SECTOR(1)) + if (abs(dx) + abs(dz) <= BLOCK(1)) { if (beetle->Velocity & 1) beetle->Pose.Orientation.y += ANGLE(2.8f); @@ -197,7 +197,7 @@ namespace TEN::Entities::TR4 FloorInfo* floor = GetFloor(beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z, &beetle->RoomNumber); int height = GetFloorHeight(floor, beetle->Pose.Position.x, beetle->Pose.Position.y, beetle->Pose.Position.z); - if (height < (beetle->Pose.Position.y - SECTOR(1.25f)) || height == NO_HEIGHT) + if (height < (beetle->Pose.Position.y - BLOCK(1.25f)) || height == NO_HEIGHT) { // Beetle has hit a wall a high step. if (angle <= 0) diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp index b3769d87d..664eb4f62 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp @@ -21,7 +21,7 @@ namespace TEN::Entities::TR4 constexpr auto BIG_BEETLE_ATTACK_RANGE = SQUARE(CLICK(1)); constexpr auto BIG_BEETLE_AWARE_RANGE = SQUARE(CLICK(12)); - const auto BigBeetleBite = CreatureBiteInfo(Vector3i::Zero, 12); + const auto BigBeetleBite = CreatureBiteInfo(Vector3::Zero, 12); const auto BigBeetleAttackJoints = std::vector{ 5, 6 }; enum BigBeetleState diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp index 01738e4bb..cc93efd8f 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp @@ -26,8 +26,8 @@ namespace TEN::Entities::TR4 constexpr auto BIG_SCORPION_ATTACK_RANGE = SQUARE(BLOCK(1.35)); constexpr auto BIG_SCORPION_RUN_RANGE = SQUARE(BLOCK(2)); - const auto BigScorpionBite1 = CreatureBiteInfo(Vector3i::Zero, 8); - const auto BigScorpionBite2 = CreatureBiteInfo(Vector3i::Zero, 23); + const auto BigScorpionBite1 = CreatureBiteInfo(Vector3::Zero, 8); + const auto BigScorpionBite2 = CreatureBiteInfo(Vector3::Zero, 23); const auto BigScorpionAttackJoints = std::vector{ 8, 20, 21, 23, 24 }; enum BigScorpionState diff --git a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp index 89a3371b2..c7a9c671b 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp @@ -33,7 +33,7 @@ namespace TEN::Entities::TR4 constexpr auto CROC_STATE_RUN_TURN_RATE_MAX = ANGLE(5.0f); constexpr auto CROC_STATE_SWIM_TURN_RATE_MAX = ANGLE(3.0f); - const auto CrocodileBite = CreatureBiteInfo(Vector3i(0, -100, 500), 9); + const auto CrocodileBite = CreatureBiteInfo(Vector3(0, -100, 500), 9); const auto CrocodileBiteAttackJoints = std::vector{ 8, 9 }; enum CrocodileState @@ -93,8 +93,8 @@ namespace TEN::Entities::TR4 int waterDepth = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); if (waterDepth != NO_HEIGHT) { - creature->LOT.Step = SECTOR(20); - creature->LOT.Drop = -SECTOR(20); + creature->LOT.Step = BLOCK(20); + creature->LOT.Drop = -BLOCK(20); creature->LOT.Fly = CROC_SWIM_SPEED; } else diff --git a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp index e41bc524c..bc603df7d 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp @@ -22,7 +22,7 @@ namespace TEN::Entities::TR4 constexpr auto DOG_BITE_ATTACK_RANGE = SQUARE(BLOCK(0.55)); constexpr auto DOG_JUMP_ATTACK_RANGE = SQUARE(BLOCK(1)); - const auto DogBite = CreatureBiteInfo(Vector3i(0, 0, 100), 3); + const auto DogBite = CreatureBiteInfo(Vector3(0, 0, 100), 3); const auto DogJumpAttackJoints = std::vector{ 3, 6, 9, 10, 13, 14 }; const auto DogBiteAttackJoints = std::vector{ 3, 6 }; @@ -146,7 +146,7 @@ namespace TEN::Entities::TR4 angle = CreatureTurn(item, creature->MaxTurn); joint0 = angle * 4; - if (creature->HurtByLara || distance < pow(SECTOR(3), 2) && !(item->AIBits & MODIFY)) + if (creature->HurtByLara || distance < pow(BLOCK(3), 2) && !(item->AIBits & MODIFY)) { AlertAllGuards(itemNumber); item->AIBits &= ~MODIFY; @@ -297,7 +297,7 @@ namespace TEN::Entities::TR4 { if (AI.bite && AI.distance < DOG_JUMP_ATTACK_RANGE) item->Animation.TargetState = DOG_STATE_JUMP_ATTACK; - else if (AI.distance < pow(SECTOR(1.5f), 2)) + else if (AI.distance < pow(BLOCK(1.5f), 2)) { item->Animation.TargetState = DOG_STATE_STALK_IDLE; item->Animation.RequiredState = DOG_STATE_STALK; @@ -320,7 +320,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = DOG_STATE_BITE_ATTACK; item->Animation.RequiredState = DOG_STATE_STALK; } - else if (AI.distance > pow(SECTOR(1.5f), 2) || item->HitStatus) + else if (AI.distance > pow(BLOCK(1.5f), 2) || item->HitStatus) item->Animation.TargetState = DOG_STATE_RUN_FORWARD; } else diff --git a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp index 7fe04601c..b37d4f247 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_enemy_jeep.cpp @@ -39,9 +39,9 @@ namespace TEN::Entities::TR4 grenadeItem->Pose.Orientation.y = item->Pose.Orientation.y - ANGLE(180.0f); grenadeItem->Pose.Orientation.z = 0; - grenadeItem->Pose.Position.x = item->Pose.Position.x + SECTOR(1) * phd_sin(grenadeItem->Pose.Orientation.y); + grenadeItem->Pose.Position.x = item->Pose.Position.x + BLOCK(1) * phd_sin(grenadeItem->Pose.Orientation.y); grenadeItem->Pose.Position.y = item->Pose.Position.y - CLICK(3); - grenadeItem->Pose.Position.z = item->Pose.Position.x + SECTOR(1) * phd_cos(grenadeItem->Pose.Orientation.y); + grenadeItem->Pose.Position.z = item->Pose.Position.x + BLOCK(1) * phd_cos(grenadeItem->Pose.Orientation.y); for (int i = 0; i < 5; i++) TriggerGunSmoke(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 0, 0, 0, 1, LaraWeaponType::GrenadeLauncher, 32); @@ -79,7 +79,7 @@ namespace TEN::Entities::TR4 item->ItemFlags[1] = i; other->ItemFlags[0] = -80; - other->Pose.Position.y = item->Pose.Position.y - SECTOR(1); + other->Pose.Position.y = item->Pose.Position.y - BLOCK(1); } } } @@ -140,8 +140,8 @@ namespace TEN::Entities::TR4 short angle = phd_atan(dz, dx) - item->Pose.Orientation.y; int distance; - if (dx > SECTOR(31.25f) || dx < -SECTOR(31.25f) || - dz > SECTOR(31.25f) || dz < -SECTOR(31.25f)) + if (dx > BLOCK(31.25f) || dx < -BLOCK(31.25f) || + dz > BLOCK(31.25f) || dz < -BLOCK(31.25f)) { distance = INT_MAX; } @@ -164,7 +164,7 @@ namespace TEN::Entities::TR4 if (item->Animation.RequiredState != NO_STATE) item->Animation.TargetState = item->Animation.RequiredState; - else if (AI.distance > pow(SECTOR(1), 2) || Lara.Location >= item->ItemFlags[3]) + else if (AI.distance > pow(BLOCK(1), 2) || Lara.Location >= item->ItemFlags[3]) item->Animation.TargetState = 1; break; @@ -243,7 +243,7 @@ namespace TEN::Entities::TR4 } } - if (AI.distance < pow(SECTOR(1.5f), 2) || item->ItemFlags[3] == -2) + if (AI.distance < pow(BLOCK(1.5f), 2) || item->ItemFlags[3] == -2) creature->ReachedGoal = true; if (creature->ReachedGoal) @@ -266,8 +266,8 @@ namespace TEN::Entities::TR4 } } - if (distance > pow(SECTOR(2), 2) && - distance < pow(SECTOR(10), 2) && + if (distance > pow(BLOCK(2), 2) && + distance < pow(BLOCK(10), 2) && !item->ItemFlags[2] && (angle < -ANGLE(112.5f) || angle > ANGLE(112.5f))) { @@ -372,7 +372,7 @@ namespace TEN::Entities::TR4 item->Animation.Velocity.y = 0; } - SoundEffect(SFX_TR4_VEHICLE_JEEP_MOVING, &item->Pose, SoundEnvironment::Land, 1.0f + (float)item->ItemFlags[0] / SECTOR(8)); // TODO: Check actual sound! + SoundEffect(SFX_TR4_VEHICLE_JEEP_MOVING, &item->Pose, SoundEnvironment::Land, 1.0f + (float)item->ItemFlags[0] / BLOCK(8)); // TODO: Check actual sound! } } } diff --git a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp index 9e61b9c20..c5bca20b2 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp @@ -18,8 +18,8 @@ namespace TEN::Entities::TR4 { constexpr auto GUIDE_ATTACK_DAMAGE = 20; - const auto GuideBite1 = CreatureBiteInfo(Vector3i(0, 20, 180), 18); - const auto GuideBite2 = CreatureBiteInfo(Vector3i(30, 80, 50), 15); + const auto GuideBite1 = CreatureBiteInfo(Vector3(0, 20, 180), 18); + const auto GuideBite2 = CreatureBiteInfo(Vector3(30, 80, 50), 15); const auto GuideLeftFingerSwapJoints = std::vector{ 15 }; const auto GuideRightHandSwapJoints = std::vector{ 18 }; const auto GuideHeadSwapJoints = std::vector{ 21 }; diff --git a/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp b/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp index e720dc6b9..866fe6e9a 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp @@ -16,7 +16,7 @@ namespace TEN::Entities::TR4 constexpr auto HAMMERHEAD_BITE_ATTACK_DAMAGE = 120; constexpr auto HAMMERHEAD_ATTACK_RANGE = SQUARE(BLOCK(0.66f)); - const auto HammerheadBite = CreatureBiteInfo(Vector3i::Zero, 12); + const auto HammerheadBite = CreatureBiteInfo(Vector3::Zero, 12); const auto HammerheadBiteAttackJoints = std::vector{ 10, 12, 13 }; enum HammerheadState @@ -106,7 +106,7 @@ namespace TEN::Entities::TR4 case HAMMERHEAD_STATE_SWIM_SLOW: creature->MaxTurn = ANGLE(7.0f); - if (AI.distance <= pow(SECTOR(1), 2)) + if (AI.distance <= pow(BLOCK(1), 2)) { if (AI.distance < HAMMERHEAD_ATTACK_RANGE) item->Animation.TargetState = HAMMERHEAD_STATE_IDLE_BITE_ATTACK; @@ -117,7 +117,7 @@ namespace TEN::Entities::TR4 break; case HAMMERHEAD_STATE_SWIM_FAST: - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_SLOW; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp b/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp index e9397e30f..d87124e6a 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp @@ -30,11 +30,11 @@ namespace TEN::Entities::TR4 constexpr auto HARPY_SWOOP_ATTACK_DAMAGE = 10; constexpr auto HARPY_STINGER_POISON_POTENCY = 8; - const auto HarpyBite1 = CreatureBiteInfo(Vector3i::Zero, 4); - const auto HarpyBite2 = CreatureBiteInfo(Vector3i::Zero, 2); - const auto HarpyBite3 = CreatureBiteInfo(Vector3i::Zero, 15); - const auto HarpyAttack1 = CreatureBiteInfo(Vector3i(0, 128, 0), 2); - const auto HarpyAttack2 = CreatureBiteInfo(Vector3i(0, 128, 0), 4); + const auto HarpyBite1 = CreatureBiteInfo(Vector3::Zero, 4); + const auto HarpyBite2 = CreatureBiteInfo(Vector3::Zero, 2); + const auto HarpyBite3 = CreatureBiteInfo(Vector3::Zero, 15); + const auto HarpyAttack1 = CreatureBiteInfo(Vector3(0, 128, 0), 2); + const auto HarpyAttack2 = CreatureBiteInfo(Vector3(0, 128, 0), 4); const auto HarpySwoopAttackJoints = std::vector{ 2, 4, 15 }; const auto HarpyStingerAttackJoints = std::vector{ 2, 4 }; diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp index ea0b360b3..12ace8fd6 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp @@ -20,17 +20,17 @@ using namespace TEN::Math; namespace TEN::Entities::TR4 { - const auto HorsemanBite1 = CreatureBiteInfo(Vector3i::Zero, 6); - const auto HorsemanBite2 = CreatureBiteInfo(Vector3i::Zero, 14); - const auto HorsemanBite3 = CreatureBiteInfo(Vector3i::Zero, 10); + const auto HorsemanBite1 = CreatureBiteInfo(Vector3::Zero, 6); + const auto HorsemanBite2 = CreatureBiteInfo(Vector3::Zero, 14); + const auto HorsemanBite3 = CreatureBiteInfo(Vector3::Zero, 10); const auto HorsemanAxeAttackJoints = std::vector{ 5, 6 }; const auto HorsemanKickAttackJoints = std::vector{ 14 }; const auto HorsemanMountedAttackJoints = std::vector{ 5, 6, 10 }; const auto HorsemanShieldAttackJoints = std::vector{ 10 }; - const auto HorseBite1 = CreatureBiteInfo(Vector3i::Zero, 13); - const auto HorseBite2 = CreatureBiteInfo(Vector3i::Zero, 17); - const auto HorseBite3 = CreatureBiteInfo(Vector3i::Zero, 19); + const auto HorseBite1 = CreatureBiteInfo(Vector3::Zero, 13); + const auto HorseBite2 = CreatureBiteInfo(Vector3::Zero, 17); + const auto HorseBite3 = CreatureBiteInfo(Vector3::Zero, 19); enum HorsemanState { @@ -324,7 +324,7 @@ namespace TEN::Entities::TR4 if (item->HitStatus && laraAI.angle < ANGLE(67.5f) && laraAI.angle > -ANGLE(67.5f) && - laraAI.distance < pow(SECTOR(2), 2)) + laraAI.distance < pow(BLOCK(2), 2)) { if (item->Animation.ActiveState != HORSEMAN_STATE_SHIELD) { @@ -388,7 +388,7 @@ namespace TEN::Entities::TR4 creature->Flags || creature->ReachedGoal) { - if (laraAI.distance > pow(SECTOR(4), 2) || + if (laraAI.distance > pow(BLOCK(4), 2) || creature->ReachedGoal) { creature->Enemy = LaraItem; @@ -408,16 +408,16 @@ namespace TEN::Entities::TR4 } } - if (AI.distance >= pow(SECTOR(1), 2)) + if (AI.distance >= pow(BLOCK(1), 2)) { if (AI.bite) { if (AI.angle >= -ANGLE(10.0f) || - (AI.distance >= pow(SECTOR(1), 2) && + (AI.distance >= pow(BLOCK(1), 2) && (AI.distance >= pow(1365, 2) || AI.angle <= -ANGLE(20.0f)))) { if (AI.angle > ANGLE(10.0f) && - (AI.distance < pow(SECTOR(1), 2) || + (AI.distance < pow(BLOCK(1), 2) || (AI.distance < pow(1365, 2) && AI.angle < ANGLE(20.0f)))) { item->Animation.TargetState = HORSEMAN_STATE_MOUNTED_ATTACK_RIGHT; @@ -439,11 +439,11 @@ namespace TEN::Entities::TR4 if (AI.bite) { if (AI.angle >= -ANGLE(10.0f) || - (AI.distance >= pow(SECTOR(1), 2) && + (AI.distance >= pow(BLOCK(1), 2) && (AI.distance >= pow(1365, 2) || AI.angle <= -ANGLE(20.0f)))) { if (AI.angle > ANGLE(10.0f) && - (AI.distance < pow(SECTOR(1), 2) || + (AI.distance < pow(BLOCK(1), 2) || AI.distance < pow(1365, 2) && AI.angle < ANGLE(20.0f))) { @@ -465,7 +465,7 @@ namespace TEN::Entities::TR4 case HORSEMAN_STATE_MOUNTED_WALK_FORWARD: creature->MaxTurn = ANGLE(1.5f); - if (laraAI.distance > pow(SECTOR(4), 2) || creature->ReachedGoal || creature->Enemy->IsLara()) + if (laraAI.distance > pow(BLOCK(4), 2) || creature->ReachedGoal || creature->Enemy->IsLara()) { item->Animation.TargetState = HORSEMAN_STATE_MOUNTED_RUN_FORWARD; creature->ReachedGoal = false; @@ -497,7 +497,7 @@ namespace TEN::Entities::TR4 } else if (creature->ReachedGoal || !horseItem->Flags && - AI.distance < pow(SECTOR(1), 2) && + AI.distance < pow(BLOCK(1), 2) && AI.bite && AI.angle < ANGLE(10.0f) && AI.angle > -ANGLE(10.0f)) @@ -584,7 +584,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = item->Animation.RequiredState; else if (AI.bite && AI.distance < pow(682,2)) item->Animation.TargetState = HORSEMAN_STATE_IDLE_ATTACK; - else if (AI.distance < pow(SECTOR(6), 2) && AI.distance > pow(682, 2)) + else if (AI.distance < pow(BLOCK(6), 2) && AI.distance > pow(682, 2)) item->Animation.TargetState = HORSEMAN_STATE_WALK_FORWARD; } else @@ -625,7 +625,7 @@ namespace TEN::Entities::TR4 else item->Animation.TargetState = HORSEMAN_STATE_IDLE; } - else if (AI.distance < pow(SECTOR(5), 2) && AI.distance > pow(1365, 2)) + else if (AI.distance < pow(BLOCK(5), 2) && AI.distance > pow(1365, 2)) item->Animation.TargetState = HORSEMAN_STATE_RUN_FORWARD; break; @@ -720,7 +720,7 @@ namespace TEN::Entities::TR4 horseItem->Animation.FrameNumber = GetAnimData(horseItem).frameBase; } - if (laraAI.distance > pow(SECTOR(4), 2) || creature->ReachedGoal) + if (laraAI.distance > pow(BLOCK(4), 2) || creature->ReachedGoal) { creature->ReachedGoal = false; creature->Enemy = LaraItem; diff --git a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp index 68688389a..0c59403fb 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp @@ -24,7 +24,7 @@ namespace TEN::Entities::TR4 constexpr auto KTEMPLAR_IDLE_TURN_RATE_MAX = ANGLE(2.0f); constexpr auto KTEMPLAR_WALK_TURN_RATE_MAX = ANGLE(7.0f); - const auto KnightTemplarBite = CreatureBiteInfo(Vector3i::Zero, 11); + const auto KnightTemplarBite = CreatureBiteInfo(Vector3::Zero, 11); const auto KnightTemplarSwordAttackJoints = std::vector{ 10, 11 }; enum KnightTemplarState @@ -192,8 +192,8 @@ namespace TEN::Entities::TR4 { for (auto& mesh : room.mesh) { - if (abs(pos.x - mesh.pos.Position.x) < SECTOR(1) && - abs(pos.z - mesh.pos.Position.z) < SECTOR(1) && + if (abs(pos.x - mesh.pos.Position.x) < BLOCK(1) && + abs(pos.z - mesh.pos.Position.z) < BLOCK(1) && StaticObjects[mesh.staticNumber].shatterType == SHT_NONE) { ShatterObject(nullptr, &mesh, -64, LaraItem->RoomNumber, 0); diff --git a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp index b885b1073..84ffb9c7e 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp @@ -28,8 +28,8 @@ namespace TEN::Entities::TR4 constexpr auto MUMMY_WALK_TURN_RATE_MAX = ANGLE(7.0f); constexpr auto MUMMY_ATTACK_TURN_RATE_MAX = ANGLE(7.0f); - const auto MummyBite1 = CreatureBiteInfo(Vector3i::Zero, 11); - const auto MummyBite2 = CreatureBiteInfo(Vector3i::Zero, 14); + const auto MummyBite1 = CreatureBiteInfo(Vector3::Zero, 11); + const auto MummyBite2 = CreatureBiteInfo(Vector3::Zero, 14); const auto MummySwipeAttackJoints = std::vector{ 11, 14 }; enum MummyState diff --git a/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp b/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp index ca66c2dc6..8fc51518b 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mutant.cpp @@ -245,11 +245,11 @@ namespace TEN::Entities::TR4 void MutantAIFix(ItemInfo* item, AI_INFO* AI) { - MoveItemFront(item, SECTOR(2)); + MoveItemFront(item, BLOCK(2)); item->Pose.Position.y -= CLICK(3); CreatureAIInfo(item, AI); item->Pose.Position.y += CLICK(3); - MoveItemBack(item, SECTOR(2)); + MoveItemBack(item, BLOCK(2)); } void InitializeCrocgod(short itemNumber) diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp index a724125e4..9c4d8a199 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp @@ -34,7 +34,7 @@ namespace TEN::Entities::TR4 constexpr auto SAS_WALK_RANGE = SQUARE(BLOCK(2)); constexpr auto SAS_SHOOT_RANGE = SQUARE(BLOCK(3)); - const auto SasGunBite = CreatureBiteInfo(Vector3i(0, 420, 80), 7); + const auto SasGunBite = CreatureBiteInfo(Vector3(0, 420, 80), 7); const auto SasDragBodyPosition = Vector3i(0, 0, -460); const auto SasDragBounds = ObjectCollisionBounds diff --git a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp index 722746e05..83900153e 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sentry_gun.cpp @@ -21,7 +21,7 @@ using namespace TEN::Gui; namespace TEN::Entities::TR4 { const auto SentryGunFlameOffset = Vector3i(-140, 0, 0); - const auto SentryGunBite = CreatureBiteInfo(Vector3i::Zero, 8); + const auto SentryGunBite = CreatureBiteInfo(Vector3::Zero, 8); void InitializeSentryGun(short itemNumber) { @@ -78,11 +78,11 @@ namespace TEN::Entities::TR4 if (Targetable(item, &AI)) { - if (AI.distance < pow(SECTOR(9), 2)) + if (AI.distance < pow(BLOCK(9), 2)) { if (!g_Gui.IsObjectInInventory(ID_PUZZLE_ITEM5) && !item->ItemFlags[0]) { - if (AI.distance <= pow(SECTOR(2), 2)) + if (AI.distance <= pow(BLOCK(2), 2)) { // Throw fire ThrowFire(itemNumber, 7, SentryGunFlameOffset, SentryGunFlameOffset); @@ -140,7 +140,7 @@ namespace TEN::Entities::TR4 } else { - ExplodingDeath(itemNumber, BODY_EXPLODE | BODY_NO_BOUNCE); + ExplodingDeath(itemNumber, BODY_DO_EXPLOSION | BODY_NO_BOUNCE); DisableEntityAI(itemNumber); KillItem(itemNumber); diff --git a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp index c178942ee..0862aa4c6 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp @@ -44,10 +44,10 @@ namespace TEN::Entities::TR4 constexpr auto SETH_WALK_TURN_RATE_MAX = ANGLE(7.0f); constexpr auto SETH_RUN_TURN_RATE_MAX = ANGLE(11.0f); - const auto SethBite1 = CreatureBiteInfo(Vector3i(0, 220, 50), 17); - const auto SethBite2 = CreatureBiteInfo(Vector3i(0, 220, 50), 13); - const auto SethAttack1 = CreatureBiteInfo(Vector3i(-16, 200, 32), 13); - const auto SethAttack2 = CreatureBiteInfo(Vector3i(16, 200, 32), 17); + const auto SethBite1 = CreatureBiteInfo(Vector3(0, 220, 50), 17); + const auto SethBite2 = CreatureBiteInfo(Vector3(0, 220, 50), 13); + const auto SethAttack1 = CreatureBiteInfo(Vector3(-16, 200, 32), 13); + const auto SethAttack2 = CreatureBiteInfo(Vector3(16, 200, 32), 17); const auto SethPounceAttackJoints1 = std::vector{ 13, 14, 15 }; const auto SethPounceAttackJoints2 = std::vector{ 16, 17, 18 }; @@ -667,7 +667,7 @@ namespace TEN::Entities::TR4 laraItem->Pose = Pose(item->Pose.Position, item->Pose.Orientation); if (item->RoomNumber != laraItem->RoomNumber) - ItemNewRoom(lara.ItemNumber, item->RoomNumber); + ItemNewRoom(laraItem->Index, item->RoomNumber); AnimateItem(laraItem); laraItem->HitPoints = -1; diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp index f6c911e62..5922fb0d4 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp @@ -26,7 +26,7 @@ namespace TEN::Entities::TR4 { constexpr auto SKELETON_ATTACK_DAMAGE = 80; - const auto SkeletonBite = CreatureBiteInfo(Vector3i(0, -16, 200), 11); + const auto SkeletonBite = CreatureBiteInfo(Vector3(0, -16, 200), 11); const auto SkeletonSwordAttackJoints = std::vector{ 15, 16 }; enum SkeletonState diff --git a/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp b/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp index 8571490eb..4d63ba910 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp @@ -23,8 +23,8 @@ namespace TEN::Entities::TR4 constexpr auto SMALL_SCORPION_ATTACK_RANGE = SQUARE(BLOCK(0.31)); - const auto SmallScorpionBite1 = CreatureBiteInfo(Vector3i::Zero, 0); - const auto SmallScorpionBite2 = CreatureBiteInfo(Vector3i::Zero, 23); + const auto SmallScorpionBite1 = CreatureBiteInfo(Vector3::Zero, 0); + const auto SmallScorpionBite2 = CreatureBiteInfo(Vector3::Zero, 23); const auto SmallScorpionAttackJoints = std::vector{ 8, 22, 23, 25, 26 }; enum SmallScorionState diff --git a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp index 5bf73a67b..2a3d172b3 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp @@ -20,7 +20,7 @@ namespace TEN::Entities::TR4 constexpr auto SPHINX_WALK_TURN_ANGLE = ANGLE(3.0f); constexpr auto SPHINX_RUN_TURN_ANGLE = ANGLE(0.33f); - const auto SphinxBite = CreatureBiteInfo(Vector3i::Zero, 6); + const auto SphinxBite = CreatureBiteInfo(Vector3::Zero, 6); const auto SphinxAttackJoints = std::vector{ 6 }; enum SphinxState @@ -90,8 +90,8 @@ namespace TEN::Entities::TR4 { auto* mesh = &room->mesh[i]; - if (((mesh->pos.Position.z / SECTOR(1)) == (z / SECTOR(1))) && - ((mesh->pos.Position.x / SECTOR(1)) == (x / SECTOR(1))) && + if (((mesh->pos.Position.z / BLOCK(1)) == (z / BLOCK(1))) && + ((mesh->pos.Position.x / BLOCK(1)) == (x / BLOCK(1))) && StaticObjects[mesh->staticNumber].shatterType != SHT_NONE) { ShatterObject(nullptr, mesh, -64, item->RoomNumber, 0); @@ -136,7 +136,7 @@ namespace TEN::Entities::TR4 case SPHINX_STATE_REST: creature->MaxTurn = 0; - if (AI.distance < pow(SECTOR(1), 2) || item->TriggerFlags) + if (AI.distance < pow(BLOCK(1), 2) || item->TriggerFlags) item->Animation.TargetState = SPHINX_STATE_SLEEP_TO_IDLE; // TODO: Use TestProbability(). @@ -148,7 +148,7 @@ namespace TEN::Entities::TR4 case SPHINX_STATE_REST_ALERTED: creature->MaxTurn = 0; - if (AI.distance < pow(SECTOR(1), 2) || item->TriggerFlags) + if (AI.distance < pow(BLOCK(1), 2) || item->TriggerFlags) item->Animation.TargetState = SPHINX_STATE_SLEEP_TO_IDLE; // TODO: Use TestProbability(). @@ -160,12 +160,12 @@ namespace TEN::Entities::TR4 case SPHINX_STATE_WALK_FORWARD: creature->MaxTurn = SPHINX_WALK_TURN_ANGLE; - if (AI.distance > pow(SECTOR(1), 2) && abs(AI.angle) <= ANGLE(2.8f) || + if (AI.distance > pow(BLOCK(1), 2) && abs(AI.angle) <= ANGLE(2.8f) || item->Animation.RequiredState == SPHINX_STATE_RUN_FORWARD) { item->Animation.TargetState = SPHINX_STATE_RUN_FORWARD; } - else if (AI.distance < pow(SECTOR(2), 2) && item->Animation.TargetState != SPHINX_STATE_RUN_FORWARD) + else if (AI.distance < pow(BLOCK(2), 2) && item->Animation.TargetState != SPHINX_STATE_RUN_FORWARD) { if (height2 <= (item->Pose.Position.y + CLICK(1)) && height2 >= (item->Pose.Position.y - CLICK(1))) @@ -193,7 +193,7 @@ namespace TEN::Entities::TR4 if (dx >= 50 || dz >= 50 || item->Animation.AnimNumber != Objects[item->ObjectNumber].animIndex) { - if (AI.distance > pow(SECTOR(2), 2) && abs(AI.angle) > ANGLE(2.8f)) + if (AI.distance > pow(BLOCK(2), 2) && abs(AI.angle) > ANGLE(2.8f)) item->Animation.TargetState = SPHINX_STATE_IDLE; } else @@ -208,7 +208,7 @@ namespace TEN::Entities::TR4 case SPHINX_STATE_WALK_BACK: creature->MaxTurn = SPHINX_WALK_TURN_ANGLE; - if (AI.distance > pow(SECTOR(2), 2) || + if (AI.distance > pow(BLOCK(2), 2) || height2 > (item->Pose.Position.y + CLICK(1)) || height2 < (item->Pose.Position.y - CLICK(1))) { diff --git a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp index 5933f4b3e..3aba0aafd 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp @@ -20,7 +20,7 @@ using namespace TEN::Math; namespace TEN::Entities::TR4 { - const auto TroopsBite1 = CreatureBiteInfo(Vector3i(0, 270, 40), 7); + const auto TroopsBite1 = CreatureBiteInfo(Vector3(0, 270, 40), 7); enum TroopState { @@ -242,7 +242,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = TROOP_STATE_RUN; else if (Targetable(item, &AI)) { - if (AI.distance < pow(SECTOR(3), 2) || AI.zoneNumber != AI.enemyZone) + if (AI.distance < pow(BLOCK(3), 2) || AI.zoneNumber != AI.enemyZone) { if (Random::TestProbability(1 / 2.0f)) item->Animation.TargetState = TROOP_STATE_AIM_3; @@ -255,9 +255,9 @@ namespace TEN::Entities::TR4 else { if ((creature->Alerted || creature->Mood != MoodType::Bored) && - (!(item->AIBits & FOLLOW) || !(item->AIBits & MODIFY) && distance <= pow(SECTOR(2), 2))) + (!(item->AIBits & FOLLOW) || !(item->AIBits & MODIFY) && distance <= pow(BLOCK(2), 2))) { - if (creature->Mood == MoodType::Bored || AI.distance <= pow(SECTOR(2), 2)) + if (creature->Mood == MoodType::Bored || AI.distance <= pow(BLOCK(2), 2)) { item->Animation.TargetState = TROOP_STATE_WALK; break; @@ -285,20 +285,20 @@ namespace TEN::Entities::TR4 if (item->AIBits & GUARD || item->AIBits & FOLLOW && (creature->ReachedGoal || - distance > pow(SECTOR(2), 2))) + distance > pow(BLOCK(2), 2))) { item->Animation.TargetState = TROOP_STATE_IDLE; } else if (Targetable(item, &AI)) { - if (AI.distance < pow(SECTOR(3), 2) || AI.enemyZone != AI.zoneNumber) + if (AI.distance < pow(BLOCK(3), 2) || AI.enemyZone != AI.zoneNumber) item->Animation.TargetState = TROOP_STATE_IDLE; else item->Animation.TargetState = TROOP_STATE_AIM_2; } else if (creature->Mood != MoodType::Bored) { - if (AI.distance > pow(SECTOR(2), 2)) + if (AI.distance > pow(BLOCK(2), 2)) item->Animation.TargetState = TROOP_STATE_RUN; } else if (AI.ahead) @@ -317,7 +317,7 @@ namespace TEN::Entities::TR4 if (item->AIBits & GUARD || item->AIBits & FOLLOW && (creature->ReachedGoal || - distance > pow(SECTOR(2), 2))) + distance > pow(BLOCK(2), 2))) { item->Animation.TargetState = TROOP_STATE_WALK; } @@ -328,7 +328,7 @@ namespace TEN::Entities::TR4 else if (creature->Mood == MoodType::Bored || creature->Mood == MoodType::Stalk && !(item->AIBits & FOLLOW) && - AI.distance < pow(SECTOR(2), 2)) + AI.distance < pow(BLOCK(2), 2)) { item->Animation.TargetState = TROOP_STATE_WALK; } @@ -413,7 +413,7 @@ namespace TEN::Entities::TR4 case TROOP_STATE_ATTACK_3: if (item->Animation.TargetState != TROOP_STATE_IDLE && (creature->Mood == MoodType::Escape || - AI.distance > pow(SECTOR(3), 2) || + AI.distance > pow(BLOCK(3), 2) || !Targetable(item, &AI))) { item->Animation.TargetState = TROOP_STATE_IDLE; diff --git a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp index 602f99b01..0a0731328 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp @@ -22,7 +22,7 @@ namespace TEN::Entities::TR4 { constexpr auto VON_CROY_FLAG_JUMP = 6; - const auto VonCroyBite = CreatureBiteInfo(Vector3i(0, 35, 130), 18); + const auto VonCroyBite = CreatureBiteInfo(Vector3(0, 35, 130), 18); const auto VonCroyKnifeSwapJoints = std::vector{ 7, 18 }; bool VonCroyPassedWaypoints[128]; @@ -106,8 +106,8 @@ namespace TEN::Entities::TR4 VON_CROY_ANIM_LARA_INTERACT_COME_CLOSE = 32, VON_CROY_ANIM_LARA_INTERACT_STOP = 33, VON_CROY_ANIM_LARA_INTERACT_STOP_TO_COME = 34, - VON_CROY_ANIM_CLIMB_DOWN_1_SECTOR = 35, - VON_CROY_ANIM_CLIMB_DOWN_2_SECTORS = 36, + VON_CROY_ANIM_CLIMB_DOWN_1_BLOCK = 35, + VON_CROY_ANIM_CLIMB_DOWN_2_BLOCKS = 36, VON_CROY_ANIM_JUMP_TO_HANG = 37, VON_CROY_ANIM_SHIMMY_TO_THE_RIGHT = 38, VON_CROY_ANIM_CLIMB = 39, @@ -246,7 +246,7 @@ namespace TEN::Entities::TR4 dx = currentItem->Pose.Position.x - item->Pose.Position.x; dz = currentItem->Pose.Position.z - item->Pose.Position.z; - if (abs(dx) < SECTOR(5) && abs(dz) < SECTOR(5)) + if (abs(dx) < BLOCK(5) && abs(dz) < BLOCK(5)) { distance = pow(dx, 2) + pow(dz, 2); if (distance < minDistance) @@ -268,7 +268,7 @@ namespace TEN::Entities::TR4 AI_INFO AI; // HACK: Even the most advanced zone in TR must have a step height of 1024, so we need to recreate zones when step difference is higher. - if (item->Animation.AnimNumber == Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_2_SECTORS || + if (item->Animation.AnimNumber == Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_2_BLOCKS || item->Animation.AnimNumber == Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_UP_AFTER_JUMP) { short oldRoom = item->RoomNumber; @@ -308,7 +308,7 @@ namespace TEN::Entities::TR4 laraAI.enemyFacing = laraAI.angle - LaraItem->Pose.Position.x + -ANGLE(180.0f); int distance = 0; - if (dz > SECTOR(31.25f) || dz < -SECTOR(31.25f) || dx > SECTOR(31.25f) || dx < -SECTOR(31.25f)) + if (dz > BLOCK(31.25f) || dz < -BLOCK(31.25f) || dx > BLOCK(31.25f) || dx < -BLOCK(31.25f)) laraAI.distance = INT_MAX; else laraAI.distance = pow(dx, 2) + pow(dz, 2); @@ -496,20 +496,20 @@ namespace TEN::Entities::TR4 { if (Lara.Location >= item->ItemFlags[3]) { - if (!foundTarget || AI.distance >= pow(SECTOR(1.5f), 2) && - (item->TestMeshSwapFlags(18) || AI.distance >= pow(SECTOR(3), 2))) + if (!foundTarget || AI.distance >= pow(BLOCK(1.5f), 2) && + (item->TestMeshSwapFlags(18) || AI.distance >= pow(BLOCK(3), 2))) { if (creature->Enemy->IsLara()) { - if (AI.distance >= pow(SECTOR(2), 2)) + if (AI.distance >= pow(BLOCK(2), 2)) { - if (AI.distance > pow(SECTOR(4), 2)) + if (AI.distance > pow(BLOCK(4), 2)) item->Animation.TargetState = VON_CROY_STATE_RUN; } else item->Animation.TargetState = VON_CROY_STATE_IDLE; } - else if (Lara.Location > item->ItemFlags[3] && laraAI.distance > pow(SECTOR(2), 2)) + else if (Lara.Location > item->ItemFlags[3] && laraAI.distance > pow(BLOCK(2), 2)) item->Animation.TargetState = VON_CROY_STATE_RUN; } else @@ -521,7 +521,7 @@ namespace TEN::Entities::TR4 if (AI.bite) { - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = VON_CROY_STATE_IDLE; break; @@ -530,7 +530,7 @@ namespace TEN::Entities::TR4 if (creature->Mood == MoodType::Attack && !(creature->JumpAhead) && - AI.distance > pow(SECTOR(1), 2)) + AI.distance > pow(BLOCK(1), 2)) { item->Animation.TargetState = VON_CROY_STATE_RUN; } @@ -551,7 +551,7 @@ namespace TEN::Entities::TR4 creature->MaxTurn = ANGLE(11.0f); tilt = abs(angle) / 2; - if (AI.distance < pow(SECTOR(2), 2) || Lara.Location < creature->LocationAI) + if (AI.distance < pow(BLOCK(2), 2) || Lara.Location < creature->LocationAI) { item->Animation.TargetState = VON_CROY_STATE_IDLE; break; @@ -577,13 +577,13 @@ namespace TEN::Entities::TR4 item->AIBits & FOLLOW || creature->MonkeySwingAhead || creature->JumpAhead || - AI.distance < pow(SECTOR(1), 2)) + AI.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = VON_CROY_STATE_IDLE; break; } - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = VON_CROY_STATE_WALK; break; @@ -613,7 +613,7 @@ namespace TEN::Entities::TR4 if (item->BoxNumber == creature->LOT.TargetBox || !creature->MonkeySwingAhead) { probe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, probe.RoomNumber); - if (probe.Position.Ceiling == (probe.Position.Floor - SECTOR(1.5f))) + if (probe.Position.Ceiling == (probe.Position.Floor - BLOCK(1.5f))) item->Animation.TargetState = VON_CROY_STATE_START_MONKEY; } @@ -893,14 +893,14 @@ namespace TEN::Entities::TR4 creature->MaxTurn = 0; break; case -7: - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_2_SECTORS; + item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_2_BLOCKS; item->Animation.FrameNumber = GetAnimData(item).frameBase; item->Animation.ActiveState = VON_CROY_STATE_STEP_DOWN_HIGH; creature->MaxTurn = 0; break; case -4: - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_1_SECTOR; + item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_1_BLOCK; item->Animation.FrameNumber = GetAnimData(item).frameBase; item->Animation.ActiveState = VON_CROY_STATE_JUMP_DOWN_4_CLICKS; creature->MaxTurn = 0; diff --git a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp index 41086ea32..3c820a632 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp @@ -20,7 +20,7 @@ namespace TEN::Entities::TR4 constexpr auto WILD_BOAR_ATTACK_DAMAGE = 30; constexpr auto WILD_BOAR_ATTACK_RANGE = SQUARE(CLICK(1)); - const auto WildBoarBite = CreatureBiteInfo(Vector3i::Zero, 14); + const auto WildBoarBite = CreatureBiteInfo(Vector3::Zero, 14); enum WildBoarState { @@ -151,7 +151,7 @@ namespace TEN::Entities::TR4 break; case BOAR_STATE_RUN_FORWARD: - if (AI.distance >= pow(SECTOR(2), 2)) + if (AI.distance >= pow(BLOCK(2), 2)) { creature->MaxTurn = ANGLE(6.0f); item->Flags = 0; diff --git a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp index d4419b2f8..b0763ec17 100644 --- a/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_clockwork_beetle.cpp @@ -184,9 +184,9 @@ void ClockworkBeetleControl(short itemNumber) int dy = beetle->Pose.Position.y - item->Pose.Position.y; int dz = beetle->Pose.Position.z - item->Pose.Position.z; - if (dx > -SECTOR(1) && dx < SECTOR(1) && - dz > -SECTOR(1) && dz < SECTOR(1) && - dy > -SECTOR(1) && dy < SECTOR(1)) + if (dx > -BLOCK(1) && dx < BLOCK(1) && + dz > -BLOCK(1) && dz < BLOCK(1) && + dy > -BLOCK(1) && dy < BLOCK(1)) { break; } @@ -350,9 +350,9 @@ void UseClockworkBeetle(short flag) int dy = item->Pose.Position.y - item2->Pose.Position.y; int dz = item->Pose.Position.z - item2->Pose.Position.z; - if (dx > -SECTOR(1) && dx < SECTOR(1) && - dz > -SECTOR(1) && dz < SECTOR(1) && - dy > -SECTOR(1) && dy < SECTOR(1)) + if (dx > -BLOCK(1) && dx < BLOCK(1) && + dz > -BLOCK(1) && dz < BLOCK(1) && + dy > -BLOCK(1) && dy < BLOCK(1)) { break; } diff --git a/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp b/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp index 1cd775576..b3ccfe847 100644 --- a/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_obelisk.cpp @@ -82,12 +82,12 @@ void ObeliskControl(short itemNumber) pos2.y = item->Pose.Position.y; pos2.x = item->Pose.Position.z + (someNumber * phd_cos(item->Pose.Orientation.z + ANGLE(90.0f))); - if (abs(pos.x - LaraItem->Pose.Position.x) < SECTOR(20) && - abs(pos.y - LaraItem->Pose.Position.y) < SECTOR(20) && - abs(pos.z - LaraItem->Pose.Position.z) < SECTOR(20) && - abs(pos2.x - LaraItem->Pose.Position.x) < SECTOR(20) && - abs(pos2.y - LaraItem->Pose.Position.y) < SECTOR(20) && - abs(pos2.z - LaraItem->Pose.Position.z) < SECTOR(20)) + if (abs(pos.x - LaraItem->Pose.Position.x) < BLOCK(20) && + abs(pos.y - LaraItem->Pose.Position.y) < BLOCK(20) && + abs(pos.z - LaraItem->Pose.Position.z) < BLOCK(20) && + abs(pos2.x - LaraItem->Pose.Position.x) < BLOCK(20) && + abs(pos2.y - LaraItem->Pose.Position.y) < BLOCK(20) && + abs(pos2.z - LaraItem->Pose.Position.z) < BLOCK(20)) { if (!(GlobalCounter & 3)) { @@ -104,9 +104,9 @@ void ObeliskControl(short itemNumber) if (item->ItemFlags[3] >= 256 && item->TriggerFlags == 2) { - pos.x = item->Pose.Position.x + SECTOR(8) * phd_sin(item->Pose.Orientation.y); + pos.x = item->Pose.Position.x + BLOCK(8) * phd_sin(item->Pose.Orientation.y); pos.y = item->Pose.Position.y; - pos.z = item->Pose.Position.z + SECTOR(8) * phd_cos(item->Pose.Orientation.y + ANGLE(90.0f)); + pos.z = item->Pose.Position.z + BLOCK(8) * phd_cos(item->Pose.Orientation.y + ANGLE(90.0f)); SoundEffect(SFX_TR4_ELECTRIC_ARCING_LOOP, &Pose(Vector3i(pos))); @@ -116,12 +116,12 @@ void ObeliskControl(short itemNumber) pos2.y = (GetRandomControl() & 0x3FF) + pos.y - 512; pos2.z = (GetRandomControl() & 0x3FF) + pos.z - 512; - if (abs(pos.x - LaraItem->Pose.Position.x) < SECTOR(20) && - abs(pos.y - LaraItem->Pose.Position.y) < SECTOR(20) && - abs(pos.z - LaraItem->Pose.Position.z) < SECTOR(20) && - abs(pos2.x - LaraItem->Pose.Position.x) < SECTOR(20) && - abs(pos2.y - LaraItem->Pose.Position.y) < SECTOR(20) && - abs(pos2.z - LaraItem->Pose.Position.z) < SECTOR(20)) + if (abs(pos.x - LaraItem->Pose.Position.x) < BLOCK(20) && + abs(pos.y - LaraItem->Pose.Position.y) < BLOCK(20) && + abs(pos.z - LaraItem->Pose.Position.z) < BLOCK(20) && + abs(pos2.x - LaraItem->Pose.Position.x) < BLOCK(20) && + abs(pos2.y - LaraItem->Pose.Position.y) < BLOCK(20) && + abs(pos2.z - LaraItem->Pose.Position.z) < BLOCK(20)) { if (item->ItemFlags[2] != NO_ITEM) { diff --git a/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp b/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp index 4684c331c..1a86534cd 100644 --- a/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp @@ -16,9 +16,9 @@ const auto SarcophagusPosition = Vector3i(0, 0, -300); const ObjectCollisionBounds SarcophagusBounds = { GameBoundingBox( - -SECTOR(0.5f), SECTOR(0.5f), + -BLOCK(0.5f), BLOCK(0.5f), -100, 100, - -SECTOR(0.5f), 0 + -BLOCK(0.5f), 0 ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), 0), diff --git a/TombEngine/Objects/TR4/Object/tr4_scales.cpp b/TombEngine/Objects/TR4/Object/tr4_scales.cpp index 96258fd65..bc03367c2 100644 --- a/TombEngine/Objects/TR4/Object/tr4_scales.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_scales.cpp @@ -23,7 +23,7 @@ ObjectCollisionBounds ScalesBounds = GameBoundingBox( -CLICK(5.5f), -CLICK(5.5f), 0, 0, - -SECTOR(0.5f), SECTOR(0.5f)), + -BLOCK(0.5f), BLOCK(0.5f)), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), EulerAngles(ANGLE(10.0f), ANGLE(30.0f), ANGLE(10.0f))) diff --git a/TombEngine/Objects/TR4/Object/tr4_senet.cpp b/TombEngine/Objects/TR4/Object/tr4_senet.cpp index ea7011ff9..f7c71915d 100644 --- a/TombEngine/Objects/TR4/Object/tr4_senet.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_senet.cpp @@ -101,13 +101,13 @@ void GameSticksControl(short itemNumber) if (piece == -1) piece = 16; - x = SenetTargetX + SECTOR(1); - z = SenetTargetZ + SECTOR(piece - 5); + x = SenetTargetX + BLOCK(1); + z = SenetTargetZ + BLOCK(piece - 5); } else { - x = SenetTargetX + SECTOR(2 * number - 2); - z = SenetTargetZ + SECTOR(4 - piece); + x = SenetTargetX + BLOCK(2 * number - 2); + z = SenetTargetZ + BLOCK(4 - piece); } if (abs(x - item2->Pose.Position.x) < 128) @@ -176,8 +176,8 @@ void GameSticksControl(short itemNumber) z == item2->Pose.Position.z) { SenetPieceExplosionEffect(item2, number == 1 ? 0xFF8020 : 0x6060E0, -64); - item2->Pose.Position.x = SenetTargetX - SECTOR(4 * number) + SECTOR(7); - item2->Pose.Position.z = SenetTargetZ + SECTOR(i % 3); + item2->Pose.Position.x = SenetTargetX - BLOCK(4 * number) + BLOCK(7); + item2->Pose.Position.z = SenetTargetZ + BLOCK(i % 3); probedRoomNumber = GetCollision(item2->Pose.Position.x, item2->Pose.Position.y - 32, item2->Pose.Position.z, item2->RoomNumber).RoomNumber; if (item2->RoomNumber != probedRoomNumber) diff --git a/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp new file mode 100644 index 000000000..e685b46bb --- /dev/null +++ b/TombEngine/Objects/TR4/Trap/SpikyCeiling.cpp @@ -0,0 +1,97 @@ +#include "framework.h" +#include "Objects/TR4/Trap/SpikyCeiling.h" + +#include "Game/animation.h" +#include "Game/collision/collide_item.h" +#include "Game/collision/collide_room.h" +#include "Game/collision/sphere.h" +#include "Game/control/control.h" +#include "Game/effects/effects.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Sound/sound.h" +#include "Specific/level.h" + +namespace TEN::Entities::Traps +{ + // NOTES: + // ItemFlags[0] = Vertical velocity. Positive value moves down, negative value moves up. + + constexpr auto SPIKY_CEILING_HARM_DAMAGE = 15; + + void InitializeSpikyCeiling(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + item.ItemFlags[0] = item.TriggerFlags; + } + + void ControlSpikyCeiling(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + if (!TriggerActive(&item) || item.Status == ITEM_DEACTIVATED) + return; + + // Determine height bounds. + auto bounds = GameBoundingBox(&item); + int upperFloorBound = bounds.Y2; + int lowerCeilBound = bounds.Y1; + + // Get point collision. + auto pointColl = GetCollision(&item); + int relFloorHeight = pointColl.Position.Floor - item.Pose.Position.y; + int relCeilHeight = pointColl.Position.Ceiling - item.Pose.Position.y; + + int verticalVel = item.ItemFlags[0]; + + // Stop moving. + if ((verticalVel > 0 && relFloorHeight <= upperFloorBound) || + (verticalVel < 0 && relCeilHeight >= lowerCeilBound)) + { + item.Status = ITEM_DEACTIVATED; + StopSoundEffect(SFX_TR4_ROLLING_BALL); + } + // Move. + else + { + item.Pose.Position.y += verticalVel; + + if (pointColl.RoomNumber != item.RoomNumber) + ItemNewRoom(itemNumber, pointColl.RoomNumber); + + SoundEffect(SFX_TR4_ROLLING_BALL, &item.Pose); + } + } + + void CollideSpikyCeiling(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) + { + auto& item = g_Level.Items[itemNumber]; + + if (item.ObjectNumber != ID_SPIKY_CEILING) + return; + + // Collide with objects. + if (item.Status == ITEM_ACTIVE) + { + if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + return; + + TestCollision(&item, playerItem); + } + else if (item.Status != ITEM_INVISIBLE) + { + ObjectCollision(itemNumber, playerItem, coll); + } + + // Damage entity. + if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + { + DoDamage(playerItem, SPIKY_CEILING_HARM_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(); + + SoundEffect(SFX_TR4_LARA_GRABFEET, &playerItem->Pose); + } + } +} diff --git a/TombEngine/Objects/TR4/Trap/SpikyCeiling.h b/TombEngine/Objects/TR4/Trap/SpikyCeiling.h new file mode 100644 index 000000000..87dc1cd75 --- /dev/null +++ b/TombEngine/Objects/TR4/Trap/SpikyCeiling.h @@ -0,0 +1,11 @@ +#pragma once + +struct CollisionInfo; +struct ItemInfo; + +namespace TEN::Entities::Traps +{ + void InitializeSpikyCeiling(short itemNumber); + void ControlSpikyCeiling(short itemNumber); + void CollideSpikyCeiling(short itemNumber, ItemInfo* item, CollisionInfo* coll); +} diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.cpp b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp new file mode 100644 index 000000000..d3dda9014 --- /dev/null +++ b/TombEngine/Objects/TR4/Trap/SpikyWall.cpp @@ -0,0 +1,92 @@ +#include "framework.h" +#include "Objects/TR4/Trap/SpikyWall.h" + +#include "Game/collision/collide_item.h" +#include "Game/collision/collide_room.h" +#include "Game/collision/sphere.h" +#include "Game/control/control.h" +#include "Game/effects/effects.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Math/Math.h" +#include "Sound/sound.h" +#include "Specific/level.h" + +using namespace TEN::Math; + +namespace TEN::Entities::Traps +{ + constexpr auto SPIKY_WALL_HARM_DAMAGE = 15; + + void InitializeSpikyWall(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + item.ItemFlags[0] = item.TriggerFlags; + } + + void ControlSpikyWall(short itemNumber) + { + auto& item = g_Level.Items[itemNumber]; + + if (!TriggerActive(&item) || item.Status == ITEM_DEACTIVATED) + return; + + int forwardVel = item.ItemFlags[0]; + auto bounds = GameBoundingBox(&item); + + // Get point collision. + auto pointColl = GetCollision(&item, item.Pose.Orientation.y, (forwardVel >= 0) ? bounds.Z2 : bounds.Z1); + int upperFloorBound = item.Pose.Position.y; + int lowerCeilBound = item.Pose.Position.y + bounds.Y1; + + // Stop moving. + if (pointColl.Position.Floor < upperFloorBound || + pointColl.Position.Ceiling > lowerCeilBound) + { + item.Status = ITEM_DEACTIVATED; + StopSoundEffect(SFX_TR4_ROLLING_BALL); + } + // Move. + else + { + item.Pose.Position = Geometry::TranslatePoint(item.Pose.Position, item.Pose.Orientation.y, forwardVel); + + if (pointColl.RoomNumber != item.RoomNumber) + ItemNewRoom(itemNumber, pointColl.RoomNumber); + + SoundEffect(SFX_TR4_ROLLING_BALL, &item.Pose); + } + } + + void CollideSpikyWall(short itemNumber, ItemInfo* playerItem, CollisionInfo* coll) + { + auto& item = g_Level.Items[itemNumber]; + + if (item.ObjectNumber != ID_SPIKY_WALL) + return; + + // Collide with objects. + if (item.Status == ITEM_ACTIVE) + { + if (!TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + return; + + TestCollision(&item, playerItem); + } + else if (item.Status != ITEM_INVISIBLE) + { + ObjectCollision(itemNumber, playerItem, coll); + } + + // Damage entity. + if (TestBoundsCollide(&item, playerItem, coll->Setup.Radius)) + { + DoDamage(playerItem, SPIKY_WALL_HARM_DAMAGE); + DoLotsOfBlood(playerItem->Pose.Position.x, playerItem->Pose.Position.y + CLICK(2), playerItem->Pose.Position.z, 4, playerItem->Pose.Orientation.y, playerItem->RoomNumber, 3); + playerItem->TouchBits.ClearAll(); + + SoundEffect(SFX_TR4_LARA_GRABFEET, &playerItem->Pose); + } + } +} diff --git a/TombEngine/Objects/TR4/Trap/SpikyWall.h b/TombEngine/Objects/TR4/Trap/SpikyWall.h new file mode 100644 index 000000000..60de66fab --- /dev/null +++ b/TombEngine/Objects/TR4/Trap/SpikyWall.h @@ -0,0 +1,11 @@ +#pragma once + +struct CollisionInfo; +struct ItemInfo; + +namespace TEN::Entities::Traps +{ + void InitializeSpikyWall(short itemNumber); + void ControlSpikyWall(short itemNumber); + void CollideSpikyWall(short itemNumber, ItemInfo* item, CollisionInfo* coll); +} diff --git a/TombEngine/Objects/TR4/Trap/tr4_spikyceiling.cpp b/TombEngine/Objects/TR4/Trap/tr4_spikyceiling.cpp deleted file mode 100644 index 462ae8476..000000000 --- a/TombEngine/Objects/TR4/Trap/tr4_spikyceiling.cpp +++ /dev/null @@ -1,48 +0,0 @@ -#include "framework.h" -#include "tr4_spikyceiling.h" -#include "Specific/level.h" -#include "Game/control/control.h" -#include "Sound/sound.h" -#include "Game/items.h" -#include "Game/collision/collide_room.h" -#include "Game/Lara/lara.h" -#include "Game/effects/effects.h" -#include "Game/animation.h" - -void ControlSpikyCeiling(short itemNumber) -{ - auto* item = &g_Level.Items[itemNumber]; - - if (TriggerActive(item) && item->Status != ITEM_DEACTIVATED) - { - int y = item->Pose.Position.y + ((item->ItemFlags[0] == 1) ? 10 : 5); - auto probe = GetCollision(item->Pose.Position.x, y, item->Pose.Position.z, item->RoomNumber); - - if (probe.Position.Floor < (y + SECTOR(1))) - { - item->Status = ITEM_DEACTIVATED; - StopSoundEffect(SFX_TR4_ROLLING_BALL); - } - else - { - item->Pose.Position.y = y; - - if (probe.RoomNumber != item->RoomNumber) - ItemNewRoom(itemNumber, probe.RoomNumber); - - SoundEffect(SFX_TR4_ROLLING_BALL, &item->Pose); - } - } - - if (item->TouchBits.TestAny()) - { - DoDamage(LaraItem, 20); - DoLotsOfBlood(LaraItem->Pose.Position.x, item->Pose.Position.y + CLICK(3), LaraItem->Pose.Position.z, 4, item->Pose.Orientation.y, LaraItem->RoomNumber, 3); - item->TouchBits.ClearAll(); - - SoundEffect(SFX_TR4_LARA_GRABFEET, &item->Pose); - } - - if (TriggerActive(item) && item->Status != ITEM_DEACTIVATED && item->ItemFlags[0] == 1) - AnimateItem(item); -} diff --git a/TombEngine/Objects/TR4/Trap/tr4_spikyceiling.h b/TombEngine/Objects/TR4/Trap/tr4_spikyceiling.h deleted file mode 100644 index 1a41f1af0..000000000 --- a/TombEngine/Objects/TR4/Trap/tr4_spikyceiling.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -void ControlSpikyCeiling(short itemNumber); diff --git a/TombEngine/Objects/TR4/Trap/tr4_spikywall.cpp b/TombEngine/Objects/TR4/Trap/tr4_spikywall.cpp deleted file mode 100644 index d55752faf..000000000 --- a/TombEngine/Objects/TR4/Trap/tr4_spikywall.cpp +++ /dev/null @@ -1,57 +0,0 @@ -#include "framework.h" -#include "Objects/TR4/Trap/tr4_spikywall.h" - -#include "Game/collision/collide_room.h" -#include "Game/control/control.h" -#include "Game/effects/effects.h" -#include "Game/items.h" -#include "Game/Lara/lara.h" -#include "Math/Math.h" -#include "Sound/sound.h" -#include "Specific/level.h" - -using namespace TEN::Math; - -void InitializeSpikyWall(short itemNumber) -{ - auto& item = g_Level.Items[itemNumber]; - - item.ItemFlags[0] = item.TriggerFlags; -} - -void ControlSpikyWall(short itemNumber) -{ - auto& item = g_Level.Items[itemNumber]; - - // Move wall. - if (TriggerActive(&item) && item.Status != ITEM_DEACTIVATED) - { - auto pos = Geometry::TranslatePoint(item.Pose.Position, item.Pose.Orientation.y, item.ItemFlags[0]); - auto pointColl = GetCollision(pos.x, pos.y, pos.z, item.RoomNumber); - - if (pointColl.Position.Floor != item.Pose.Position.y) - { - item.Status = ITEM_DEACTIVATED; - StopSoundEffect(SFX_TR4_ROLLING_BALL); - } - else - { - item.Pose.Position.x = pos.x; - item.Pose.Position.z = pos.z; - - if (pointColl.RoomNumber != item.RoomNumber) - ItemNewRoom(itemNumber, pointColl.RoomNumber); - - SoundEffect(SFX_TR4_ROLLING_BALL, &item.Pose); - } - } - - if (item.TouchBits.TestAny()) - { - DoDamage(LaraItem, 15); - DoLotsOfBlood(LaraItem->Pose.Position.x, LaraItem->Pose.Position.y - CLICK(2), LaraItem->Pose.Position.z, 4, item.Pose.Orientation.y, LaraItem->RoomNumber, 3); - item.TouchBits.ClearAll(); - - SoundEffect(SFX_TR4_LARA_GRABFEET, &item.Pose); - } -} diff --git a/TombEngine/Objects/TR4/Trap/tr4_spikywall.h b/TombEngine/Objects/TR4/Trap/tr4_spikywall.h deleted file mode 100644 index ce9fd4075..000000000 --- a/TombEngine/Objects/TR4/Trap/tr4_spikywall.h +++ /dev/null @@ -1,4 +0,0 @@ -#pragma once - -void ControlSpikyWall(short itemNumber); -void InitializeSpikyWall(short itemNumber); diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index ff09c5c3e..cf0ed03e6 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -21,13 +21,13 @@ namespace TEN::Entities::Traps const vector StargateHarmJoints = { 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25 }; const vector StargateBounds = { - Vector3i(-CLICK(2), CLICK(2), -SECTOR(2)), + Vector3i(-CLICK(2), CLICK(2), -BLOCK(2)), Vector3i(-896, -96, 96), Vector3i(-CLICK(2), CLICK(2), -128), Vector3i(0, -96, 96), - Vector3i(-CLICK(2), -384, -SECTOR(2)), + Vector3i(-CLICK(2), -384, -BLOCK(2)), Vector3i(0, -96, 96), - Vector3i(384, CLICK(2), -SECTOR(2)), + Vector3i(384, CLICK(2), -BLOCK(2)), Vector3i(0, -96, 96) }; diff --git a/TombEngine/Objects/TR4/Vehicles/jeep.cpp b/TombEngine/Objects/TR4/Vehicles/jeep.cpp index ef1f5c77c..667b41a52 100644 --- a/TombEngine/Objects/TR4/Vehicles/jeep.cpp +++ b/TombEngine/Objects/TR4/Vehicles/jeep.cpp @@ -223,10 +223,10 @@ namespace TEN::Entities::Vehicles static int DoJeepShift(ItemInfo* jeepItem, Vector3i* pos, Vector3i* old) { - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); - int oldX = old->x / SECTOR(1); - int oldZ = old->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); + int oldX = old->x / BLOCK(1); + int oldZ = old->z / BLOCK(1); int shiftX = pos->x & WALL_MASK; int shiftZ = pos->z & WALL_MASK; @@ -759,13 +759,13 @@ namespace TEN::Entities::Vehicles if (jeep->Velocity < 0) { - if (TrInput & VEHICLE_IN_RIGHT) + if (IsHeld(In::Right)) { jeep->TurnRate -= rot2; if (jeep->TurnRate < -rot1) jeep->TurnRate = -rot1; } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) { jeep->TurnRate += rot2; if (jeep->TurnRate > rot1) @@ -774,13 +774,13 @@ namespace TEN::Entities::Vehicles } else if (jeep->Velocity > 0) { - if (TrInput & VEHICLE_IN_RIGHT) + if (IsHeld(In::Right)) { jeep->TurnRate += rot2; if (jeep->TurnRate > rot1) jeep->TurnRate = rot1; } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) { jeep->TurnRate -= rot2; if (jeep->TurnRate < -rot1) @@ -789,7 +789,7 @@ namespace TEN::Entities::Vehicles } // Brake/reverse - if (TrInput & VEHICLE_IN_BRAKE) + if (IsHeld(In::Brake)) { if (jeep->Velocity < 0) { @@ -805,7 +805,7 @@ namespace TEN::Entities::Vehicles } } // Accelerate - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { if (jeep->Gear) { @@ -849,7 +849,7 @@ namespace TEN::Entities::Vehicles jeep->EngineRevs += (abs(revs) - jeep->EngineRevs) / 8; } - if (TrInput & VEHICLE_IN_BRAKE) + if (IsHeld(In::Brake)) { auto pos = GetJointPosition(jeepItem, 11, Vector3i(0, -144, -1024)); TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); @@ -919,7 +919,7 @@ namespace TEN::Entities::Vehicles laraItem->Animation.TargetState = JS_DEATH; else { - dismount = ((TrInput & VEHICLE_IN_BRAKE) && (TrInput & VEHICLE_IN_LEFT)) ? true : false; + dismount = (IsHeld(In::Brake) && IsHeld(In::Left)) ? true : false; if (dismount && !jeep->Velocity && !JeepNoGetOff) { if (JeepCanGetOff(jeepItem, laraItem)) @@ -948,14 +948,14 @@ namespace TEN::Entities::Vehicles } else { - if ((TrInput & VEHICLE_IN_ACCELERATE) && !(TrInput & VEHICLE_IN_BRAKE)) + if (IsHeld(In::Accelerate) && !IsHeld(In::Brake)) { laraItem->Animation.TargetState = JS_DRIVE_FORWARD; break; } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_FWD_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_FWD_RIGHT; } @@ -963,14 +963,14 @@ namespace TEN::Entities::Vehicles { if (!(DbInput & JEEP_IN_TOGGLE_REVERSE)) { - if ((TrInput & VEHICLE_IN_ACCELERATE) && !(TrInput & VEHICLE_IN_BRAKE)) + if (IsHeld(In::Accelerate) && !IsHeld(In::Brake)) { laraItem->TargetState = JS_DRIVE_FORWARD; break; } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->TargetState = JS_FWD_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->TargetState = JS_FWD_RIGHT; } else if (jeep->Gear < 1) @@ -996,9 +996,9 @@ namespace TEN::Entities::Vehicles else { if (jeep->Velocity & 0xFFFFFF00 || - TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_BRAKE)) + (IsHeld(In::Accelerate) || IsHeld(In::Brake))) { - if (TrInput & VEHICLE_IN_BRAKE) + if (IsHeld(In::Brake)) { if (jeep->Velocity <= 21844) laraItem->Animation.TargetState = JS_IDLE; @@ -1007,9 +1007,9 @@ namespace TEN::Entities::Vehicles } else { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_FWD_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_FWD_RIGHT; } } @@ -1025,7 +1025,7 @@ namespace TEN::Entities::Vehicles case 5: if (dead) laraItem->Animation.TargetState = JS_IDLE; - else if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_BRAKE)) + else if (IsHeld(In::Accelerate) || IsHeld(In::Brake)) laraItem->Animation.TargetState = JS_DRIVE_FORWARD; break; @@ -1035,9 +1035,9 @@ namespace TEN::Entities::Vehicles laraItem->Animation.TargetState = JS_IDLE; else if (jeep->Velocity & 0xFFFFFF00) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_FWD_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_FWD_RIGHT; } else @@ -1062,9 +1062,9 @@ namespace TEN::Entities::Vehicles } } } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_DRIVE_FORWARD; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_FWD_LEFT; else if (jeep->Velocity) laraItem->Animation.TargetState = JS_DRIVE_FORWARD; @@ -1108,9 +1108,9 @@ namespace TEN::Entities::Vehicles } } } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_DRIVE_FORWARD; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_FWD_RIGHT; else if (jeep->Velocity) laraItem->Animation.TargetState = JS_DRIVE_FORWARD; @@ -1148,9 +1148,9 @@ namespace TEN::Entities::Vehicles laraItem->Animation.TargetState = JS_DRIVE_BACK; else if (abs(jeep->Velocity) & 0xFFFFFF00) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_BACK_RIGHT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_BACK_LEFT; } else @@ -1168,7 +1168,7 @@ namespace TEN::Entities::Vehicles if (jeep->Gear < 1) jeep->Gear++; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_BACK_LEFT; else laraItem->Animation.TargetState = JS_BACK; @@ -1209,7 +1209,7 @@ namespace TEN::Entities::Vehicles if (jeep->Gear < 1) jeep->Gear++; } - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_BACK_RIGHT; else laraItem->Animation.TargetState = JS_BACK; @@ -1255,11 +1255,11 @@ namespace TEN::Entities::Vehicles if (jeep->Gear < 1) jeep->Gear++; } - else if (!(TrInput & VEHICLE_IN_ACCELERATE) || TrInput & VEHICLE_IN_BRAKE) + else if (!IsHeld(In::Accelerate) || IsHeld(In::Brake)) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Right)) laraItem->Animation.TargetState = JS_BACK_RIGHT; - else if (TrInput & VEHICLE_IN_LEFT) + else if (IsHeld(In::Left)) laraItem->Animation.TargetState = JS_BACK_LEFT; } else @@ -1395,7 +1395,7 @@ namespace TEN::Entities::Vehicles if (roomNumber != jeepItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, roomNumber); - ItemNewRoom(lara->ItemNumber, roomNumber); + ItemNewRoom(laraItem->Index, roomNumber); } laraItem->Pose = jeepItem->Pose; @@ -1405,7 +1405,7 @@ namespace TEN::Entities::Vehicles SyncVehicleAnimation(*jeepItem, *laraItem); Camera.targetElevation = -ANGLE(30.0f); - Camera.targetDistance = SECTOR(2); + Camera.targetDistance = BLOCK(2); if (jeep->Gear == 1) jeep->CameraElevation += ((32578 - jeep->CameraElevation) / 8); diff --git a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp index 5cc4300f0..7c14bcf99 100644 --- a/TombEngine/Objects/TR4/Vehicles/motorbike.cpp +++ b/TombEngine/Objects/TR4/Vehicles/motorbike.cpp @@ -216,10 +216,10 @@ namespace TEN::Entities::Vehicles static int DoMotorbikeShift(ItemInfo* motorbikeItem, Vector3i* pos, Vector3i* old) { - int x = pos->x / SECTOR(1); - int z = pos->z / SECTOR(1); - int oldX = old->x / SECTOR(1); - int oldZ = old->z / SECTOR(1); + int x = pos->x / BLOCK(1); + int z = pos->z / BLOCK(1); + int oldX = old->x / BLOCK(1); + int oldZ = old->z / BLOCK(1); int shiftX = pos->x & WALL_MASK; int shiftZ = pos->z & WALL_MASK; @@ -237,7 +237,7 @@ namespace TEN::Entities::Vehicles } else { - motorbikeItem->Pose.Position.z += SECTOR(1) - shiftZ; + motorbikeItem->Pose.Position.z += BLOCK(1) - shiftZ; return (motorbikeItem->Pose.Position.x - pos->x); } } @@ -250,7 +250,7 @@ namespace TEN::Entities::Vehicles } else { - motorbikeItem->Pose.Position.x += SECTOR(1) - shiftX; + motorbikeItem->Pose.Position.x += BLOCK(1) - shiftX; return (pos->z - motorbikeItem->Pose.Position.z); } } @@ -265,7 +265,7 @@ namespace TEN::Entities::Vehicles if (pos->z > old->z) z = -shiftZ - 1; else - z = SECTOR(1) - shiftZ; + z = BLOCK(1) - shiftZ; } floorHeight = GetCollision(pos->x, pos->y, old->z, motorbikeItem->RoomNumber).Position.Floor; @@ -274,7 +274,7 @@ namespace TEN::Entities::Vehicles if (pos->x > old->x) x = -shiftX - 1; else - x = SECTOR(1) - shiftX; + x = BLOCK(1) - shiftX; } if (x && z) @@ -577,9 +577,9 @@ namespace TEN::Entities::Vehicles motorbikeItem->Pose.Orientation.y += motorbike->TurnRate + motorbike->ExtraRotation; rotation = motorbikeItem->Pose.Orientation.y - motorbike->MomentumAngle; - momentum = MOTORBIKE_MOMENTUM_TURN_ANGLE_MIN - ((2 * motorbike->Velocity) / SECTOR(1)); + momentum = MOTORBIKE_MOMENTUM_TURN_ANGLE_MIN - ((2 * motorbike->Velocity) / BLOCK(1)); - if (!(TrInput & VEHICLE_IN_ACCELERATE) && motorbike->Velocity > 0) + if (!IsHeld(In::Accelerate) && motorbike->Velocity > 0) momentum += momentum / 2; if (rotation < -MOTORBIKE_MOMENTUM_TURN_ANGLE_MAX) @@ -787,14 +787,14 @@ namespace TEN::Entities::Vehicles else { bool dismount = false; - if ((TrInput & VEHICLE_IN_RIGHT) && (TrInput & VEHICLE_IN_DISMOUNT)) + if (IsHeld(In::Right) && IsHeld(In::Brake)) dismount = true; if (!dismount || motorbike->Velocity || motorbike->DisableDismount) { - if (TrInput & VEHICLE_IN_ACCELERATE && !(TrInput & VEHICLE_IN_BRAKE)) + if (IsHeld(In::Accelerate) && !IsHeld(In::Brake)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_FRONT; - else if (TrInput & VEHICLE_IN_REVERSE) + else if (IsHeld(In::Reverse)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_BACK; } else if (dismount && TestMotorbikeDismount(motorbikeItem, laraItem)) @@ -815,18 +815,18 @@ namespace TEN::Entities::Vehicles } else if ((motorbike->Velocity / VEHICLE_VELOCITY_SCALE) != 0) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_LEFT; - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_RIGHT; - else if (TrInput & VEHICLE_IN_BRAKE) + else if (IsHeld(In::Brake)) { if (motorbike->Velocity <= 0x5554) // 85.3f * VEHICLE_VELOCITY_SCALE laraItem->Animation.TargetState = MOTORBIKE_STATE_NONE_3; else laraItem->Animation.TargetState = MOTORBIKE_STATE_STOP; } - else if (TrInput & VEHICLE_IN_REVERSE && motorbike->Velocity <= MOTORBIKE_BACKING_VEL) + else if (IsHeld(In::Reverse) && motorbike->Velocity <= MOTORBIKE_BACKING_VEL) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_BACK; else if (motorbike->Velocity == 0) laraItem->Animation.TargetState = MOTORBIKE_STATE_IDLE; @@ -839,7 +839,7 @@ namespace TEN::Entities::Vehicles case MOTORBIKE_STATE_MOVING_LEFT: if ((motorbike->Velocity / VEHICLE_VELOCITY_SCALE) != 0) { - if (TrInput & VEHICLE_IN_RIGHT || !(TrInput & VEHICLE_IN_LEFT)) + if (IsHeld(In::Right) || !IsHeld(In::Left)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_FRONT; } else @@ -850,7 +850,7 @@ namespace TEN::Entities::Vehicles break; case MOTORBIKE_STATE_MOVING_BACK: - if (TrInput & VEHICLE_IN_REVERSE) + if (IsHeld(In::Reverse)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_BACK_LOOP; else laraItem->Animation.TargetState = MOTORBIKE_STATE_IDLE; @@ -860,7 +860,7 @@ namespace TEN::Entities::Vehicles case MOTORBIKE_STATE_MOVING_RIGHT: if ((motorbike->Velocity / VEHICLE_VELOCITY_SCALE) != 0) { - if (TrInput & VEHICLE_IN_LEFT || !(TrInput & VEHICLE_IN_RIGHT)) + if (IsHeld(In::Left) || !(IsHeld(In::Right))) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_FRONT; } else @@ -876,10 +876,10 @@ namespace TEN::Entities::Vehicles case MOTORBIKE_STATE_ACCELERATE: if ((motorbike->Velocity / VEHICLE_VELOCITY_SCALE) != 0) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_LEFT; - if (TrInput & VEHICLE_IN_RIGHT) + if (IsHeld(In::Right)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_RIGHT; } else @@ -910,7 +910,7 @@ namespace TEN::Entities::Vehicles case MOTORBIKE_STATE_HITBACK: case MOTORBIKE_STATE_HITRIGHT: case MOTORBIKE_STATE_HITLEFT: - if (TrInput & (VEHICLE_IN_ACCELERATE | VEHICLE_IN_BRAKE)) + if (IsHeld(In::Accelerate) || IsHeld(In::Brake)) laraItem->Animation.TargetState = MOTORBIKE_STATE_MOVING_FRONT; break; @@ -968,8 +968,7 @@ namespace TEN::Entities::Vehicles else motorbike->Revs = 0; - if ((TrInput & VEHICLE_IN_SPEED) && - (TrInput & VEHICLE_IN_ACCELERATE) && + if (IsHeld(In::Speed) && IsHeld(In::Accelerate) && (motorbike->Flags & MOTORBIKE_FLAG_NITRO)) { if (lara->Status.Stamina > 10) @@ -995,7 +994,7 @@ namespace TEN::Entities::Vehicles // Moving forward. if (motorbike->Velocity > 0) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) { if (motorbike->Velocity > MOTORBIKE_ACCEL_1) motorbike->TurnRate -= MOTORBIKE_FORWARD_TURN_ANGLE; @@ -1005,7 +1004,7 @@ namespace TEN::Entities::Vehicles if (motorbike->TurnRate < -MOTORBIKE_TURN_ANGLE_MAX) motorbike->TurnRate = -MOTORBIKE_TURN_ANGLE_MAX; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { if (motorbike->Velocity > MOTORBIKE_ACCEL_1) motorbike->TurnRate += MOTORBIKE_FORWARD_TURN_ANGLE; @@ -1019,13 +1018,13 @@ namespace TEN::Entities::Vehicles // Moving back. else if (motorbike->Velocity < 0) { - if (TrInput & VEHICLE_IN_LEFT) + if (IsHeld(In::Left)) { motorbike->TurnRate += MOTORBIKE_BACK_TURN_ANGLE; if (motorbike->TurnRate > MOTORBIKE_TURN_ANGLE_MAX) motorbike->TurnRate = MOTORBIKE_TURN_ANGLE_MAX; } - else if (TrInput & VEHICLE_IN_RIGHT) + else if (IsHeld(In::Right)) { motorbike->TurnRate -= MOTORBIKE_BACK_TURN_ANGLE; if (motorbike->TurnRate < -MOTORBIKE_TURN_ANGLE_MAX) @@ -1033,7 +1032,7 @@ namespace TEN::Entities::Vehicles } } - if (TrInput & VEHICLE_IN_BRAKE) + if (IsHeld(In::Brake)) { auto pos = GetJointPosition(motorbikeItem, 0, Vector3i(0, -144, -1024)); TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 64, 0, 0); @@ -1043,7 +1042,7 @@ namespace TEN::Entities::Vehicles else motorbikeItem->MeshBits.Clear(MotorbikeBrakeLightJoints); - if (TrInput & VEHICLE_IN_BRAKE) + if (IsHeld(In::Brake)) { if (motorbike->Velocity < 0) { @@ -1058,7 +1057,7 @@ namespace TEN::Entities::Vehicles motorbike->Velocity = 0; } } - else if (TrInput & VEHICLE_IN_ACCELERATE) + else if (IsHeld(In::Accelerate)) { if (motorbike->Velocity < MOTORBIKE_ACCEL_MAX) { @@ -1269,7 +1268,7 @@ namespace TEN::Entities::Vehicles if (probe.RoomNumber != motorbikeItem->RoomNumber) { ItemNewRoom(lara->Context.Vehicle, probe.RoomNumber); - ItemNewRoom(lara->ItemNumber, probe.RoomNumber); + ItemNewRoom(laraItem->Index, probe.RoomNumber); } laraItem->Pose = motorbikeItem->Pose; diff --git a/TombEngine/Objects/TR4/tr4_objects.cpp b/TombEngine/Objects/TR4/tr4_objects.cpp index 6c9f3a260..8135afefd 100644 --- a/TombEngine/Objects/TR4/tr4_objects.cpp +++ b/TombEngine/Objects/TR4/tr4_objects.cpp @@ -55,6 +55,8 @@ // Switches // Traps +#include "Objects/TR4/Trap/SpikyCeiling.h" +#include "Objects/TR4/Trap/SpikyWall.h" #include "Objects/TR4/Trap/tr4_birdblade.h" #include "Objects/TR4/Trap/tr4_blade.h" #include "Objects/TR4/Trap/tr4_catwalkblade.h" @@ -69,8 +71,6 @@ #include "Objects/TR4/Trap/tr4_sethblade.h" #include "Objects/TR4/Trap/tr4_slicerdicer.h" #include "Objects/TR4/Trap/tr4_spikeball.h" -#include "Objects/TR4/Trap/tr4_spikywall.h" -#include "Objects/TR4/Trap/tr4_spikyceiling.h" #include "Objects/TR4/Trap/tr4_stargate.h" #include "Objects/TR4/Trap/tr4_cog.h" #include "Objects/TR4/Trap/tr4_teethspike.h" @@ -900,15 +900,16 @@ namespace TEN::Entities { obj->Initialize = InitializeSpikyWall; obj->control = ControlSpikyWall; - obj->collision = ObjectCollision; + obj->collision = CollideSpikyWall; obj->SetupHitEffect(true); } obj = &Objects[ID_SPIKY_CEILING]; if (obj->loaded) { + obj->Initialize = InitializeSpikyCeiling; obj->control = ControlSpikyCeiling; - obj->collision = TrapCollision; + obj->collision = CollideSpikyCeiling; obj->SetupHitEffect(true); } diff --git a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp index 88f2a365a..bd7cd6466 100644 --- a/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp +++ b/TombEngine/Objects/TR5/Emitter/tr5_rats_emitter.cpp @@ -171,7 +171,7 @@ void UpdateRats() if (rat->Flags & 1) { // if rat is very near - if (abs(dz) + abs(dx) <= SECTOR(1)) + if (abs(dz) + abs(dx) <= BLOCK(1)) { if (rat->Velocity & 1) rat->Pose.Orientation.y += ANGLE(2.8f); diff --git a/TombEngine/Objects/TR5/Emitter/tr5_smoke_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_smoke_emitter.cpp index 4ac58ae79..45a08a47a 100644 --- a/TombEngine/Objects/TR5/Emitter/tr5_smoke_emitter.cpp +++ b/TombEngine/Objects/TR5/Emitter/tr5_smoke_emitter.cpp @@ -134,7 +134,7 @@ void SmokeEmitterControl(short itemNumber) int dx = Camera.pos.x - item->Pose.Position.x; int dz = Camera.pos.z - item->Pose.Position.z; - if (dx < -SECTOR(16) || dx > SECTOR(16) || dz < -SECTOR(16) || dz > SECTOR(16)) + if (dx < -BLOCK(16) || dx > BLOCK(16) || dz < -BLOCK(16) || dz > BLOCK(16)) return; auto* sptr = GetFreeParticle(); @@ -158,9 +158,9 @@ void SmokeEmitterControl(short itemNumber) if (item->ItemFlags[2] == 4096) size = (GetRandomControl() & 0x7FF) + 2048; - sptr->xVel = (short)((size * phd_sin(item->Pose.Orientation.y - 32768)) / SECTOR(1)); + sptr->xVel = (short)((size * phd_sin(item->Pose.Orientation.y - 32768)) / BLOCK(1)); sptr->yVel = -16 - (GetRandomControl() & 0xF); - sptr->zVel = (short)((size * phd_cos(item->Pose.Orientation.y - 32768)) / SECTOR(1)); + sptr->zVel = (short)((size * phd_cos(item->Pose.Orientation.y - 32768)) / BLOCK(1)); sptr->friction = 4; sptr->flags = SP_SCALE | SP_DEF | SP_ROTATE | SP_EXPDEF; @@ -196,7 +196,7 @@ void SmokeEmitterControl(short itemNumber) int dx = Camera.pos.x - item->Pose.Position.x; int dz = Camera.pos.z - item->Pose.Position.z; - if (dx < -SECTOR(16) || dx > SECTOR(16) || dz < -SECTOR(16) || dz > SECTOR(16)) + if (dx < -BLOCK(16) || dx > BLOCK(16) || dz < -BLOCK(16) || dz > BLOCK(16)) return; auto* sptr = GetFreeParticle(); diff --git a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp index 76bf7e4e7..b4eb28d9c 100644 --- a/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp +++ b/TombEngine/Objects/TR5/Emitter/tr5_spider_emitter.cpp @@ -186,7 +186,7 @@ void UpdateSpiders() FloorInfo* floor = GetFloor(spider->Pose.Position.x, spider->Pose.Position.y, spider->Pose.Position.z,&spider->RoomNumber); int height = GetFloorHeight(floor, spider->Pose.Position.x, spider->Pose.Position.y, spider->Pose.Position.z); - if (height >= spider->Pose.Position.y - CLICK(5) || height == -SECTOR(31.75f)) + if (height >= spider->Pose.Position.y - CLICK(5) || height == -BLOCK(31.75f)) { if (height >= spider->Pose.Position.y - 64) { diff --git a/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp b/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp index 09fc728fd..131996c15 100644 --- a/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp +++ b/TombEngine/Objects/TR5/Entity/HeavyGuard.cpp @@ -171,7 +171,7 @@ namespace TEN::Entities::Creatures::TR5 auto hitPos = Vector3i::Zero; MESH_INFO* hitJoint = nullptr; - if (ObjectOnLOS2(&origin2, &target2, &hitPos, &hitJoint, ID_LARA) == GetLaraInfo(creature.Enemy)->ItemNumber) + if (ObjectOnLOS2(&origin2, &target2, &hitPos, &hitJoint, ID_LARA) == creature.Enemy->Index) { if (LaraItem->HitPoints <= HEAVY_GUARD_RAYGUN_PLAYER_BURN_HEALTH) { diff --git a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp index 2864b54d4..68d435eb2 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp @@ -19,8 +19,8 @@ namespace TEN::Entities::Creatures::TR5 { constexpr auto BROWN_BEAST_ATTACK_DAMAGE = 150; - const auto BrownBeastBite1 = CreatureBiteInfo(Vector3i::Zero, 16); - const auto BrownBeastBite2 = CreatureBiteInfo(Vector3i::Zero, 22); + const auto BrownBeastBite1 = CreatureBiteInfo(Vector3::Zero, 16); + const auto BrownBeastBite2 = CreatureBiteInfo(Vector3::Zero, 22); const auto BrownBeastAttackJoints1 = std::vector{ 14, 15, 16, 17 }; const auto BrownBeastAttackJoints2 = std::vector{ 20, 21, 22, 23 }; @@ -96,7 +96,7 @@ namespace TEN::Entities::Creatures::TR5 if (creature->Mood == MoodType::Attack) { - if (distance <= pow(SECTOR(1), 2)) + if (distance <= pow(BLOCK(1), 2)) { if (Random::TestProbability(1 / 2.0f)) item->Animation.TargetState = 4; @@ -115,7 +115,7 @@ namespace TEN::Entities::Creatures::TR5 case 2: case 3: - if (distance < pow(SECTOR(1), 2) || creature->Mood != MoodType::Attack) + if (distance < pow(BLOCK(1), 2) || creature->Mood != MoodType::Attack) item->Animation.TargetState = 1; SoundEffect(SFX_TR5_IMP_BARREL_ROLL, &item->Pose); diff --git a/TombEngine/Objects/TR5/Entity/tr5_chef.cpp b/TombEngine/Objects/TR5/Entity/tr5_chef.cpp index c72929358..88c37ec3f 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_chef.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_chef.cpp @@ -15,7 +15,7 @@ namespace TEN::Entities::Creatures::TR5 { - const auto ChefBite = CreatureBiteInfo(Vector3i(0, 200, 0), 13); + const auto ChefBite = CreatureBiteInfo(Vector3(0, 200, 0), 13); // TODO enum ChefState @@ -115,8 +115,8 @@ namespace TEN::Entities::Creatures::TR5 switch (item->Animation.ActiveState) { case CHEF_STATE_COOKING: - if (abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < SECTOR(1) && - ai.distance < pow(SECTOR(1.5f), 2) && + if (abs(LaraItem->Pose.Position.y - item->Pose.Position.y) < BLOCK(1) && + ai.distance < pow(BLOCK(1.5f), 2) && (item->TouchBits.TestAny() || item->HitStatus || LaraItem->Animation.Velocity.z > 15 || diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp index 179a63de3..e489eca4e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp @@ -36,7 +36,7 @@ namespace TEN::Entities::Creatures::TR5 constexpr auto CYBORG_DISTURBANCE_VELOCITY = 20.0f; - const auto CyborgGunBite = CreatureBiteInfo(Vector3i(-32, 240, 50), 18); + const auto CyborgGunBite = CreatureBiteInfo(Vector3(-32, 240, 50), 18); const auto CyborgJoints = std::vector{ 15, 14, 13, 6, 5, 12, 7, 4, 10, 11, 19 }; enum CyborgState diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp index 7b225dfcd..fe1813024 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR5 { - const auto DobermanBite = CreatureBiteInfo(Vector3i(0, 30, 141), 20); + const auto DobermanBite = CreatureBiteInfo(Vector3(0, 30, 141), 20); enum DobermanState { diff --git a/TombEngine/Objects/TR5/Entity/tr5_dog.cpp b/TombEngine/Objects/TR5/Entity/tr5_dog.cpp index 584eafff5..4e648979c 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_dog.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_dog.cpp @@ -14,7 +14,7 @@ namespace TEN::Entities::Creatures::TR5 { - const auto DogBite = CreatureBiteInfo(Vector3i(0, 0, 100), 3); + const auto DogBite = CreatureBiteInfo(Vector3(0, 0, 100), 3); static BYTE DogAnims[] = { 20, 21, 22, 20 }; void InitializeTr5Dog(short itemNumber) @@ -94,7 +94,7 @@ namespace TEN::Entities::Creatures::TR5 angle = CreatureTurn(item, creature->MaxTurn); joint0 = 4 * angle; - if (creature->HurtByLara || distance < pow(SECTOR(3), 2) && !(item->AIBits & MODIFY)) + if (creature->HurtByLara || distance < pow(BLOCK(3), 2) && !(item->AIBits & MODIFY)) { AlertAllGuards(itemNumber); item->AIBits &= ~MODIFY; @@ -249,9 +249,9 @@ namespace TEN::Entities::Creatures::TR5 } else if (creature->Mood != MoodType::Bored) { - if (AI.bite && AI.distance < pow(SECTOR(1), 2)) + if (AI.bite && AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = 6; - else if (AI.distance < pow(SECTOR(1.5f), 2)) + else if (AI.distance < pow(BLOCK(1.5f), 2)) { item->Animation.RequiredState = 5; item->Animation.TargetState = 9; @@ -274,7 +274,7 @@ namespace TEN::Entities::Creatures::TR5 item->Animation.TargetState = 12; item->Animation.RequiredState = 5; } - else if (AI.distance > pow(SECTOR(1.5f), 2) || item->HitStatus) + else if (AI.distance > pow(BLOCK(1.5f), 2) || item->HitStatus) item->Animation.TargetState = 3; } else diff --git a/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp b/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp index d6534ea91..f5cd442eb 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp @@ -13,7 +13,7 @@ namespace TEN::Entities::Creatures::TR5 { - const auto InvisibleGhostBite = CreatureBiteInfo(Vector3i::Zero, 17); + const auto InvisibleGhostBite = CreatureBiteInfo(Vector3::Zero, 17); void InitializeInvisibleGhost(short itemNumber) { @@ -92,7 +92,7 @@ namespace TEN::Entities::Creatures::TR5 CreatureJoint(item, 1, joint1); CreatureJoint(item, 2, joint2); - if (AI.distance >= pow(SECTOR(1.5f), 2)) + if (AI.distance >= pow(BLOCK(1.5f), 2)) { item->AfterDeath = 125; item->ItemFlags[0] = 0; diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index 3ee994104..8b56bacc2 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -23,7 +23,7 @@ namespace TEN::Entities::Creatures::TR5 // TODO: Ranges. - const auto GladiatorBite = CreatureBiteInfo(Vector3i::Zero, 16); + const auto GladiatorBite = CreatureBiteInfo(Vector3::Zero, 16); const auto GladiatorAttackJoints = std::vector{ 13, 14 }; enum GladiatorState @@ -152,7 +152,7 @@ namespace TEN::Entities::Creatures::TR5 if (item->AIBits & GUARD || Random::TestProbability(1.0f / 32) && - (AI.distance > pow(SECTOR(1), 2) || creature->Mood != MoodType::Attack)) + (AI.distance > pow(BLOCK(1), 2) || creature->Mood != MoodType::Attack)) { joint2 = AIGuard(creature); break; @@ -173,7 +173,7 @@ namespace TEN::Entities::Creatures::TR5 else { if (creature->Mood == MoodType::Bored || - (item->AIBits & FOLLOW && (creature->ReachedGoal || distance > pow(SECTOR(2), 2)))) + (item->AIBits & FOLLOW && (creature->ReachedGoal || distance > pow(BLOCK(2), 2)))) { if (item->Animation.RequiredState != NO_STATE) item->Animation.TargetState = item->Animation.RequiredState; @@ -184,7 +184,7 @@ namespace TEN::Entities::Creatures::TR5 } if (Lara.TargetEntity == item && - unknown && distance < pow(SECTOR(1.5f), 2) && + unknown && distance < pow(BLOCK(1.5f), 2) && Random::TestProbability(1 / 2.0f) && (Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun || Random::TestProbability(0.06f)) && item->MeshBits == -1) @@ -223,15 +223,15 @@ namespace TEN::Entities::Creatures::TR5 item->Animation.TargetState = GLADIATOR_STATE_RUN_FORWARD; else if (creature->Mood != MoodType::Bored) { - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; } - if (AI.bite && AI.distance < pow(SECTOR(2), 2)) + if (AI.bite && AI.distance < pow(BLOCK(2), 2)) item->Animation.TargetState = GLADIATOR_STATE_WALK_SWORD_ATTACK; - else if (!AI.ahead || AI.distance > pow(SECTOR(1.5f), 2)) + else if (!AI.ahead || AI.distance > pow(BLOCK(1.5f), 2)) item->Animation.TargetState = GLADIATOR_STATE_RUN_FORWARD; } else if (Random::TestProbability(1 / 64.0f)) @@ -269,7 +269,7 @@ namespace TEN::Entities::Creatures::TR5 } if (item->AIBits & FOLLOW && - (creature->ReachedGoal || distance > pow(SECTOR(2), 2))) + (creature->ReachedGoal || distance > pow(BLOCK(2), 2))) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -281,7 +281,7 @@ namespace TEN::Entities::Creatures::TR5 break; } - if (AI.distance < pow(SECTOR(1.5f), 2)) + if (AI.distance < pow(BLOCK(1.5f), 2)) { if (AI.bite) item->Animation.TargetState = GLADIATOR_STATE_RUN_SWORD_ATTACK; diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp index 0494218e9..445cfef0d 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp @@ -32,11 +32,11 @@ namespace TEN::Entities::Creatures::TR5 constexpr auto GUARD_NO_WEAPON_ON_HAND_SWAPFLAG = 0x2000; constexpr auto GUARD_HEAD_MESH = 14; - const auto SwatGunBite = CreatureBiteInfo(Vector3i(16, 240, 90), 13); - const auto MafiaGunBite = CreatureBiteInfo(Vector3i(16, 270, 90), 13); - const auto SniperGunBite = CreatureBiteInfo(Vector3i(0, 480, 110), 13); - const auto ArmedMafia2GunLeftBite = CreatureBiteInfo(Vector3i(-16, 200, 60), 10); - const auto ArmedMafia2GunRightBite = CreatureBiteInfo(Vector3i(16, 200, 60), 13); + const auto SwatGunBite = CreatureBiteInfo(Vector3(16, 240, 90), 13); + const auto MafiaGunBite = CreatureBiteInfo(Vector3(16, 270, 90), 13); + const auto SniperGunBite = CreatureBiteInfo(Vector3(0, 480, 110), 13); + const auto ArmedMafia2GunLeftBite = CreatureBiteInfo(Vector3(-16, 200, 60), 10); + const auto ArmedMafia2GunRightBite = CreatureBiteInfo(Vector3(16, 200, 60), 13); // TODO: Revise names of enum elements. @@ -292,9 +292,9 @@ namespace TEN::Entities::Creatures::TR5 InitializeCreature(itemNumber); SetAnimation(item, 0); - item->Pose.Position.x += SECTOR(1) * phd_sin(item->Pose.Orientation.y + ANGLE(90.0f)); + item->Pose.Position.x += BLOCK(1) * phd_sin(item->Pose.Orientation.y + ANGLE(90.0f)); item->Pose.Position.y += CLICK(2); - item->Pose.Position.z += SECTOR(1) * phd_cos(item->Pose.Orientation.y + ANGLE(90.0f)); + item->Pose.Position.z += BLOCK(1) * phd_cos(item->Pose.Orientation.y + ANGLE(90.0f)); } void InitializeGuardLaser(short itemNumber) @@ -420,7 +420,7 @@ namespace TEN::Entities::Creatures::TR5 { if (!(item->AIBits & FOLLOW) && item->ObjectNumber != ID_SCIENTIST && - abs(item->Pose.Position.y - LaraItem->Pose.Position.y) < SECTOR(1.25f)) + abs(item->Pose.Position.y - LaraItem->Pose.Position.y) < BLOCK(1.25f)) { creature->Enemy = LaraItem; // TODO: deal with LaraItem global ! AlertAllGuards(itemNumber); @@ -661,7 +661,7 @@ namespace TEN::Entities::Creatures::TR5 creature->LOT.IsJumping = true; } - else if (AI.distance >= SQUARE(SECTOR(1))) + else if (AI.distance >= SQUARE(BLOCK(1))) { if (!los || item->AIBits) { @@ -719,7 +719,7 @@ namespace TEN::Entities::Creatures::TR5 creature->MaxTurn = 0; headY = laraAI.angle; - if (item->Pose.Position.y <= (item->Floor - SECTOR(2)) || item->TriggerFlags != (int)GuardOcb::RopeDownFast) + if (item->Pose.Position.y <= (item->Floor - BLOCK(2)) || item->TriggerFlags != (int)GuardOcb::RopeDownFast) { if (item->Pose.Position.y >= (item->Floor - CLICK(2))) item->Animation.TargetState = GUARD_STATE_AIM; @@ -1213,7 +1213,7 @@ namespace TEN::Entities::Creatures::TR5 creature->Enemy = LaraItem; angle = CreatureTurn(item, creature->MaxTurn); - if ((laraAI.distance < pow(SECTOR(2), 2) && LaraItem->Animation.Velocity.z > 20) || + if ((laraAI.distance < pow(BLOCK(2), 2) && LaraItem->Animation.Velocity.z > 20) || item->HitStatus || TargetVisible(item, &laraAI)) { @@ -1256,7 +1256,7 @@ namespace TEN::Entities::Creatures::TR5 } if (Targetable(item, &ai)) { - if (ai.distance < pow(SECTOR(1), 2) || ai.zoneNumber != ai.enemyZone) + if (ai.distance < pow(BLOCK(1), 2) || ai.zoneNumber != ai.enemyZone) item->Animation.TargetState = MAFIA2_STATE_AIM; else if (!(item->AIBits & MODIFY)) item->Animation.TargetState = MAFIA2_STATE_WALK; @@ -1285,7 +1285,7 @@ namespace TEN::Entities::Creatures::TR5 if (creature->Mood != MoodType::Bored) { - if (ai.distance >= pow(SECTOR(3), 2)) + if (ai.distance >= pow(BLOCK(3), 2)) item->Animation.TargetState = MAFIA2_STATE_WALK; } else @@ -1386,7 +1386,7 @@ namespace TEN::Entities::Creatures::TR5 creature->LOT.IsJumping = false; if (Targetable(item, &ai) && - (ai.distance < pow(SECTOR(1), 2) || ai.zoneNumber != ai.enemyZone)) + (ai.distance < pow(BLOCK(1), 2) || ai.zoneNumber != ai.enemyZone)) { item->Animation.TargetState = MAFIA2_STATE_AIM; } @@ -1408,9 +1408,9 @@ namespace TEN::Entities::Creatures::TR5 break; } - if (ai.distance >= pow(SECTOR(1), 2)) + if (ai.distance >= pow(BLOCK(1), 2)) { - if (ai.distance > pow(SECTOR(3), 2)) + if (ai.distance > pow(BLOCK(3), 2)) item->Animation.TargetState = MAFIA2_STATE_RUN; } else @@ -1424,7 +1424,7 @@ namespace TEN::Entities::Creatures::TR5 creature->LOT.IsJumping = false; if (Targetable(item, &ai) && - (ai.distance < pow(SECTOR(1), 2) || ai.zoneNumber != ai.enemyZone)) + (ai.distance < pow(BLOCK(1), 2) || ai.zoneNumber != ai.enemyZone)) { item->Animation.TargetState = MAFIA2_STATE_AIM; } @@ -1442,7 +1442,7 @@ namespace TEN::Entities::Creatures::TR5 creature->LOT.IsJumping = true; } - else if (ai.distance < pow(SECTOR(3), 2)) + else if (ai.distance < pow(BLOCK(3), 2)) item->Animation.TargetState = MAFIA2_STATE_WALK; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp index 66c329873..5ec01e989 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp @@ -19,7 +19,7 @@ using namespace TEN::Math; namespace TEN::Entities::Creatures::TR5 { - const auto HydraBite = CreatureBiteInfo(Vector3i::Zero, 11); + const auto HydraBite = CreatureBiteInfo(Vector3::Zero, 11); enum HydraState { @@ -232,7 +232,7 @@ namespace TEN::Entities::Creatures::TR5 if (AI.distance >= pow(CLICK(7), 2) && Random::TestProbability(0.97f)) { - if (AI.distance >= pow(SECTOR(2), 2) && Random::TestProbability(0.97f)) + if (AI.distance >= pow(BLOCK(2), 2) && Random::TestProbability(0.97f)) { if (Random::TestProbability(0.06f)) item->Animation.TargetState = HYDRA_STATE_AIM; @@ -263,7 +263,7 @@ namespace TEN::Entities::Creatures::TR5 if (item->HitStatus && AI.distance < pow(CLICK(7), 2)) { distance = sqrt(AI.distance); - damage = 5 - distance / SECTOR(1); + damage = 5 - distance / BLOCK(1); if (Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun) damage *= 3; @@ -294,7 +294,7 @@ namespace TEN::Entities::Creatures::TR5 damage *= 3; if ((GetRandomControl() & 0xF) < damage && - AI.distance < SQUARE(SECTOR(10)) && damage > 0) + AI.distance < SQUARE(BLOCK(10)) && damage > 0) { item->Animation.TargetState = 4; DoDamage(item, damage); diff --git a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp index a875ef298..87d5089f2 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp @@ -33,8 +33,8 @@ namespace TEN::Entities::Creatures::TR5 constexpr auto IMP_HEAD_MESH_SWAP_INTERVAL = 16; - const auto ImpLeftHandBite = CreatureBiteInfo(Vector3i(0, 100, 0), 7); - const auto ImpRightHandBite = CreatureBiteInfo(Vector3i(0, 100, 0), 9); + const auto ImpLeftHandBite = CreatureBiteInfo(Vector3(0, 100, 0), 7); + const auto ImpRightHandBite = CreatureBiteInfo(Vector3(0, 100, 0), 9); const auto ImpHeadMeshSwapJoints = std::vector{ 10 }; enum ImpState diff --git a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp index 706335287..fd9ad5756 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp @@ -18,7 +18,7 @@ namespace TEN::Entities::Creatures::TR5 { constexpr auto LAGOON_WITCH_ATTACK_DAMAGE = 100; - const auto LagoonWitchBite = CreatureBiteInfo(Vector3i::Zero, 7); + const auto LagoonWitchBite = CreatureBiteInfo(Vector3::Zero, 7); const auto LagoonWitchAttackJoints = std::vector{ 6, 7, 8, 9, 14, 15, 16, 17 }; enum LagoonWitchState @@ -106,7 +106,7 @@ namespace TEN::Entities::Creatures::TR5 case WITCH_STATE_SWIM: creature->MaxTurn = ANGLE(4.0f); - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) item->Animation.TargetState = WITCH_STATE_IDLE; break; @@ -117,7 +117,7 @@ namespace TEN::Entities::Creatures::TR5 if (AI.distance < pow(CLICK(3), 2)) item->Animation.TargetState = WITCH_STATE_ATTACK; - else if (AI.distance > pow(SECTOR(1), 2)) + else if (AI.distance > pow(BLOCK(1), 2)) item->Animation.TargetState = WITCH_STATE_SWIM; else item->Animation.TargetState = WITCH_STATE_IDLE; diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index 6ccd3d626..535fe9ee0 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -31,9 +31,9 @@ namespace TEN::Entities::Creatures::TR5 #define TR5_LARSON_MIN_HP 40 - const auto LarsonGun = CreatureBiteInfo(Vector3i(-55, 200, 5), 14); - const auto PierreGunLeft = CreatureBiteInfo(Vector3i(45, 200, 0), 11); - const auto PierreGunRight = CreatureBiteInfo(Vector3i(-40, 200, 0), 14); + const auto LarsonGun = CreatureBiteInfo(Vector3(-55, 200, 5), 14); + const auto PierreGunLeft = CreatureBiteInfo(Vector3(45, 200, 0), 11); + const auto PierreGunRight = CreatureBiteInfo(Vector3(-40, 200, 0), 14); void InitializeLarson(short itemNumber) { @@ -133,7 +133,7 @@ namespace TEN::Entities::Creatures::TR5 GetCreatureMood(item, &AI, true); CreatureMood(item, &AI, true); - if (AI.distance < SQUARE(SECTOR(2)) && + if (AI.distance < SQUARE(BLOCK(2)) && LaraItem->Animation.Velocity.z > 20.0f || item->HitStatus || TargetVisible(item, &AI) != 0) @@ -215,7 +215,7 @@ namespace TEN::Entities::Creatures::TR5 item->Animation.TargetState = STATE_TR5_LARSON_STOP; item->Animation.RequiredState = STATE_TR5_LARSON_AIM; } - else if (!AI.ahead || AI.distance > SQUARE(SECTOR(3))) + else if (!AI.ahead || AI.distance > SQUARE(BLOCK(3))) { item->Animation.TargetState = STATE_TR5_LARSON_STOP; item->Animation.RequiredState = STATE_TR5_LARSON_RUN; @@ -243,7 +243,7 @@ namespace TEN::Entities::Creatures::TR5 } else if (AI.ahead) { - if (AI.distance <= SQUARE(SECTOR(3))) + if (AI.distance <= SQUARE(BLOCK(3))) { item->Animation.TargetState = STATE_TR5_LARSON_STOP; item->Animation.RequiredState = STATE_TR5_LARSON_WALK; @@ -363,9 +363,9 @@ namespace TEN::Entities::Creatures::TR5 auto* room = &g_Level.Rooms[roomNumber]; - int x = room->x + (creature->Tosspad / 256 & 0xFF) * SECTOR(1) + 512; + int x = room->x + (creature->Tosspad / 256 & 0xFF) * BLOCK(1) + 512; int y = room->minfloor + floorHeight; - int z = room->z + (creature->Tosspad & 0xFF) * SECTOR(1) + 512; + int z = room->z + (creature->Tosspad & 0xFF) * BLOCK(1) + 512; TestTriggers(x, y, z, roomNumber, true); diff --git a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp index f4ee1adc4..6bbbdf29c 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp @@ -406,7 +406,7 @@ namespace TEN::Entities::Creatures::TR5 start.RoomNumber = item->RoomNumber; auto end = GameVector(guardian->fireArcs[i]->pos4.x, guardian->fireArcs[i]->pos4.y, guardian->fireArcs[i]->pos4.z, 0); - if (ObjectOnLOS2(&start, &end, &hitPos, &hitMesh, ID_LARA) == GetLaraInfo(LaraItem)->ItemNumber) + if (ObjectOnLOS2(&start, &end, &hitPos, &hitMesh, ID_LARA) == LaraItem->Index) { if (LaraItem->Effect.Type != EffectType::Smoke) { diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp index 3820af174..ac6e20bf8 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp @@ -34,8 +34,8 @@ namespace TEN::Entities::Creatures::TR5 constexpr auto LION_RUN_TURN_RATE_MAX = ANGLE(5.0f); constexpr auto LION_ATTACK_TURN_RATE_MAX = ANGLE(1.0f); - const auto LionBite1 = CreatureBiteInfo(Vector3i(2, -10, 250), 21); - const auto LionBite2 = CreatureBiteInfo(Vector3i(-2, -10, 132), 21); + const auto LionBite1 = CreatureBiteInfo(Vector3(2, -10, 250), 21); + const auto LionBite2 = CreatureBiteInfo(Vector3(-2, -10, 132), 21); const auto LionAttackJoints = std::vector{ 3, 6, 21 }; enum LionState diff --git a/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp b/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp index 2b8627c69..b95e6ceed 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp @@ -60,7 +60,7 @@ namespace TEN::Entities::Creatures::TR5 item->Pose.Orientation.x = -ANGLE(67.5f); CreatureAnimation(itemNumber, angle, 0); - CreatureUnderwater(item, SECTOR(1)); + CreatureUnderwater(item, BLOCK(1)); } } } diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp index a96d0d63e..73be0c039 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::Creatures::TR5 constexpr auto ROMAN_STATUE_GRENADE_SUPER_AMMO_LIMITER = 2.0f; constexpr auto ROMAN_STATUE_EXPLOSIVE_DAMAGE_COEFF = 2.0f; - const auto RomanStatueBite = CreatureBiteInfo(Vector3i::Zero, 15); + const auto RomanStatueBite = CreatureBiteInfo(Vector3::Zero, 15); struct RomanStatueInfo { @@ -362,7 +362,7 @@ namespace TEN::Entities::Creatures::TR5 if (item->AIBits || !(GetRandomControl() & 0x1F) && - (ai.distance > pow(SECTOR(1), 2) || + (ai.distance > pow(BLOCK(1), 2) || creature->Mood != MoodType::Attack)) { joint2 = AIGuard((CreatureInfo*)creature); @@ -371,7 +371,7 @@ namespace TEN::Entities::Creatures::TR5 { item->Animation.TargetState = STATUE_STATE_TURN_180; } - else if (ai.ahead && ai.distance < pow(SECTOR(1), 2)) + else if (ai.ahead && ai.distance < pow(BLOCK(1), 2)) { if (ai.bite & ((GetRandomControl() & 3) == 0)) item->Animation.TargetState = STATUE_STATE_ATTACK_1; @@ -398,7 +398,7 @@ namespace TEN::Entities::Creatures::TR5 } } - if (item->TriggerFlags || ai.distance >= pow(SECTOR(2.5f), 2) || !ai.bite) + if (item->TriggerFlags || ai.distance >= pow(BLOCK(2.5f), 2) || !ai.bite) { item->Animation.TargetState = STATUE_STATE_WALK; break; @@ -459,9 +459,9 @@ namespace TEN::Entities::Creatures::TR5 pos2 = GetJointPosition(item, 14, Vector3i(-48, 48, 450)); - pos1.x = (GetRandomControl() & 0xFFF) + item->Pose.Position.x - SECTOR(2); - pos1.y = item->Pose.Position.y - (GetRandomControl() & 0x3FF) - SECTOR(4); - pos1.z = (GetRandomControl() & 0xFFF) + item->Pose.Position.z - SECTOR(2); + pos1.x = (GetRandomControl() & 0xFFF) + item->Pose.Position.x - BLOCK(2); + pos1.y = item->Pose.Position.y - (GetRandomControl() & 0x3FF) - BLOCK(4); + pos1.z = (GetRandomControl() & 0xFFF) + item->Pose.Position.z - BLOCK(2); for (int i = 0; i < 8; i++) { @@ -635,13 +635,13 @@ namespace TEN::Entities::Creatures::TR5 } } - if (ai.distance < pow(SECTOR(1), 2)) + if (ai.distance < pow(BLOCK(1), 2)) { item->Animation.TargetState = STATUE_STATE_IDLE; break; } - if (ai.bite && ai.distance < pow(SECTOR(1.75f), 2)) + if (ai.bite && ai.distance < pow(BLOCK(1.75f), 2)) { item->Animation.TargetState = 9; break; @@ -656,7 +656,7 @@ namespace TEN::Entities::Creatures::TR5 } } - if (item->TriggerFlags || ai.distance >= pow(SECTOR(2.5f), 2)) + if (item->TriggerFlags || ai.distance >= pow(BLOCK(2.5f), 2)) item->Animation.TargetState = STATUE_STATE_WALK; else item->Animation.TargetState = STATUE_STATE_IDLE; @@ -692,7 +692,7 @@ namespace TEN::Entities::Creatures::TR5 if (deltaFrame == 34) { - pos1 = GetJointPosition(item, 14, Vector3i(-48, 48, SECTOR(1))); + pos1 = GetJointPosition(item, 14, Vector3i(-48, 48, BLOCK(1))); pos2 = GetJointPosition(item, 14, Vector3i(-48, 48, 450)); auto orient = Geometry::GetOrientToPoint(pos2.ToVector3(), pos1.ToVector3()); @@ -801,9 +801,9 @@ namespace TEN::Entities::Creatures::TR5 short floorHeight = item->ItemFlags[2] & 0xFF00; auto* room = &g_Level.Rooms[roomNumber]; - int x = room->x + (creature->Tosspad / 256 & 0xFF) * SECTOR(1) + 512; + int x = room->x + (creature->Tosspad / 256 & 0xFF) * BLOCK(1) + 512; int y = room->minfloor + floorHeight; - int z = room->z + (creature->Tosspad & 0xFF) * SECTOR(1) + 512; + int z = room->z + (creature->Tosspad & 0xFF) * BLOCK(1) + 512; TestTriggers(x, y, z, roomNumber, true); } diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp index 10170d64e..6e905c729 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp @@ -256,7 +256,7 @@ namespace TEN::Entities::Creatures::TR5 creature->Flags = 0; } - if (laraAI.distance >= pow(SECTOR(3), 2)) + if (laraAI.distance >= pow(BLOCK(3), 2)) { item->Animation.TargetState = 1; SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_LOOP, &item->Pose, SoundEnvironment::Always); @@ -264,7 +264,7 @@ namespace TEN::Entities::Creatures::TR5 else item->Animation.TargetState = 0; - if (AI.distance < pow(SECTOR(1), 2)) + if (AI.distance < pow(BLOCK(1), 2)) { creature->MaxTurn = 0; if (abs(laraAI.angle) >= ANGLE(2.0f)) @@ -316,9 +316,9 @@ namespace TEN::Entities::Creatures::TR5 if (!LOS(&origin, &target)) { int distance = sqrt(pow(target.x - origin.x, 2) + pow(target.y - origin.y, 2) + pow(target.z - origin.z, 2)); - if (distance < SECTOR(16)) + if (distance < BLOCK(16)) { - distance = SECTOR(16) - distance; + distance = BLOCK(16) - distance; byte color = (GetRandomControl() & 0xF) + (distance / 128) + 64; TriggerDynamicLight(target.x, target.y, target.z, (GetRandomControl() & 1) + (distance / 2048) + 12, color / 2, color, color / 2); } diff --git a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp index 190a69be5..ad5e049e9 100644 --- a/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_bodypart.cpp @@ -4,6 +4,8 @@ #include "Math/Math.h" #include "Sound/sound.h" #include "tr5_missile.h" +#include "Game/Lara/lara.h" +#include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" #include "Game/items.h" #include "Game/effects/tomb4fx.h" @@ -13,6 +15,19 @@ using namespace TEN::Math::Random; constexpr int BODY_PART_LIFE = 64; constexpr int BOUNCE_FALLSPEED = 32; +constexpr auto BODY_PART_EXPLODE_DAMAGE = 50; +constexpr auto BODY_PART_EXPLODE_DAMAGE_RANGE = CLICK(3.0f); + +// TODO: Remove LaraItem global - TokyoSU: 12/6/2023 +static void BodyPartExplode(FX_INFO& fx) +{ + TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -2, 0, fx.roomNumber); + TriggerExplosionSparks(fx.pos.Position.x, fx.pos.Position.y, fx.pos.Position.z, 3, -1, 0, fx.roomNumber); + TriggerShockwave(&fx.pos, 48, 304, (GetRandomControl() & 0x1F) + 112, 128, 32, 32, 32, EulerAngles(ANGLE(12.0f), 0, 0), 0, true, false, (int)ShockwaveStyle::Normal); + + if (ItemNearLara(fx.pos.Position, BODY_PART_EXPLODE_DAMAGE_RANGE)) + DoDamage(LaraItem, BODY_PART_EXPLODE_DAMAGE); +} void ControlBodyPart(short fxNumber) { @@ -54,25 +69,25 @@ void ControlBodyPart(short fxNumber) fx->pos.Position.y += fallspeed; fx->pos.Position.z += speed * phd_cos(fx->pos.Orientation.y); - if ((fx->flag2 & BODY_EXPLODE) && + if ((fx->flag2 & BODY_DO_EXPLOSION) && !(fx->flag2 & BODY_NO_FLAME) && !TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, fx->roomNumber)) { if (GenerateInt(0, 10) > (abs(fx->fallspeed) > 0 ? 5 : 8)) - TriggerFireFlame(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, FlameType::Big); + TriggerFireFlame(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, FlameType::Medium); } - auto probe = GetCollision(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber); + auto pointColl = GetCollision(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber); if (!fx->counter) { - if (fx->pos.Position.y < probe.Position.Ceiling) + if (fx->pos.Position.y < pointColl.Position.Ceiling) { - fx->pos.Position.y = probe.Position.Ceiling; + fx->pos.Position.y = pointColl.Position.Ceiling; fx->fallspeed = -fx->fallspeed; fx->speed -= (fx->speed / 8); } - if (fx->pos.Position.y >= probe.Position.Floor) + if (fx->pos.Position.y >= pointColl.Position.Floor) { if (fx->flag2 & BODY_NO_BOUNCE) { @@ -80,10 +95,21 @@ void ControlBodyPart(short fxNumber) fx->pos.Position.y = y; fx->pos.Position.z = z; - if (fx->flag2 & BODY_NO_BOUNCE_ALT) - ExplodeFX(fx, -2, 32); - else - ExplodeFX(fx, -1, 32); + if (!(fx->flag2 & BODY_NO_SHATTER_EFFECT)) + { + if (fx->flag2 & BODY_NO_BOUNCE_ALT) + { + ExplodeFX(fx, -2, 32); + } + else + { + ExplodeFX(fx, -1, 32); + } + } + + // Remove if touched floor (no bounce mode). + if (fx->flag2 & BODY_PART_EXPLODE) + BodyPartExplode(*fx); KillEffect(fxNumber); @@ -93,10 +119,19 @@ void ControlBodyPart(short fxNumber) return; } - if (y <= probe.Position.Floor) + if (y <= pointColl.Position.Floor) { + // Remove if touched floor (no bounce mode). + if (fx->flag2 & BODY_PART_EXPLODE) + { + BodyPartExplode(*fx); + KillEffect(fxNumber); + } + if (fx->fallspeed <= BOUNCE_FALLSPEED) + { fx->fallspeed = 0; + } else { fx->fallspeed = -fx->fallspeed / 4; @@ -104,9 +139,13 @@ void ControlBodyPart(short fxNumber) if (!TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, fx->roomNumber)) { if (fx->flag2 & BODY_STONE_SOUND) + { SoundEffect(SFX_TR4_ROCK_FALL_LAND, &fx->pos); + } else if (fx->flag2 & BODY_GIBS) + { SoundEffect(SFX_TR4_LARA_THUD, &fx->pos, SoundEnvironment::Land, GenerateFloat(0.8f, 1.2f)); + } } } } @@ -120,19 +159,29 @@ void ControlBodyPart(short fxNumber) fx->speed -= (fx->speed / 4); if (abs(fx->speed) < 4) fx->speed = 0; + fx->pos.Position.y = y; } if (!fx->speed && ++fx->flag1 > BODY_PART_LIFE) { - for (int i = 0; i < 6; i++) + if (!(fx->flag2 & BODY_NO_SMOKE)) { - TriggerFlashSmoke(fx->pos.Position.x + GenerateInt(-16, 16), - fx->pos.Position.y + GenerateInt( 16, 32), - fx->pos.Position.z + GenerateInt(-16, 16), fx->roomNumber); + for (int i = 0; i < 6; i++) + { + TriggerFlashSmoke( + fx->pos.Position.x + GenerateInt(-16, 16), + fx->pos.Position.y + GenerateInt(16, 32), + fx->pos.Position.z + GenerateInt(-16, 16), fx->roomNumber); + } } - ExplodeFX(fx, -1, 32); + if (fx->flag2 & BODY_PART_EXPLODE) + BodyPartExplode(*fx); + + if (!(fx->flag2 & BODY_NO_SHATTER_EFFECT)) + ExplodeFX(fx, -1, 32); + KillEffect(fxNumber); return; } @@ -152,20 +201,28 @@ void ControlBodyPart(short fxNumber) } } - if (probe.RoomNumber != fx->roomNumber) + if (pointColl.RoomNumber != fx->roomNumber) { - if ( TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, probe.RoomNumber) && + if (TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointColl.RoomNumber) && !TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, fx->roomNumber)) { - int waterHeight = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, probe.RoomNumber); + int waterHeight = GetWaterHeight(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, pointColl.RoomNumber); + SplashSetup.y = waterHeight - 1; SplashSetup.x = fx->pos.Position.x; SplashSetup.z = fx->pos.Position.z; SplashSetup.splashPower = fx->fallspeed; SplashSetup.innerRadius = 48; - SetupSplash(&SplashSetup, probe.RoomNumber); + SetupSplash(&SplashSetup, pointColl.RoomNumber); + + // Remove if touched water. + if (fx->flag2 & BODY_PART_EXPLODE) + { + BodyPartExplode(*fx); + KillEffect(fxNumber); + } } - EffectNewRoom(fxNumber, probe.RoomNumber); + EffectNewRoom(fxNumber, pointColl.RoomNumber); } } \ No newline at end of file diff --git a/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp b/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp index 0a3aa8bf3..be3d9d1f2 100644 --- a/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp @@ -43,35 +43,35 @@ bool IsOnExpandingPlatform(int itemNumber, int x, int z) if (item->ItemFlags[1] <= 0) return false; - int xb = x / SECTOR(1); - int zb = z / SECTOR(1); - int itemxb = item->Pose.Position.x / SECTOR(1); - int itemzb = item->Pose.Position.z / SECTOR(1); + int xb = x / BLOCK(1); + int zb = z / BLOCK(1); + int itemxb = item->Pose.Position.x / BLOCK(1); + int itemzb = item->Pose.Position.z / BLOCK(1); auto bounds = GameBoundingBox(item); auto halfWidth = abs(bounds.Z2 - bounds.Z1) / 2; if (item->Pose.Orientation.y == ANGLE(90.0f)) { - int xBorder = item->Pose.Position.x + halfWidth - SECTOR(1) * item->ItemFlags[1] / 4096; + int xBorder = item->Pose.Position.x + halfWidth - BLOCK(1) * item->ItemFlags[1] / 4096; if (x < xBorder || zb != itemzb || xb != itemxb) return false; } else if (item->Pose.Orientation.y == ANGLE(270.0f)) { - int xBorder = item->Pose.Position.x - halfWidth + SECTOR(1) * item->ItemFlags[1] / 4096; + int xBorder = item->Pose.Position.x - halfWidth + BLOCK(1) * item->ItemFlags[1] / 4096; if (x > xBorder || zb != itemzb || xb != itemxb) return false; } else if (item->Pose.Orientation.y == 0) { - int zBorder = item->Pose.Position.z + halfWidth - SECTOR(1) * item->ItemFlags[1] / 4096; + int zBorder = item->Pose.Position.z + halfWidth - BLOCK(1) * item->ItemFlags[1] / 4096; if (z < zBorder || zb != itemzb || xb != itemxb) return false; } else if (item->Pose.Orientation.y == ANGLE(180.0f)) { - int zBorder = item->Pose.Position.z - halfWidth + SECTOR(1) * item->ItemFlags[1] / 4096; + int zBorder = item->Pose.Position.z - halfWidth + BLOCK(1) * item->ItemFlags[1] / 4096; if (z > zBorder || zb != itemzb || xb != itemxb) return false; } @@ -95,35 +95,35 @@ bool IsInFrontOfExpandingPlatform(int itemNumber, int x, int y, int z, int margi auto bounds = GameBoundingBox(item); auto halfWidth = abs(bounds.Z2 - bounds.Z1) / 2; - int xb = x / SECTOR(1); - int zb = z / SECTOR(1); - int itemxb = item->Pose.Position.x / SECTOR(1); - int itemzb = item->Pose.Position.z / SECTOR(1); + int xb = x / BLOCK(1); + int zb = z / BLOCK(1); + int itemxb = item->Pose.Position.x / BLOCK(1); + int itemzb = item->Pose.Position.z / BLOCK(1); if (item->Pose.Orientation.y == ANGLE(90)) { - int xBorder = item->Pose.Position.x + halfWidth - margin - SECTOR(1) * item->ItemFlags[1] / 4096; + int xBorder = item->Pose.Position.x + halfWidth - margin - BLOCK(1) * item->ItemFlags[1] / 4096; int xBorder2 = item->Pose.Position.x + halfWidth; if (x < xBorder || zb != itemzb || x > xBorder2) return false; } else if (item->Pose.Orientation.y == ANGLE(270)) { - int xBorder = item->Pose.Position.x - halfWidth + margin + SECTOR(1) * item->ItemFlags[1] / 4096; + int xBorder = item->Pose.Position.x - halfWidth + margin + BLOCK(1) * item->ItemFlags[1] / 4096; int xBorder2 = item->Pose.Position.x - halfWidth; if (x > xBorder || zb != itemzb || x < xBorder2) return false; } else if (item->Pose.Orientation.y == 0) { - int zBorder = item->Pose.Position.z + halfWidth - margin - SECTOR(1) * item->ItemFlags[1] / 4096; + int zBorder = item->Pose.Position.z + halfWidth - margin - BLOCK(1) * item->ItemFlags[1] / 4096; int zBorder2 = item->Pose.Position.z + halfWidth; if (z < zBorder || xb != itemxb || z > zBorder2) return false; } else if (item->Pose.Orientation.y == ANGLE(180)) { - int zBorder = item->Pose.Position.z - halfWidth + margin + SECTOR(1) * item->ItemFlags[1] / 4096; + int zBorder = item->Pose.Position.z - halfWidth + margin + BLOCK(1) * item->ItemFlags[1] / 4096; int zBorder2 = item->Pose.Position.z - halfWidth; if (z > zBorder || xb != itemxb || z < zBorder2) return false; diff --git a/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp b/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp index 8d863b55f..fa4ecb2ae 100644 --- a/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_pushableblock.cpp @@ -675,12 +675,10 @@ namespace TEN::Entities::Generic return false; const auto& object = Objects[CollidedItems[i]->ObjectNumber]; - int collidedIndex = CollidedItems[i] - g_Level.Items.data(); // Index of CollidedItems[i]. - auto colPos = CollidedItems[i]->Pose.Position; // Check if floor function returns nullopt. - if (object.floor(collidedIndex, colPos.x, colPos.y, colPos.z) == std::nullopt) + if (object.floor(CollidedItems[i]->Index, colPos.x, colPos.y, colPos.z) == std::nullopt) return false; } @@ -757,13 +755,12 @@ namespace TEN::Entities::Generic else { const auto& object = Objects[CollidedItems[i]->ObjectNumber]; - int collidedIndex = CollidedItems[i] - g_Level.Items.data(); int xCol = CollidedItems[i]->Pose.Position.x; int yCol = CollidedItems[i]->Pose.Position.y; int zCol = CollidedItems[i]->Pose.Position.z; - if (object.floor(collidedIndex, xCol, yCol, zCol) == std::nullopt) + if (object.floor(CollidedItems[i]->Index, xCol, yCol, zCol) == std::nullopt) return false; } } @@ -832,12 +829,11 @@ namespace TEN::Entities::Generic else { const auto& object = Objects[CollidedItems[i]->ObjectNumber]; - int collidedIndex = CollidedItems[i] - g_Level.Items.data(); int xCol = CollidedItems[i]->Pose.Position.x; int yCol = CollidedItems[i]->Pose.Position.y; int zCol = CollidedItems[i]->Pose.Position.z; - if (object.floor(collidedIndex, xCol, yCol, zCol) == std::nullopt) + if (object.floor(CollidedItems[i]->Index, xCol, yCol, zCol) == std::nullopt) return false; } } diff --git a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp index 3d9ad46fd..0685deb1a 100644 --- a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp @@ -20,8 +20,9 @@ void InitializeRaisingBlock(short itemNumber) auto* item = &g_Level.Items[itemNumber]; short roomNumber = item->RoomNumber; - FloorInfo* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); - if(floor->Box != NO_BOX) + auto* floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); + + if (floor->Box != NO_BOX) g_Level.Boxes[floor->Box].flags &= ~BLOCKED; // Set mutators to EulerAngles identity by default. @@ -38,6 +39,22 @@ void InitializeRaisingBlock(short itemNumber) TEN::Collision::Floordata::UpdateBridgeItem(itemNumber); } +void ShakeRaisingBlock(ItemInfo* item) +{ + SoundEffect(SFX_TR4_RAISING_BLOCK, &item->Pose); + + if (item->TriggerFlags == 0) + return; + + if ((item->Pose.Position.ToVector3() - Camera.pos.ToVector3()).Length() < BLOCK(10)) + { + if (item->ItemFlags[1] == 64 || item->ItemFlags[1] == 4096) + Camera.bounce = -32; + else + Camera.bounce = -16; + } +} + void ControlRaisingBlock(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; @@ -46,49 +63,17 @@ void ControlRaisingBlock(short itemNumber) { if (!item->ItemFlags[2]) { - if (item->ObjectNumber == ID_RAISING_BLOCK1) - { - if (item->TriggerFlags == -1) - { - //AlterFloorHeight(item, -255); - } - else if (item->TriggerFlags == -3) - { - //AlterFloorHeight(item, -1023); - } - else - { - //AlterFloorHeight(item, -item->itemFlags[7]); - } - } - else - { - //AlterFloorHeight(item, -item->itemFlags[7]); - } - item->ItemFlags[2] = 1; } if (item->TriggerFlags < 0) + { item->ItemFlags[1] = 1; + } else if (item->ItemFlags[1] < 4096) { - SoundEffect(SFX_TR4_RAISING_BLOCK, &item->Pose); - + ShakeRaisingBlock(item); item->ItemFlags[1] += 64; - - if (item->TriggerFlags > 0) - { - if (abs(item->Pose.Position.x - Camera.pos.x) < 10240 && - abs(item->Pose.Position.x - Camera.pos.x) < 10240 && - abs(item->Pose.Position.x - Camera.pos.x) < 10240) - { - if (item->ItemFlags[1] == 64 || item->ItemFlags[1] == 4096) - Camera.bounce = -32; - else - Camera.bounce = -16; - } - } } } else if (item->ItemFlags[1] <= 0 || item->TriggerFlags < 0) @@ -101,22 +86,12 @@ void ControlRaisingBlock(short itemNumber) { if (item->TriggerFlags == -1) { - //AlterFloorHeight(item, 255); item->ItemFlags[2] = 0; } else if (item->TriggerFlags == -3) { - //AlterFloorHeight(item, 1023); item->ItemFlags[2] = 0; } - else - { - //AlterFloorHeight(item, item->itemFlags[7]); - } - } - else - { - //AlterFloorHeight(item, item->itemFlags[7]); } item->ItemFlags[2] = 0; @@ -124,21 +99,7 @@ void ControlRaisingBlock(short itemNumber) } else { - SoundEffect(SFX_TR4_RAISING_BLOCK, &item->Pose); - - if (item->TriggerFlags >= 0) - { - if (abs(item->Pose.Position.x - Camera.pos.x) < 10240 && - abs(item->Pose.Position.x - Camera.pos.x) < 10240 && - abs(item->Pose.Position.x - Camera.pos.x) < 10240) - { - if (item->ItemFlags[1] == 64 || item->ItemFlags[1] == 4096) - Camera.bounce = -32; - else - Camera.bounce = -16; - } - } - + ShakeRaisingBlock(item); item->ItemFlags[1] -= 64; } diff --git a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp index 23d7309f3..7f04f59c3 100644 --- a/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_rollingball.cpp @@ -15,7 +15,7 @@ #include "Sound/sound.h" #include "Specific/level.h" -constexpr auto ROLLING_BALL_MAX_VELOCITY = SECTOR(3); +constexpr auto ROLLING_BALL_MAX_VELOCITY = BLOCK(3); void RollingBallCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) { diff --git a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp index d427b9078..0d330d318 100644 --- a/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_teleporter.cpp @@ -201,7 +201,7 @@ void ControlTeleporter(short itemNumber) LaraItem->Pose.Position.y = GetFloorHeight(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); if (LaraItem->RoomNumber != roomNumber) - ItemNewRoom(Lara.ItemNumber, roomNumber); + ItemNewRoom(LaraItem->Index, roomNumber); if (item->Flags & IFLAG_INVISIBLE) { diff --git a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp index 97f0b5ec1..8ff5953de 100644 --- a/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp +++ b/TombEngine/Objects/TR5/Shatter/tr5_smashobject.cpp @@ -43,7 +43,7 @@ void SmashObject(short itemNumber) item->Collidable = 0; item->MeshBits = 0xFFFE; - ExplodingDeath(itemNumber, BODY_EXPLODE | BODY_NO_BOUNCE); + ExplodingDeath(itemNumber, BODY_DO_EXPLOSION | BODY_NO_BOUNCE); item->Flags |= IFLAG_INVISIBLE; diff --git a/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp b/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp index ab4f89d9e..e6791f28b 100644 --- a/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp +++ b/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp @@ -22,7 +22,7 @@ namespace TEN::Entities::Switches GameBoundingBox( -CLICK(1), CLICK(1), 0, 0, - -SECTOR(0.5f), SECTOR(0.5f) + -BLOCK(0.5f), BLOCK(0.5f) ), std::pair( EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)), diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp index 22b1fed91..506035088 100644 --- a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp +++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp @@ -142,8 +142,8 @@ void ExplosionControl(short itemNumber) TriggerShockwave(&CollidedItems[i]->Pose, 48, 304, 96, 128, 96, 0, 24, EulerAngles::Zero, 0, true, false, (int)ShockwaveStyle::Normal); CollidedItems[i]->Pose.Position.y += 128; ExplodeItemNode(CollidedItems[i], 0, 0, 80); - SmashObject(CollidedItems[i] - g_Level.Items.data()); - KillItem(CollidedItems[i] - g_Level.Items.data()); + SmashObject(CollidedItems[i]->Index); + KillItem(CollidedItems[i]->Index); } else if (CollidedItems[i]->ObjectNumber != ID_SWITCH_TYPE7 && CollidedItems[i]->ObjectNumber != ID_SWITCH_TYPE8) { diff --git a/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp b/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp index 0c4d4a450..ed4f36f37 100644 --- a/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp +++ b/TombEngine/Objects/TR5/Trap/tr5_ventilator.cpp @@ -43,11 +43,11 @@ void VentilatorEffect(GameBoundingBox* bounds, int intensity, short rot, int spe } } - if (abs(Camera.pos.x - x) <= SECTOR(7)) + if (abs(Camera.pos.x - x) <= BLOCK(7)) { - if (abs(Camera.pos.y - y) <= SECTOR(7)) + if (abs(Camera.pos.y - y) <= BLOCK(7)) { - if (abs(Camera.pos.z - z) <= SECTOR(7)) + if (abs(Camera.pos.z - z) <= BLOCK(7)) { auto* spark = GetFreeParticle(); @@ -130,7 +130,7 @@ void InitializeVentilator(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; - item->ItemFlags[0] = item->TriggerFlags * SECTOR(1); + item->ItemFlags[0] = item->TriggerFlags * BLOCK(1); if (item->ItemFlags[0] < 2048) item->ItemFlags[0] = 3072; } diff --git a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp index fa5d46275..3df7c9b76 100644 --- a/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp +++ b/TombEngine/Objects/TR5/Trap/tr5_wreckingball.cpp @@ -96,10 +96,10 @@ void WreckingBallControl(short itemNumber) bool test = true; - if ((LaraItem->Pose.Position.x >= SECTOR(44) && - LaraItem->Pose.Position.x <= SECTOR(56)&& - LaraItem->Pose.Position.z >= SECTOR(26) && - LaraItem->Pose.Position.z <= SECTOR(42)) || + if ((LaraItem->Pose.Position.x >= BLOCK(44) && + LaraItem->Pose.Position.x <= BLOCK(56)&& + LaraItem->Pose.Position.z >= BLOCK(26) && + LaraItem->Pose.Position.z <= BLOCK(42)) || item->ItemFlags[2] < 900) { if (item->ItemFlags[2] < 900) diff --git a/TombEngine/Objects/game_object_ids.h b/TombEngine/Objects/game_object_ids.h index 128de16f2..8ce6c5995 100644 --- a/TombEngine/Objects/game_object_ids.h +++ b/TombEngine/Objects/game_object_ids.h @@ -157,15 +157,15 @@ enum GAME_OBJECT_ID : short ID_CHEF, ID_KOLD = 219, - ID_WINGED_MUMMY, - ID_CENTAUR_MUTANT, - ID_DOPPELGANGER, - ID_NATLA, - ID_WINGED_NATLA, - ID_GIANT_MUTANT, - ID_PROJ_NATLA, - ID_PROJ_SHARD, - ID_PROJ_BOMB, + ID_WINGED_MUMMY, + ID_CENTAUR_MUTANT, + ID_DOPPELGANGER, + ID_NATLA, + // 224 + ID_GIANT_MUTANT = 225, + // 226 + ID_PROJ_SHARD = 227, + ID_PROJ_BOMB, ID_YETI, ID_BIRDMONSTER, ID_MARCO_BARTOLI, @@ -804,7 +804,7 @@ enum GAME_OBJECT_ID : short ID_WATERFALLSS1, ID_WATERFALLSS2, ID_FISHTANK, - ID_BACON_REFERENCE, + ID_DOPPELGANGER_ORIGIN, ID_CORPSE, ID_WRAITH_TRAP, diff --git a/TombEngine/Renderer/RenderTarget2D/RenderTarget2D.cpp b/TombEngine/Renderer/RenderTarget2D/RenderTarget2D.cpp index 0270be504..ee9726a0d 100644 --- a/TombEngine/Renderer/RenderTarget2D/RenderTarget2D.cpp +++ b/TombEngine/Renderer/RenderTarget2D/RenderTarget2D.cpp @@ -16,9 +16,9 @@ namespace TEN::Renderer D3D11_RTV_DIMENSION rtvDimension = D3D11_RTV_DIMENSION_TEXTURE2D; int sampleCount = 1; - if (g_Configuration.Antialiasing > AntialiasingMode::Low) + if (g_Configuration.AntialiasingMode > AntialiasingMode::Low) { - int potentialSampleCount = (g_Configuration.Antialiasing == AntialiasingMode::Medium) ? 2 : 4; + int potentialSampleCount = (g_Configuration.AntialiasingMode == AntialiasingMode::Medium) ? 2 : 4; unsigned int qualityLevels = 0; if (device->CheckMultisampleQualityLevels(colorFormat, potentialSampleCount, &qualityLevels) == S_OK && qualityLevels > 0) diff --git a/TombEngine/Renderer/Renderer11.cpp b/TombEngine/Renderer/Renderer11.cpp index a450b2c83..2f0405463 100644 --- a/TombEngine/Renderer/Renderer11.cpp +++ b/TombEngine/Renderer/Renderer11.cpp @@ -16,7 +16,6 @@ namespace TEN::Renderer Renderer11::Renderer11() : gameCamera({0, 0, 0}, {0, 0, 1}, {0, 1, 0}, 1, 1, 0, 1, 10, 90) { - m_blinkColorDirection = 1; } Renderer11::~Renderer11() @@ -497,7 +496,7 @@ namespace TEN::Renderer void Renderer11::SetCullMode(CULL_MODES cullMode, bool force) { - if (m_numDebugPage == RENDERER_DEBUG_PAGE::WIREFRAME_MODE) + if (DebugPage == RendererDebugPage::WireframeMode) { m_context->RSSetState(m_states->Wireframe()); return; diff --git a/TombEngine/Renderer/Renderer11.h b/TombEngine/Renderer/Renderer11.h index a9849db2a..a135d8edc 100644 --- a/TombEngine/Renderer/Renderer11.h +++ b/TombEngine/Renderer/Renderer11.h @@ -303,6 +303,8 @@ namespace TEN::Renderer Texture2DArray m_shadowMap; + std::vector m_visitedRoomsStack; + // Shaders ComPtr m_vsRooms; ComPtr m_vsRooms_Anim; @@ -378,9 +380,9 @@ namespace TEN::Renderer // Text std::unique_ptr m_gameFont; std::vector m_strings; - int m_blinkColorValue; - int m_blinkColorDirection; - bool m_blinkUpdated = false; + float BlinkColorValue = 0.0f; + float BlinkTime = 0.0f; + bool IsBlinkUpdated = false; // System resources Texture2D m_logo; @@ -461,7 +463,7 @@ namespace TEN::Renderer int m_currentY; int m_dotProducts = 0; - RENDERER_DEBUG_PAGE m_numDebugPage = NO_PAGE; + RendererDebugPage DebugPage = RendererDebugPage::None; // Times for debug int m_timeUpdate; @@ -529,17 +531,17 @@ namespace TEN::Renderer void DrawAllStrings(); void DrawLaserBarriers(RenderView& view); void DrawHorizonAndSky(RenderView& renderView, ID3D11DepthStencilView* depthTarget); - void DrawRooms(RenderView& view, bool transparent); + void DrawRooms(RenderView& view, RendererPass rendererPass); void DrawRoomsSorted(RendererTransparentFaceInfo* info, bool resetPipeline, RenderView& view); void DrawSpritesSorted(RendererTransparentFaceInfo* info, bool resetPipeline, RenderView& view); void DrawStaticsSorted(RendererTransparentFaceInfo* info, bool resetPipeline, RenderView& view); - void DrawItems(RenderView& view, bool transparent); + void DrawItems(RenderView& view, RendererPass rendererPass); void DrawItemsSorted(RendererTransparentFaceInfo* info, bool resetPipeline, RenderView& view); - void DrawAnimatingItem(RendererItem* item, RenderView& view, bool transparent); - void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, bool transparent); + void DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass); + void DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass); void DrawBaddyGunflashes(RenderView& view); - void DrawStatics(RenderView& view, bool transparent); - void DrawLara(RenderView& view, bool transparent); + void DrawStatics(RenderView& view, RendererPass rendererPass); + void DrawLara(RenderView& view, RendererPass rendererPass); void DrawFires(RenderView& view); void DrawParticles(RenderView& view); void DrawSmokes(RenderView& view); @@ -549,8 +551,8 @@ namespace TEN::Renderer void DrawWeatherParticles(RenderView& view); void DrawDrips(RenderView& view); void DrawBubbles(RenderView& view); - void DrawEffects(RenderView& view, bool transparent); - void DrawEffect(RenderView& view, RendererEffect* effect, bool transparent); + void DrawEffects(RenderView& view, RendererPass rendererPass); + void DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass); void DrawSplashes(RenderView& view); void DrawSprites(RenderView& view); void DrawSortedFaces(RenderView& view); @@ -568,7 +570,7 @@ namespace TEN::Renderer void DrawStatistics(); void DrawExamines(); void DrawDiary(); - void DrawDebris(RenderView& view, bool transparent); + void DrawDebris(RenderView& view, RendererPass rendererPass); void DrawFullScreenImage(ID3D11ShaderResourceView* texture, float fade, ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget); void DrawShockwaves(RenderView& view); @@ -579,10 +581,10 @@ namespace TEN::Renderer void DrawSmokeParticles(RenderView& view); void DrawSparkParticles(RenderView& view); void DrawExplosionParticles(RenderView& view); - void DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, bool transparent); - void DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, bool transparent); - void DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, bool transparent); - void DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, bool transparent); + void DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RendererPass rendererPass); + void DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RendererPass rendererPass); + void DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RendererPass rendererPass); + void DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RendererPass rendererPass); void DrawSimpleParticles(RenderView& view); void DrawStreamers(RenderView& view); void DrawFootprints(RenderView& view); @@ -701,13 +703,15 @@ namespace TEN::Renderer void RenderInventory(); void RenderScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, RenderView& view); void ClearScene(); + void SaveScreenshot(); void PrintDebugMessage(LPCSTR message, ...); void DrawDebugInfo(RenderView& view); - void SwitchDebugPage(bool back); + void SwitchDebugPage(bool goBack); void DrawDisplayPickup(const DisplayPickup& pickup); int Synchronize(); - void AddString(int x, int y, const char* string, D3DCOLOR color, int flags); + void AddString(int x, int y, const std::string& string, D3DCOLOR color, int flags); void AddString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags); + void AddDebugString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags, RendererDebugPage page); void FreeRendererData(); void AddDynamicLight(int x, int y, int z, short falloff, byte r, byte g, byte b); void RenderLoadingScreen(float percentage); @@ -717,13 +721,15 @@ namespace TEN::Renderer bool IsFullsScreen(); void RenderTitleImage(); void AddLine2D(const Vector2& origin, const Vector2& target, const Color& color); - void AddLine3D(Vector3 start, Vector3 end, Vector4 color); - void AddBox(Vector3 min, Vector3 max, Vector4 color); - void AddBox(Vector3* corners, Vector4 color); - void AddDebugBox(BoundingOrientedBox box, Vector4 color, RENDERER_DEBUG_PAGE page); - void AddDebugBox(Vector3 min, Vector3 max, Vector4 color, RENDERER_DEBUG_PAGE page); - void AddSphere(Vector3 center, float radius, Vector4 color); - void AddDebugSphere(Vector3 center, float radius, Vector4 color, RENDERER_DEBUG_PAGE page); + void AddLine3D(const Vector3& origin, const Vector3& target, const Vector4& color); + void AddReticle(const Vector3& center, float radius, const Vector4& color); + void AddDebugReticle(const Vector3& center, float radius, const Vector4& color, RendererDebugPage page); + void AddBox(const Vector3 min, const Vector3& max, const Vector4& color); + void AddBox(Vector3* corners, const Vector4& color); + void AddDebugBox(const BoundingOrientedBox& box, const Vector4& color, RendererDebugPage page); + void AddDebugBox(const Vector3& min, const Vector3& max, const Vector4& color, RendererDebugPage page); + void AddSphere(const Vector3& center, float radius, const Vector4& color); + void AddDebugSphere(const Vector3& center, float radius, const Vector4& color, RendererDebugPage page); void ChangeScreenResolution(int width, int height, bool windowed); void FlipRooms(short roomNumber1, short roomNumber2); void UpdateLaraAnimations(bool force); diff --git a/TombEngine/Renderer/Renderer11Compatibility.cpp b/TombEngine/Renderer/Renderer11Compatibility.cpp index e0bd959cc..8f0e1a75a 100644 --- a/TombEngine/Renderer/Renderer11Compatibility.cpp +++ b/TombEngine/Renderer/Renderer11Compatibility.cpp @@ -208,7 +208,7 @@ namespace TEN::Renderer r->ItemsToDraw.reserve(MAX_ITEMS_DRAW); r->EffectsToDraw.reserve(MAX_ITEMS_DRAW); r->TransparentFacesToDraw.reserve(MAX_TRANSPARENT_FACES_PER_ROOM); - + Vector3 boxMin = Vector3(room.x + BLOCK(1), room.maxceiling - CLICK(1), room.z + BLOCK(1)); Vector3 boxMax = Vector3(room.x + (room.xSize - 1) * BLOCK(1), room.minfloor + CLICK(1), room.z + (room.zSize - 1) * BLOCK(1)); Vector3 center = (boxMin + boxMax) / 2.0f; @@ -316,6 +316,7 @@ namespace TEN::Renderer vertex->UV = poly.textureCoordinates[k]; vertex->Color = Vector4(room.colors[index].x, room.colors[index].y, room.colors[index].z, 1.0f); vertex->Tangent = poly.tangents[k]; + vertex->Binormal = poly.binormals[k]; vertex->AnimationFrameOffset = poly.animatedFrame; vertex->IndexInPoly = k; vertex->OriginalIndex = index; @@ -420,7 +421,7 @@ namespace TEN::Renderer light->Position = Vector3(oldLight->x, oldLight->y, oldLight->z); light->Color = Vector3(oldLight->r, oldLight->g, oldLight->b); light->Intensity = oldLight->intensity; - light->In = oldLight->in; + light->In = oldLight->in; light->Out = oldLight->out; light->Type = LIGHT_TYPE_FOG_BULB; light->Luma = Luma(light->Color); @@ -459,7 +460,7 @@ namespace TEN::Renderer ); TENLog("Preparing object data...", LogLevel::Info); - + bool isSkinPresent = false; totalVertices = 0; @@ -497,7 +498,7 @@ namespace TEN::Renderer moveable.Id = MoveablesIds[i]; moveable.DoNotDraw = (obj->drawRoutine == nullptr); moveable.ShadowType = obj->shadowType; - + for (int j = 0; j < obj->nmeshes; j++) { // HACK: mesh pointer 0 is the placeholder for Lara's body parts and is right hand with pistols @@ -790,7 +791,7 @@ namespace TEN::Renderer for (int i = 0; i < StaticObjectsIds.size(); i++) { int objNum = StaticObjectsIds[i]; - STATIC_INFO* obj = &StaticObjects[objNum]; + StaticInfo* obj = &StaticObjects[objNum]; MESH* mesh = &g_Level.Meshes[obj->meshNumber]; for (auto& bucket : mesh->buckets) @@ -807,7 +808,7 @@ namespace TEN::Renderer lastIndex = 0; for (int i = 0; i < StaticObjectsIds.size(); i++) { - STATIC_INFO *obj = &StaticObjects[StaticObjectsIds[i]]; + StaticInfo*obj = &StaticObjects[StaticObjectsIds[i]]; m_staticObjects[StaticObjectsIds[i]] = RendererObject(); RendererObject &staticObject = *m_staticObjects[StaticObjectsIds[i]]; staticObject.Type = 1; @@ -922,11 +923,19 @@ namespace TEN::Renderer vertex.Position.x = meshPtr->positions[v].x; vertex.Position.y = meshPtr->positions[v].y; vertex.Position.z = meshPtr->positions[v].z; - + vertex.Normal.x = poly->normals[k].x; vertex.Normal.y = poly->normals[k].y; vertex.Normal.z = poly->normals[k].z; + vertex.Tangent.x = poly->tangents[k].x; + vertex.Tangent.y = poly->tangents[k].y; + vertex.Tangent.z = poly->tangents[k].z; + + vertex.Binormal.x = poly->binormals[k].x; + vertex.Binormal.y = poly->binormals[k].y; + vertex.Binormal.z = poly->binormals[k].z; + vertex.UV.x = poly->textureCoordinates[k].x; vertex.UV.y = poly->textureCoordinates[k].y; diff --git a/TombEngine/Renderer/Renderer11Draw.cpp b/TombEngine/Renderer/Renderer11Draw.cpp index 6a4e4acab..16e2e8b45 100644 --- a/TombEngine/Renderer/Renderer11Draw.cpp +++ b/TombEngine/Renderer/Renderer11Draw.cpp @@ -31,6 +31,7 @@ #include "Specific/winmain.h" using namespace std::chrono; +using namespace TEN::Effects::Hair; using namespace TEN::Entities::Generic; using namespace TEN::Hud; @@ -41,7 +42,7 @@ namespace TEN::Renderer void Renderer11::RenderBlobShadows(RenderView& renderView) { auto nearestSpheres = std::vector{}; - nearestSpheres.reserve(g_Configuration.ShadowMaxBlobs); + nearestSpheres.reserve(g_Configuration.ShadowBlobsMax); // Collect player spheres. static const std::array sphereMeshes = { LM_HIPS, LM_TORSO, LM_LFOOT, LM_RFOOT }; @@ -90,7 +91,7 @@ namespace TEN::Renderer } } - if (nearestSpheres.size() > g_Configuration.ShadowMaxBlobs) + if (nearestSpheres.size() > g_Configuration.ShadowBlobsMax) { std::sort(nearestSpheres.begin(), nearestSpheres.end(), [](const Sphere& a, const Sphere& b) { @@ -98,8 +99,8 @@ namespace TEN::Renderer return Vector3::Distance(laraPos.ToVector3(), a.position) < Vector3::Distance(laraPos.ToVector3(), b.position); }); - std::copy(nearestSpheres.begin(), nearestSpheres.begin() + g_Configuration.ShadowMaxBlobs, m_stShadowMap.Spheres); - m_stShadowMap.NumSpheres = g_Configuration.ShadowMaxBlobs; + std::copy(nearestSpheres.begin(), nearestSpheres.begin() + g_Configuration.ShadowBlobsMax, m_stShadowMap.Spheres); + m_stShadowMap.NumSpheres = g_Configuration.ShadowBlobsMax; } else { @@ -167,7 +168,7 @@ namespace TEN::Renderer // Set texture BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP); // Set camera matrices Matrix view; @@ -175,7 +176,7 @@ namespace TEN::Renderer if (m_shadowLight->Type == LIGHT_TYPE_POINT) { view = Matrix::CreateLookAt(m_shadowLight->Position, m_shadowLight->Position + - RenderTargetCube::forwardVectors[step] * SECTOR(10), + RenderTargetCube::forwardVectors[step] * BLOCK(10), RenderTargetCube::upVectors[step]); projection = Matrix::CreatePerspectiveFieldOfView(90.0f * PI / 180.0f, 1.0f, 16.0f, m_shadowLight->Out); @@ -184,7 +185,7 @@ namespace TEN::Renderer else if (m_shadowLight->Type == LIGHT_TYPE_SPOT) { view = Matrix::CreateLookAt(m_shadowLight->Position, - m_shadowLight->Position - m_shadowLight->Direction * SECTOR(10), + m_shadowLight->Position + m_shadowLight->Direction * BLOCK(10), Vector3(0.0f, -1.0f, 0.0f)); // Vertex lighting fades out in 1024-steps. increase angle artificially for a bigger blend radius. @@ -237,9 +238,9 @@ namespace TEN::Renderer { RendererRoom& room = m_rooms[item->RoomNumber]; - DrawLaraHolsters(item, &room, false); - DrawLaraJoints(item, &room, false); - DrawLaraHair(item, &room, false); + DrawLaraHolsters(item, &room, RendererPass::ShadowMap); + DrawLaraJoints(item, &room, RendererPass::ShadowMap); + DrawLaraHair(item, &room, RendererPass::ShadowMap); } } } @@ -247,7 +248,7 @@ namespace TEN::Renderer void Renderer11::DrawGunShells(RenderView& view) { auto& room = m_rooms[LaraItem->RoomNumber]; - auto* item = &m_items[Lara.ItemNumber]; + auto* item = &m_items[LaraItem->Index]; int gunShellsCount = 0; short objectNumber = 0; @@ -312,7 +313,7 @@ namespace TEN::Renderer } BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); DrawIndexedInstancedTriangles(bucket.NumIndices, gunShellsCount, bucket.StartIndex, 0); @@ -422,62 +423,62 @@ namespace TEN::Renderer if (Objects[ID_SPIDERS_EMITTER].loaded) { - ObjectInfo* obj = &Objects[ID_SPIDERS_EMITTER]; - RendererObject* moveableObj = m_moveableObjects[ID_SPIDERS_EMITTER].get(); - short* meshPtr = Meshes[Objects[ID_SPIDERS_EMITTER].meshIndex + ((Wibble >> 2) & 2)]; - RendererMesh* mesh = m_meshPointersToMesh[meshPtr]; - RendererBucket* bucket = mesh->GetBucket(bucketIndex); + ObjectInfo* obj = &Objects[ID_SPIDERS_EMITTER]; + RendererObject* moveableObj = m_moveableObjects[ID_SPIDERS_EMITTER].get(); + short* meshPtr = Meshes[Objects[ID_SPIDERS_EMITTER].meshIndex + ((Wibble >> 2) & 2)]; + RendererMesh* mesh = m_meshPointersToMesh[meshPtr]; + RendererBucket* bucket = mesh->GetBucket(bucketIndex); - if (bucket->NumVertices == 0) - return true; + if (bucket->NumVertices == 0) + return true; - setGpuStateForBucket(bucketIndex); + setGpuStateForBucket(bucketIndex); - m_device->SetStreamSource(0, bucket->GetVertexBuffer(), 0, sizeof(RendererVertex)); - m_device->SetIndices(bucket->GetIndexBuffer()); + m_device->SetStreamSource(0, bucket->GetVertexBuffer(), 0, sizeof(RendererVertex)); + m_device->SetIndices(bucket->GetIndexBuffer()); - LPD3DXEFFECT effect; - if (pass == RENDERER_PASS_SHADOW_MAP) - effect = m_shaderDepth->GetEffect(); - else if (pass == RENDERER_PASS_RECONSTRUCT_DEPTH) - effect = m_shaderReconstructZBuffer->GetEffect(); - else if (pass == RENDERER_PASS_GBUFFER) - effect = m_shaderFillGBuffer->GetEffect(); - else - effect = m_shaderTransparent->GetEffect(); + LPD3DXEFFECT effect; + if (pass == RENDERER_PASS_SHADOW_MAP) + effect = m_shaderDepth->GetEffect(); + else if (pass == RENDERER_PASS_RECONSTRUCT_DEPTH) + effect = m_shaderReconstructZBuffer->GetEffect(); + else if (pass == RENDERER_PASS_GBUFFER) + effect = m_shaderFillGBuffer->GetEffect(); + else + effect = m_shaderTransparent->GetEffect(); - effect->SetBool(effect->GetParameterByName(nullptr, "UseSkinning"), false); - effect->SetInt(effect->GetParameterByName(nullptr, "ModelType"), MODEL_TYPE_MOVEABLE); + effect->SetBool(effect->GetParameterByName(nullptr, "UseSkinning"), false); + effect->SetInt(effect->GetParameterByName(nullptr, "ModelType"), MODEL_TYPE_MOVEABLE); - if (bucketIndex == RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKET_SOLID_DS) - effect->SetInt(effect->GetParameterByName(nullptr, "BlendMode"), BLENDMODE_OPAQUE); - else - effect->SetInt(effect->GetParameterByName(nullptr, "BlendMode"), BLENDMODE_ALPHATEST); + if (bucketIndex == RENDERER_BUCKET_SOLID || bucketIndex == RENDERER_BUCKET_SOLID_DS) + effect->SetInt(effect->GetParameterByName(nullptr, "BlendMode"), BLENDMODE_OPAQUE); + else + effect->SetInt(effect->GetParameterByName(nullptr, "BlendMode"), BLENDMODE_ALPHATEST); - for (int i = 0; i < NUM_SPIDERS; i++) - { - SPIDER_STRUCT* spider = &Spiders[i]; + for (int i = 0; i < NUM_SPIDERS; i++) + { + SPIDER_STRUCT* spider = &Spiders[i]; - if (spider->on) - { - XMMATRIXTranslation(&m_tempTranslation, spider->pos.xPos, spider->pos.yPos, spider->pos.zPos); - XMMATRIXRotationYawPitchRoll(&m_tempRotation, spider->pos.yRot, spider->pos.xRot, spider->pos.zRot); - XMMATRIXMultiply(&m_tempWorld, &m_tempRotation, &m_tempTranslation); - effect->SetMatrix(effect->GetParameterByName(nullptr, "World"), &m_tempWorld); + if (spider->on) + { + XMMATRIXTranslation(&m_tempTranslation, spider->pos.xPos, spider->pos.yPos, spider->pos.zPos); + XMMATRIXRotationYawPitchRoll(&m_tempRotation, spider->pos.yRot, spider->pos.xRot, spider->pos.zRot); + XMMATRIXMultiply(&m_tempWorld, &m_tempRotation, &m_tempTranslation); + effect->SetMatrix(effect->GetParameterByName(nullptr, "World"), &m_tempWorld); - effect->SetVector(effect->GetParameterByName(nullptr, "AmbientLight"), &m_rooms[spider->roomNumber]->AmbientLight); + effect->SetVector(effect->GetParameterByName(nullptr, "AmbientLight"), &m_rooms[spider->roomNumber]->AmbientLight); - for (int iPass = 0; iPass < cPasses; iPass++) - { - effect->BeginPass(iPass); - effect->CommitChanges(); + for (int iPass = 0; iPass < cPasses; iPass++) + { + effect->BeginPass(iPass); + effect->CommitChanges(); - drawPrimitives(D3DPT_TRIANGLELIST, 0, 0, bucket->NumVertices, 0, bucket->Indices.size() / 3); + drawPrimitives(D3DPT_TRIANGLELIST, 0, 0, bucket->NumVertices, 0, bucket->Indices.size() / 3); - effect->EndPass(); - } - } - } + effect->EndPass(); + } + } + } }*/ } @@ -596,7 +597,7 @@ namespace TEN::Renderer SetBlendMode(bucket.BlendMode); BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); DrawIndexedInstancedTriangles(bucket.NumIndices, batsCount, bucket.StartIndex, 0); @@ -763,65 +764,91 @@ namespace TEN::Renderer SetCullMode(CULL_MODE_CCW); } - void Renderer11::AddLine3D(Vector3 start, Vector3 end, Vector4 color) + void Renderer11::AddLine3D(const Vector3& target, const Vector3& origin, const Vector4& color) { if (m_Locked) return; RendererLine3D line; - line.Start = start; - line.End = end; + line.Start = target; + line.End = origin; line.Color = color; m_lines3DToDraw.push_back(line); } - void Renderer11::AddSphere(Vector3 center, float radius, Vector4 color) + void Renderer11::AddReticle(const Vector3& center, float radius, const Vector4& color) { + auto origin0 = center + Vector3(radius, 0.0f, 0.0f); + auto target0 = center + Vector3(-radius, 0.0f, 0.0f); + AddLine3D(origin0, target0, color); + + auto origin1 = center + Vector3(0.0f, radius, 0.0f); + auto target1 = center + Vector3(0.0f, -radius, 0.0f); + AddLine3D(origin1, target1, color); + + auto origin2 = center + Vector3(0.0f, 0.0f, radius); + auto target2 = center + Vector3(0.0f, 0.0f, -radius); + AddLine3D(origin2, target2, color); + } + + void Renderer11::AddDebugReticle(const Vector3& center, float radius, const Vector4& color, RendererDebugPage page) + { + if (!DebugMode || DebugPage != page) + return; + + AddReticle(center, radius, color); + } + + void Renderer11::AddSphere(const Vector3& center, float radius, const Vector4& color) + { + constexpr auto AXIS_COUNT = 3; + constexpr auto SUBDIVISION_COUNT = 32; + constexpr auto STEP_COUNT = 4; + constexpr auto STEP_ANGLE = PI / STEP_COUNT; + if (m_Locked) return; - constexpr auto subdivisions = 10; - constexpr auto steps = 6; - constexpr auto step = PI / steps; + auto prevPoints = std::array{}; - std::array prevPoint; - - for (int s = 0; s < steps; s++) + for (int i = 0; i < STEP_COUNT; i++) { - auto x = sin(step * (float)s) * radius; - auto z = cos(step * (float)s) * radius; - float currAngle = 0.0f; + float x = sin(STEP_ANGLE * i) * radius; + float z = cos(STEP_ANGLE * i) * radius; + float angle = 0.0f; - for (int i = 0; i < subdivisions; i++) + for (int j = 0; j < SUBDIVISION_COUNT; j++) { - std::array point = + auto points = std::array { - center + Vector3(sin(currAngle) * abs(x), z, cos(currAngle) * abs(x)), - center + Vector3(cos(currAngle) * abs(x), sin(currAngle) * abs(x), z), - center + Vector3(z, sin(currAngle) * abs(x), cos(currAngle) * abs(x)) + center + Vector3(sin(angle) * abs(x), z, cos(angle) * abs(x)), + center + Vector3(cos(angle) * abs(x), sin(angle) * abs(x), z), + center + Vector3(z, sin(angle) * abs(x), cos(angle) * abs(x)) }; - if (i > 0) - for (int p = 0; p < 3; p++) - AddLine3D(prevPoint[p], point[p], color); + if (j > 0) + { + for (int k = 0; k < points.size(); k++) + AddLine3D(prevPoints[k], points[k], color); + } - prevPoint = point; - currAngle += ((PI * 2) / (subdivisions - 1)); + prevPoints = points; + angle += PI_MUL_2 / (SUBDIVISION_COUNT - 1); } } } - void Renderer11::AddDebugSphere(Vector3 center, float radius, Vector4 color, RENDERER_DEBUG_PAGE page) + void Renderer11::AddDebugSphere(const Vector3& center, float radius, const Vector4& color, RendererDebugPage page) { - if (!DebugMode || m_numDebugPage != page) + if (!DebugMode || DebugPage != page) return; AddSphere(center, radius, color); } - void Renderer11::AddBox(Vector3* corners, Vector4 color) + void Renderer11::AddBox(Vector3* corners, const Vector4& color) { if (m_Locked) return; @@ -877,7 +904,7 @@ namespace TEN::Renderer } } - void Renderer11::AddBox(Vector3 min, Vector3 max, Vector4 color) + void Renderer11::AddBox(const Vector3 min, const Vector3& max, const Vector4& color) { if (m_Locked) return; @@ -933,9 +960,9 @@ namespace TEN::Renderer } } - void Renderer11::AddDebugBox(BoundingOrientedBox box, Vector4 color, RENDERER_DEBUG_PAGE page) + void Renderer11::AddDebugBox(const BoundingOrientedBox& box, const Vector4& color, RendererDebugPage page) { - if (!DebugMode || m_numDebugPage != page) + if (!DebugMode || DebugPage != page) return; Vector3 corners[8]; @@ -943,10 +970,11 @@ namespace TEN::Renderer AddBox(corners, color); } - void Renderer11::AddDebugBox(Vector3 min, Vector3 max, Vector4 color, RENDERER_DEBUG_PAGE page) + void Renderer11::AddDebugBox(const Vector3& min, const Vector3& max, const Vector4& color, RendererDebugPage page) { - if (m_numDebugPage != page) + if (DebugPage != page) return; + AddBox(min, max, color); } @@ -1274,7 +1302,7 @@ namespace TEN::Renderer BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_animatedTextures[info->texture]), SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_animatedTextures[info->texture]), - SAMPLER_NONE); + SAMPLER_ANISOTROPIC_CLAMP); RendererAnimatedTextureSet& set = m_animatedTextureSets[info->texture]; m_stAnimated.NumFrames = set.NumTextures; @@ -1296,7 +1324,7 @@ namespace TEN::Renderer BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_roomTextures[info->texture]), SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_roomTextures[info->texture]), - SAMPLER_NONE); + SAMPLER_ANISOTROPIC_CLAMP); } SetBlendMode(info->blendMode); @@ -1344,9 +1372,9 @@ namespace TEN::Renderer // Set texture BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_staticsTextures[info->bucket->Texture]), - SAMPLER_ANISOTROPIC_CLAMP); + SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_staticsTextures[info->bucket->Texture]), - SAMPLER_NONE); + SAMPLER_ANISOTROPIC_CLAMP); if (resetPipeline) { @@ -1473,19 +1501,19 @@ namespace TEN::Renderer // Draw horizon and sky. DrawHorizonAndSky(view, m_renderTarget.DepthStencilView.Get()); - + // Draw opaque and alpha test faces. - DrawRooms(view, false); - DrawItems(view, false); - DrawStatics(view, false); - DrawEffects(view, false); + DrawRooms(view, RendererPass::Opaque); + DrawItems(view, RendererPass::Opaque); + DrawStatics(view, RendererPass::Opaque); + DrawEffects(view, RendererPass::Opaque); DrawGunShells(view); DrawBats(view); DrawRats(view); DrawSpiders(view); DrawScarabs(view); DrawLocusts(view); - DrawDebris(view, false); + DrawDebris(view, RendererPass::Opaque); m_context->OMSetRenderTargets(1, m_renderTarget.RenderTargetView.GetAddressOf(), m_renderTarget.DepthStencilView.Get()); @@ -1519,11 +1547,11 @@ namespace TEN::Renderer DrawLines3D(view); // Draw additive and unsorted blended faces, and collect all sorted blend modes faces for later. - DrawRooms(view, true); - DrawItems(view, true); - DrawStatics(view, true); - DrawEffects(view, true); - DrawDebris(view, true); + DrawRooms(view, RendererPass::Transparent); + DrawItems(view, RendererPass::Transparent); + DrawStatics(view, RendererPass::Transparent); + DrawEffects(view, RendererPass::Transparent); + DrawDebris(view, RendererPass::Transparent); DrawGunFlashes(view); DrawBaddyGunflashes(view); @@ -1552,7 +1580,7 @@ namespace TEN::Renderer } void Renderer11::RenderSimpleScene(ID3D11RenderTargetView* target, ID3D11DepthStencilView* depthTarget, - RenderView& view) + RenderView& view) { CollectRooms(view, true); // Draw shadow map @@ -1580,16 +1608,16 @@ namespace TEN::Renderer m_cbCameraMatrices.updateData(cameraConstantBuffer, m_context.Get()); BindConstantBufferVS(CB_CAMERA, m_cbCameraMatrices.get()); DrawHorizonAndSky(view, depthTarget); - DrawRooms(view, false); + DrawRooms(view, RendererPass::Opaque); } void Renderer11::DumpGameScene() { RenderScene(m_dumpScreenRenderTarget.RenderTargetView.Get(), m_dumpScreenRenderTarget.DepthStencilView.Get(), - gameCamera); + gameCamera); } - void Renderer11::DrawItems(RenderView& view, bool transparent) + void Renderer11::DrawItems(RenderView& view, RendererPass rendererPass) { UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -1610,7 +1638,7 @@ namespace TEN::Renderer switch (itemToDraw->ObjectNumber) { case ID_LARA: - DrawLara(view, transparent); + DrawLara(view, rendererPass); break; case ID_WATERFALL1: @@ -1621,11 +1649,11 @@ namespace TEN::Renderer case ID_WATERFALL6: case ID_WATERFALLSS1: case ID_WATERFALLSS2: - DrawWaterfalls(itemToDraw, view, 10, transparent); + DrawWaterfalls(itemToDraw, view, 10, rendererPass); continue; default: - DrawAnimatingItem(itemToDraw, view, transparent); + DrawAnimatingItem(itemToDraw, view, rendererPass); break; } } @@ -1644,7 +1672,7 @@ namespace TEN::Renderer } } - void Renderer11::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, bool transparent) + void Renderer11::DrawWaterfalls(RendererItem* item, RenderView& view, int fps, RendererPass rendererPass) { // Extremely hacky function to get first rendered face of a waterfall object mesh, calculate // its texture height and scroll all the textures according to that height. @@ -1681,14 +1709,14 @@ namespace TEN::Renderer m_cbAnimated.updateData(m_stAnimated, m_context.Get()); BindConstantBufferPS(CB_ANIMATED_TEXTURES, m_cbAnimated.get()); - DrawAnimatingItem(item, view, transparent); + DrawAnimatingItem(item, view, rendererPass); // Reset animated buffer after rendering just in case m_stAnimated.Fps = m_stAnimated.NumFrames = m_stAnimated.Type = 0; m_cbAnimated.updateData(m_stAnimated, m_context.Get()); } - void Renderer11::DrawAnimatingItem(RendererItem* item, RenderView& view, bool transparent) + void Renderer11::DrawAnimatingItem(RendererItem* item, RenderView& view, RendererPass rendererPass) { ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber]; RendererRoom* room = &m_rooms[item->RoomNumber]; @@ -1713,7 +1741,7 @@ namespace TEN::Renderer if (!(nativeItem->MeshBits & (1 << k))) continue; - DrawMoveableMesh(item, GetMesh(item->MeshIndex[k]), room, k, transparent); + DrawMoveableMesh(item, GetMesh(item->MeshIndex[k]), room, k, rendererPass); } } @@ -1752,9 +1780,9 @@ namespace TEN::Renderer // Set texture BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[info->bucket->Texture]), - SAMPLER_ANISOTROPIC_CLAMP); + SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[info->bucket->Texture]), - SAMPLER_NONE); + SAMPLER_ANISOTROPIC_CLAMP); SetBlendMode(info->blendMode); SetDepthState(DEPTH_STATE_READ_ONLY_ZBUFFER); @@ -1782,7 +1810,7 @@ namespace TEN::Renderer } } - void Renderer11::DrawStatics(RenderView& view, bool transparent) + void Renderer11::DrawStatics(RenderView& view, RendererPass rendererPass) { if (m_staticsTextures.size() == 0 || view.SortedStaticsToDraw.size() == 0) { @@ -1792,6 +1820,9 @@ namespace TEN::Renderer m_context->VSSetShader(m_vsInstancedStaticMeshes.Get(), NULL, 0); m_context->PSSetShader(m_psInstancedStaticMeshes.Get(), NULL, 0); + BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); + BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); + BindConstantBufferVS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get()); BindConstantBufferPS(CB_INSTANCED_STATICS, m_cbInstancedStaticMeshBuffer.get()); @@ -1809,7 +1840,7 @@ namespace TEN::Renderer std::vector statics = it->second; RendererStatic* refStatic = statics[0]; - RendererObject& refStaticObj = *m_staticObjects[refStatic->ObjectNumber]; + RendererObject& refStaticObj = *m_staticObjects[refStatic->ObjectNumber]; if (refStaticObj.ObjectMeshes.size() == 0) continue; @@ -1842,7 +1873,7 @@ namespace TEN::Renderer for (auto& bucket : refMesh->Buckets) { - if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent)) + if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent))) { continue; } @@ -1878,7 +1909,7 @@ namespace TEN::Renderer &std::get<0>(m_staticsTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, - &std::get<1>(m_staticsTextures[bucket.Texture]), SAMPLER_NONE); + &std::get<1>(m_staticsTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); DrawIndexedInstancedTriangles(bucket.NumIndices, instanceCount, bucket.StartIndex, 0); @@ -1890,7 +1921,7 @@ namespace TEN::Renderer } // Collect sorted blend modes faces ordered by room, if transparent pass - if (transparent) + if (rendererPass == RendererPass::Transparent) { Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z); @@ -1906,7 +1937,7 @@ namespace TEN::Renderer for (auto& bucket : mesh->Buckets) { - if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent)) + if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent))) { continue; } @@ -1950,7 +1981,7 @@ namespace TEN::Renderer } } - void Renderer11::DrawRooms(RenderView& view, bool transparent) + void Renderer11::DrawRooms(RenderView& view, RendererPass rendererPass) { UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -1973,7 +2004,7 @@ namespace TEN::Renderer int nmeshes = -Objects[ID_CAUSTICS_TEXTURES].nmeshes; int meshIndex = Objects[ID_CAUSTICS_TEXTURES].meshIndex; int causticsFrame = std::min(nmeshes ? meshIndex + ((GlobalCounter) % nmeshes) : meshIndex, (int)m_sprites.size()); - BindTexture(TEXTURE_CAUSTICS, m_sprites[causticsFrame].Texture, SAMPLER_NONE); + BindTexture(TEXTURE_CAUSTICS, m_sprites[causticsFrame].Texture, SAMPLER_ANISOTROPIC_CLAMP); // Strange packing due to particular HLSL 16 bytes alignment requirements RendererSprite* causticsSprite = &m_sprites[causticsFrame]; @@ -2037,7 +2068,7 @@ namespace TEN::Renderer continue; } - if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent)) + if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent))) { continue; } @@ -2097,10 +2128,10 @@ namespace TEN::Renderer if (animated) { BindTexture(TEXTURE_COLOR_MAP, - &std::get<0>(m_animatedTextures[bucket.Texture]), - SAMPLER_ANISOTROPIC_CLAMP); + &std::get<0>(m_animatedTextures[bucket.Texture]), + SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, - &std::get<1>(m_animatedTextures[bucket.Texture]), SAMPLER_NONE); + &std::get<1>(m_animatedTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); RendererAnimatedTextureSet& set = m_animatedTextureSets[bucket.Texture]; m_stAnimated.NumFrames = set.NumTextures; @@ -2125,9 +2156,9 @@ namespace TEN::Renderer else { BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_roomTextures[bucket.Texture]), - SAMPLER_ANISOTROPIC_CLAMP); + SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, - &std::get<1>(m_roomTextures[bucket.Texture]), SAMPLER_NONE); + &std::get<1>(m_roomTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); } DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0); @@ -2235,7 +2266,7 @@ namespace TEN::Renderer BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), - SAMPLER_NONE); + SAMPLER_ANISOTROPIC_CLAMP); // Always render horizon as alpha-blended surface SetBlendMode(bucket.BlendMode == BLEND_MODES::BLENDMODE_ALPHATEST ? BLEND_MODES::BLENDMODE_ALPHABLEND : bucket.BlendMode); @@ -2261,13 +2292,13 @@ namespace TEN::Renderer m_swapChain->Present(1, 0); } - void Renderer11::DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, bool transparent) + void Renderer11::DrawMoveableMesh(RendererItem* itemToDraw, RendererMesh* mesh, RendererRoom* room, int boneIndex, RendererPass rendererPass) { Vector3 cameraPosition = Vector3(Camera.pos.x, Camera.pos.y, Camera.pos.z); for (auto& bucket : mesh->Buckets) { - if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent)) + if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent))) { continue; } @@ -2277,7 +2308,16 @@ namespace TEN::Renderer continue; } - if (DoesBlendModeRequireSorting(bucket.BlendMode)) + if (rendererPass == RendererPass::ShadowMap) + { + SetBlendMode(BLENDMODE_OPAQUE); + SetAlphaTest(ALPHA_TEST_NONE, ALPHA_TEST_THRESHOLD); + + DrawIndexedTriangles(bucket.NumIndices, bucket.StartIndex, 0); + + m_numMoveablesDrawCalls++; + } + else if (DoesBlendModeRequireSorting(bucket.BlendMode)) { // Collect transparent faces for (int j = 0; j < bucket.Polygons.size(); j++) @@ -2308,9 +2348,9 @@ namespace TEN::Renderer int passes = bucket.BlendMode == BLENDMODE_ALPHATEST ? 2 : 1; BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), - SAMPLER_ANISOTROPIC_CLAMP); + SAMPLER_ANISOTROPIC_CLAMP); BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), - SAMPLER_NONE); + SAMPLER_ANISOTROPIC_CLAMP); for (int pass = 0; pass < passes; pass++) { diff --git a/TombEngine/Renderer/Renderer11Draw2D.cpp b/TombEngine/Renderer/Renderer11Draw2D.cpp index a836bb203..278fe7a82 100644 --- a/TombEngine/Renderer/Renderer11Draw2D.cpp +++ b/TombEngine/Renderer/Renderer11Draw2D.cpp @@ -349,7 +349,7 @@ namespace TEN::Renderer m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_context->IASetInputLayout(m_inputLayout.Get()); - m_stPostProcessBuffer.FXAA = g_Configuration.Antialiasing == AntialiasingMode::Low ? 1 : 0; + m_stPostProcessBuffer.FXAA = g_Configuration.AntialiasingMode == AntialiasingMode::Low ? 1 : 0; m_stPostProcessBuffer.ViewportWidth = m_screenWidth; m_stPostProcessBuffer.ViewportHeight = m_screenHeight; m_stPostProcessBuffer.ScreenFadeFactor = ScreenFadeCurrent; diff --git a/TombEngine/Renderer/Renderer11DrawEffect.cpp b/TombEngine/Renderer/Renderer11DrawEffect.cpp index d1b8e6c97..c5dda4031 100644 --- a/TombEngine/Renderer/Renderer11DrawEffect.cpp +++ b/TombEngine/Renderer/Renderer11DrawEffect.cpp @@ -49,7 +49,6 @@ extern FIRE_SPARKS FireSparks[MAX_SPARKS_FIRE]; extern SMOKE_SPARKS SmokeSparks[MAX_SPARKS_SMOKE]; extern SHOCKWAVE_STRUCT ShockWaves[MAX_SHOCKWAVE]; extern FIRE_LIST Fires[MAX_FIRE_LIST]; -extern GUNFLASH_STRUCT Gunflashes[MAX_GUNFLASH]; extern Particle Particles[MAX_PARTICLES]; extern SPLASH_STRUCT Splashes[MAX_SPLASHES]; @@ -832,6 +831,9 @@ namespace TEN::Renderer m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0); m_context->PSSetShader(m_psStatics.Get(), nullptr, 0); + BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); + BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); + UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -847,7 +849,7 @@ namespace TEN::Renderer return true; const auto& room = m_rooms[LaraItem->RoomNumber]; - auto* itemPtr = &m_items[Lara.ItemNumber]; + auto* itemPtr = &m_items[LaraItem->Index]; m_stStatic.Color = Vector4::One; m_stStatic.AmbientLight = room.AmbientLight; @@ -958,6 +960,9 @@ namespace TEN::Renderer m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0); m_context->PSSetShader(m_psStatics.Get(), nullptr, 0); + BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); + BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); + UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -1004,7 +1009,7 @@ namespace TEN::Renderer BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[flashBucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); - auto tMatrix = Matrix::CreateTranslation(creature.MuzzleFlash[0].Bite.Position.ToVector3()); + auto tMatrix = Matrix::CreateTranslation(creature.MuzzleFlash[0].Bite.Position); auto rotMatrixX = Matrix::CreateRotationX(TO_RAD(ANGLE(270.0f))); auto rotMatrixZ = Matrix::CreateRotationZ(TO_RAD(2 * GetRandomControl())); @@ -1043,15 +1048,15 @@ namespace TEN::Renderer BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[flashBucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); - auto tMatrix = Matrix::CreateTranslation(creature.MuzzleFlash[1].Bite.Position.ToVector3()); - auto rtoMatrixX = Matrix::CreateRotationX(TO_RAD(ANGLE(270.0f))); + auto tMatrix = Matrix::CreateTranslation(creature.MuzzleFlash[1].Bite.Position); + auto rotMatrixX = Matrix::CreateRotationX(TO_RAD(ANGLE(270.0f))); auto rotMatrixZ = Matrix::CreateRotationZ(TO_RAD(2 * GetRandomControl())); auto worldMatrix = rItemPtr->AnimationTransforms[creature.MuzzleFlash[1].Bite.BoneID] * rItemPtr->World; worldMatrix = tMatrix * worldMatrix; if (creature.MuzzleFlash[1].ApplyXRotation) - worldMatrix = rtoMatrixX * worldMatrix; + worldMatrix = rotMatrixX * worldMatrix; if (creature.MuzzleFlash[1].ApplyZRotation) worldMatrix = rotMatrixZ * worldMatrix; @@ -1214,7 +1219,7 @@ namespace TEN::Renderer currentSpriteBucket.SpritesToDraw.push_back(rDrawSprite); } } - + spriteBuckets.push_back(currentSpriteBucket); BindRenderTargetAsTexture(TEXTURE_DEPTH_MAP, &m_depthMap, SAMPLER_LINEAR_CLAMP); @@ -1391,7 +1396,7 @@ namespace TEN::Renderer SetCullMode(CULL_MODE_CCW); } - void Renderer11::DrawEffect(RenderView& view, RendererEffect* effect, bool transparent) + void Renderer11::DrawEffect(RenderView& view, RendererEffect* effect, RendererPass rendererPass) { const auto& room = m_rooms[effect->RoomNumber]; @@ -1404,7 +1409,7 @@ namespace TEN::Renderer BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); - if (transparent) + if (rendererPass == RendererPass::Transparent) { SetAlphaTest(ALPHA_TEST_NONE, 1.0f); } @@ -1421,11 +1426,11 @@ namespace TEN::Renderer if (bucket.NumVertices == 0) continue; - if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ transparent)) + if (!((bucket.BlendMode == BLENDMODE_OPAQUE || bucket.BlendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent))) continue; BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); SetBlendMode(lastBlendMode); @@ -1433,11 +1438,14 @@ namespace TEN::Renderer } } - void Renderer11::DrawEffects(RenderView& view, bool transparent) + void Renderer11::DrawEffects(RenderView& view, RendererPass rendererPass) { m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0); m_context->PSSetShader(m_psStatics.Get(), nullptr, 0); + BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); + BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); + UINT stride = sizeof(RendererVertex); UINT offset = 0; @@ -1454,16 +1462,20 @@ namespace TEN::Renderer const auto& object = Objects[effectPtr->ObjectNumber]; if (object.drawRoutine && object.loaded) - DrawEffect(view, effectPtr, transparent); + DrawEffect(view, effect, rendererPass); } } } - void Renderer11::DrawDebris(RenderView& view, bool transparent) + void Renderer11::DrawDebris(RenderView& view, RendererPass rendererPass) { m_context->VSSetShader(m_vsStatics.Get(), nullptr, 0); m_context->PSSetShader(m_psStatics.Get(), nullptr, 0); + BindConstantBufferVS(CB_STATIC, m_cbStatic.get()); + BindConstantBufferPS(CB_STATIC, m_cbStatic.get()); + + extern std::vector DebrisFragments; std::vector vertices; BLEND_MODES lastBlendMode = BLEND_MODES::BLENDMODE_UNSET; @@ -1472,7 +1484,7 @@ namespace TEN::Renderer { if (deb->active) { - if (!((deb->mesh.blendMode == BLENDMODE_OPAQUE || deb->mesh.blendMode == BLENDMODE_ALPHATEST) ^ transparent)) + if (!((deb->mesh.blendMode == BLENDMODE_OPAQUE || deb->mesh.blendMode == BLENDMODE_ALPHATEST) ^ (rendererPass == RendererPass::Transparent))) continue; Matrix translation = Matrix::CreateTranslation(deb->worldPosition.x, deb->worldPosition.y, deb->worldPosition.z); @@ -1490,7 +1502,7 @@ namespace TEN::Renderer BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[deb->mesh.tex]), SAMPLER_LINEAR_CLAMP); } - if (transparent) + if (rendererPass == RendererPass::Transparent) { SetAlphaTest(ALPHA_TEST_NONE, 1.0f); } diff --git a/TombEngine/Renderer/Renderer11DrawMenu.cpp b/TombEngine/Renderer/Renderer11DrawMenu.cpp index 904080351..e97339108 100644 --- a/TombEngine/Renderer/Renderer11DrawMenu.cpp +++ b/TombEngine/Renderer/Renderer11DrawMenu.cpp @@ -99,8 +99,13 @@ namespace TEN::Renderer void Renderer11::RenderOptionsMenu(Menu menu, int initialY) { + constexpr auto RIGHT_ARROW_X_OFFSET = SCREEN_SPACE_RES.x - MenuLeftSideEntry; + static const auto LEFT_ARROW_STRING = std::string("<"); + static const auto RIGHT_ARROW_STRING = std::string(">"); + static const auto CONTROL_SETTINGS_BLOCK_Y_OFFSET = (MenuVerticalNarrowLineSpacing * (int)QuickActionStrings.size()) + (MenuVerticalBlockSpacing * 2); + int y = 0; - auto title_option = g_Gui.GetSelectedOption(); + auto titleOption = g_Gui.GetSelectedOption(); char stringBuffer[32] = {}; auto screenResolution = g_Configuration.SupportedScreenResolutions[g_Gui.GetCurrentSettings().SelectedScreenResolution]; @@ -110,47 +115,45 @@ namespace TEN::Renderer (g_Gui.GetCurrentSettings().Configuration.ShadowType == ShadowMode::Lara ? STRING_SHADOWS_PLAYER : STRING_SHADOWS_ALL) : STRING_SHADOWS_NONE; const char* antialiasMode; - switch (g_Gui.GetCurrentSettings().Configuration.Antialiasing) + switch (g_Gui.GetCurrentSettings().Configuration.AntialiasingMode) { - default: - case AntialiasingMode::None: - antialiasMode = STRING_ANTIALIASING_NONE; - break; + default: + case AntialiasingMode::None: + antialiasMode = STRING_ANTIALIASING_NONE; + break; - case AntialiasingMode::Low: - antialiasMode = STRING_ANTIALIASING_LOW; - break; + case AntialiasingMode::Low: + antialiasMode = STRING_ANTIALIASING_LOW; + break; - case AntialiasingMode::Medium: - antialiasMode = STRING_ANTIALIASING_MEDIUM; - break; + case AntialiasingMode::Medium: + antialiasMode = STRING_ANTIALIASING_MEDIUM; + break; - case AntialiasingMode::High: - antialiasMode = STRING_ANTIALIASING_HIGH; - break; + case AntialiasingMode::High: + antialiasMode = STRING_ANTIALIASING_HIGH; + break; } switch (menu) { case Menu::Options: - // Setup needed parameters y = initialY; // Display - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_DISPLAY), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 0)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_DISPLAY), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 0)); GetNextLinePosition(&y); // Other options - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OTHER_SETTINGS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 1)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OTHER_SETTINGS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 1)); GetNextLinePosition(&y); // Controls - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 2)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 2)); break; case Menu::Display: - // Setup needed parameters y = MenuVerticalDisplaySettings; @@ -159,40 +162,39 @@ namespace TEN::Renderer GetNextBlockPosition(&y); // Screen resolution - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SCREEN_RESOLUTION), PRINTSTRING_COLOR_ORANGE, SF(title_option == 0)); - AddString(MenuRightSideEntry, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF(title_option == 0)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SCREEN_RESOLUTION), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 0)); + AddString(MenuRightSideEntry, y, stringBuffer, PRINTSTRING_COLOR_WHITE, SF(titleOption == 0)); GetNextLinePosition(&y); // Windowed mode - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_WINDOWED), PRINTSTRING_COLOR_ORANGE, SF(title_option == 1)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.Windowed), PRINTSTRING_COLOR_WHITE, SF(title_option == 1)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_WINDOWED), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 1)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableWindowedMode), PRINTSTRING_COLOR_WHITE, SF(titleOption == 1)); GetNextLinePosition(&y); // Enable dynamic shadows - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SHADOWS), PRINTSTRING_COLOR_ORANGE, SF(title_option == 2)); - AddString(MenuRightSideEntry, y, g_GameFlow->GetString(shadowMode), PRINTSTRING_COLOR_WHITE, SF(title_option == 2)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SHADOWS), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 2)); + AddString(MenuRightSideEntry, y, g_GameFlow->GetString(shadowMode), PRINTSTRING_COLOR_WHITE, SF(titleOption == 2)); GetNextLinePosition(&y); // Enable caustics - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_CAUSTICS), PRINTSTRING_COLOR_ORANGE, SF(title_option == 3)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableCaustics), PRINTSTRING_COLOR_WHITE, SF(title_option == 3)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_CAUSTICS), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 3)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableCaustics), PRINTSTRING_COLOR_WHITE, SF(titleOption == 3)); GetNextLinePosition(&y); // Enable antialiasing - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_ANTIALIASING), PRINTSTRING_COLOR_ORANGE, SF(title_option == 4)); - AddString(MenuRightSideEntry, y, g_GameFlow->GetString(antialiasMode), PRINTSTRING_COLOR_WHITE, SF(title_option == 4)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_ANTIALIASING), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4)); + AddString(MenuRightSideEntry, y, g_GameFlow->GetString(antialiasMode), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4)); GetNextBlockPosition(&y); // Apply - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 5)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 5)); GetNextLinePosition(&y); // Cancel - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 6)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 6)); break; case Menu::OtherSettings: - // Setup needed parameters y = MenuVerticalOtherSettings; @@ -201,8 +203,8 @@ namespace TEN::Renderer GetNextBlockPosition(&y); // Enable sound special effects - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_REVERB), PRINTSTRING_COLOR_ORANGE, SF(title_option == 0)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableReverb), PRINTSTRING_COLOR_WHITE, SF(title_option == 0)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_REVERB), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 0)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableReverb), PRINTSTRING_COLOR_WHITE, SF(titleOption == 0)); GetNextLinePosition(&y); // Initialize bars, if not yet done. Must be done here because we're calculating Y coord on the fly. @@ -210,23 +212,23 @@ namespace TEN::Renderer InitializeMenuBars(y); // Music volume - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MUSIC_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(title_option == 1)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_MUSIC_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 1)); DrawBar(g_Gui.GetCurrentSettings().Configuration.MusicVolume / 100.0f, *g_MusicVolumeBar, ID_SFX_BAR_TEXTURE, 0, false); GetNextLinePosition(&y); // Sound FX volume - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SFX_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(title_option == 2)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SFX_VOLUME), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 2)); DrawBar(g_Gui.GetCurrentSettings().Configuration.SfxVolume / 100.0f, *g_SFXVolumeBar, ID_SFX_BAR_TEXTURE, 0, false); GetNextBlockPosition(&y); // Subtitles - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SUBTITLES), PRINTSTRING_COLOR_ORANGE, SF(title_option == 3)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableSubtitles), PRINTSTRING_COLOR_WHITE, SF(title_option == 3)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_SUBTITLES), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 3)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableSubtitles), PRINTSTRING_COLOR_WHITE, SF(titleOption == 3)); GetNextLinePosition(&y); - // Automatic targeting - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTOMATIC_TARGETING), PRINTSTRING_COLOR_ORANGE, SF(title_option == 4)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAutoTargeting), PRINTSTRING_COLOR_WHITE, SF(title_option == 4)); + // Auto targeting + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_AUTO_TARGET), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 4)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableAutoTargeting), PRINTSTRING_COLOR_WHITE, SF(titleOption == 4)); GetNextLinePosition(&y); // Target highlighter @@ -235,69 +237,231 @@ namespace TEN::Renderer GetNextLinePosition(&y); // Vibration - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(title_option == 6)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(title_option == 6)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_RUMBLE), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 6)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableRumble), PRINTSTRING_COLOR_WHITE, SF(titleOption == 6)); GetNextLinePosition(&y); // Thumbstick camera - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(title_option == 7)); - AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCameraControl), PRINTSTRING_COLOR_WHITE, SF(title_option == 7)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(STRING_THUMBSTICK_CAMERA), PRINTSTRING_COLOR_ORANGE, SF(titleOption == 7)); + AddString(MenuRightSideEntry, y, Str_Enabled(g_Gui.GetCurrentSettings().Configuration.EnableThumbstickCamera), PRINTSTRING_COLOR_WHITE, SF(titleOption == 7)); GetNextBlockPosition(&y); // Apply - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 8)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 8)); GetNextLinePosition(&y); // Cancel - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 9)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == 9)); break; - case Menu::Controls: - - // Setup needed parameters - y = MenuVerticalTop; - - // Title - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS), PRINTSTRING_COLOR_YELLOW, SF_Center()); - GetNextBlockPosition(&y); - - // Control listing - for (int k = 0; k < KEY_COUNT; k++) + case Menu::GeneralActions: { - AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(ControlStrings[k]), PRINTSTRING_COLOR_WHITE, SF(title_option == k)); + // Set up needed parameters. + y = MenuVerticalTop; - if (g_Gui.GetCurrentSettings().WaitingForKey && title_option == k) - AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true)); - else + // Arrows + AddString(RIGHT_ARROW_X_OFFSET, y, RIGHT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true)); + + // Title + auto titleString = std::string(g_GameFlow->GetString(STRING_GENERAL_ACTIONS)); + AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center()); + GetNextBlockPosition(&y); + + // General action listing + for (int k = 0; k < GeneralActionStrings.size(); k++) { - int index = KeyboardLayout[1][k] ? KeyboardLayout[1][k] : KeyboardLayout[0][k]; - AddString(MenuRightSideEntry, y, (char*)g_KeyNames[index], PRINTSTRING_COLOR_ORANGE, SF(false)); + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(GeneralActionStrings[k].c_str()), PRINTSTRING_COLOR_WHITE, SF(titleOption == k)); + + if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k) + { + AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true)); + } + else + { + int index = Bindings[1][k] ? Bindings[1][k] : Bindings[0][k]; + AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false)); + } + + if (k < (GeneralActionStrings.size() - 1)) + GetNextNarrowLinePosition(&y); } - if (k < KEY_COUNT - 1) - GetNextNarrowLinePosition(&y); - else - GetNextBlockPosition(&y); + y = CONTROL_SETTINGS_BLOCK_Y_OFFSET; + + // Reset to defaults + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == GeneralActionStrings.size())); + GetNextLinePosition(&y); + + // Apply + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (GeneralActionStrings.size() + 1))); + GetNextLinePosition(&y); + + // Cancel + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (GeneralActionStrings.size() + 2))); + break; } - // Defaults - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 17)); - GetNextLinePosition(&y); + case Menu::VehicleActions: + { + // Set up needed parameters. + y = MenuVerticalTop; - // Apply - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 18)); - GetNextLinePosition(&y); + // Arrows + AddString(MenuLeftSideEntry, y, LEFT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true)); + AddString(RIGHT_ARROW_X_OFFSET, y, RIGHT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true)); - // Cancel - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(title_option == 19)); - break; + // Title + auto titleString = std::string(g_GameFlow->GetString(STRING_VEHICLE_ACTIONS)); + AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center()); + GetNextBlockPosition(&y); + + int baseIndex = KEY_ACCELERATE; + + // Vehicle action listing + for (int k = 0; k < VehicleActionStrings.size(); k++) + { + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(VehicleActionStrings[k].c_str()), PRINTSTRING_COLOR_WHITE, SF(titleOption == k)); + + if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k) + { + AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true)); + } + else + { + int index = Bindings[1][baseIndex + k] ? Bindings[1][baseIndex + k] : Bindings[0][baseIndex + k]; + AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false)); + } + + if (k < (VehicleActionStrings.size() - 1)) + { + GetNextNarrowLinePosition(&y); + } + else + { + GetNextBlockPosition(&y); + } + } + + y = CONTROL_SETTINGS_BLOCK_Y_OFFSET; + + // Reset to defaults + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == VehicleActionStrings.size())); + GetNextLinePosition(&y); + + // Apply + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (VehicleActionStrings.size() + 1))); + GetNextLinePosition(&y); + + // Cancel + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (VehicleActionStrings.size() + 2))); + break; + } + + case Menu::QuickActions: + { + // Set up needed parameters. + y = MenuVerticalTop; + + // Arrows + AddString(MenuLeftSideEntry, y, LEFT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true)); + AddString(RIGHT_ARROW_X_OFFSET, y, RIGHT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true)); + + // Title + auto titleString = std::string(g_GameFlow->GetString(STRING_QUICK_ACTIONS)); + AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center()); + GetNextBlockPosition(&y); + + int baseIndex = KEY_FLARE; + + // Quick action listing + for (int k = 0; k < QuickActionStrings.size(); k++) + { + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(QuickActionStrings[k].c_str()), PRINTSTRING_COLOR_WHITE, SF(titleOption == k)); + + if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k) + { + AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true)); + } + else + { + int index = Bindings[1][baseIndex + k] ? Bindings[1][baseIndex + k] : Bindings[0][baseIndex + k]; + AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false)); + } + + if (k < (QuickActionStrings.size() - 1)) + GetNextNarrowLinePosition(&y); + } + + y = CONTROL_SETTINGS_BLOCK_Y_OFFSET; + + // Reset to defaults + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == QuickActionStrings.size())); + GetNextLinePosition(&y); + + // Apply + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (QuickActionStrings.size() + 1))); + GetNextLinePosition(&y); + + // Cancel + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (QuickActionStrings.size() + 2))); + break; + } + + case Menu::MenuActions: + { + // Setup needed parameters. + y = MenuVerticalTop; + + // Arrows + AddString(MenuLeftSideEntry, y, LEFT_ARROW_STRING.c_str(), PRINTSTRING_COLOR_YELLOW, SF(true)); + + // Title + auto titleString = std::string(g_GameFlow->GetString(STRING_MENU_ACTIONS)); + AddString(MenuCenterEntry, y, titleString.c_str(), PRINTSTRING_COLOR_YELLOW, SF_Center()); + GetNextBlockPosition(&y); + + int baseIndex = KEY_SELECT; + + // Menu action listing. + for (int k = 0; k < MenuActionStrings.size(); k++) + { + AddString(MenuLeftSideEntry, y, g_GameFlow->GetString(MenuActionStrings[k].c_str()), PRINTSTRING_COLOR_WHITE, SF(titleOption == k)); + + if (g_Gui.GetCurrentSettings().WaitingForKey && titleOption == k) + { + AddString(MenuRightSideEntry, y, g_GameFlow->GetString(STRING_WAITING_FOR_INPUT), PRINTSTRING_COLOR_YELLOW, SF(true)); + } + else + { + int index = Bindings[1][baseIndex + k] ? Bindings[1][baseIndex + k] : Bindings[0][baseIndex + k]; + AddString(MenuRightSideEntry, y, g_KeyNames[index].c_str(), PRINTSTRING_COLOR_ORANGE, SF(false)); + } + + if (k < (MenuActionStrings.size() - 1)) + GetNextNarrowLinePosition(&y); + } + + y = CONTROL_SETTINGS_BLOCK_Y_OFFSET; + + // Reset to defaults + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_RESET_TO_DEFAULTS), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == MenuActionStrings.size())); + GetNextLinePosition(&y); + + // Apply + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_APPLY), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (MenuActionStrings.size() + 1))); + GetNextLinePosition(&y); + + // Cancel + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CANCEL), PRINTSTRING_COLOR_ORANGE, SF_Center(titleOption == (MenuActionStrings.size() + 2))); + break; + } } } void Renderer11::RenderTitleMenu(Menu menu) { int y = MenuVerticalBottomCenter; - auto title_option = g_Gui.GetSelectedOption(); + auto titleOption = g_Gui.GetSelectedOption(); // HACK: Check if it works properly -- Lwmte, 07.06.22 if (menu == Menu::LoadGame && !g_GameFlow->EnableLoadSave) @@ -308,19 +472,19 @@ namespace TEN::Renderer case Menu::Title: // New game - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 0)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_NEW_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 0)); GetNextLinePosition(&y); // Load game - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 1)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_LOAD_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 1)); GetNextLinePosition(&y); // Options - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 2)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 2)); GetNextLinePosition(&y); // Exit game - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(title_option == 3)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_GAME), PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == 3)); break; case Menu::LoadGame: @@ -340,13 +504,16 @@ namespace TEN::Renderer for (int i = 1; i < g_GameFlow->GetNumLevels(); i++) { AddString(MenuCenterEntry, y, g_GameFlow->GetString(g_GameFlow->GetLevel(i)->NameStringKey.c_str()), - PRINTSTRING_COLOR_WHITE, SF_Center(title_option == i - 1)); + PRINTSTRING_COLOR_WHITE, SF_Center(titleOption == i - 1)); GetNextNarrowLinePosition(&y); } break; case Menu::Options: - case Menu::Controls: + case Menu::GeneralActions: + case Menu::VehicleActions: + case Menu::QuickActions: + case Menu::MenuActions: case Menu::Display: case Menu::OtherSettings: RenderOptionsMenu(menu, MenuVerticalOptionsTitle); @@ -357,7 +524,7 @@ namespace TEN::Renderer void Renderer11::RenderPauseMenu(Menu menu) { int y = 0; - auto pause_option = g_Gui.GetSelectedOption(); + auto pauseOption = g_Gui.GetSelectedOption(); switch (g_Gui.GetMenuToDisplay()) { @@ -367,19 +534,19 @@ namespace TEN::Renderer y = MenuVerticalPause; // Header - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_CONTROLS_PAUSE), PRINTSTRING_COLOR_ORANGE, SF_Center()); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_ACTIONS_PAUSE), PRINTSTRING_COLOR_ORANGE, SF_Center()); GetNextBlockPosition(&y); // Statistics - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_STATISTICS), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 0)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_STATISTICS), PRINTSTRING_COLOR_WHITE, SF_Center(pauseOption == 0)); GetNextLinePosition(&y); // Options - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 1)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_OPTIONS), PRINTSTRING_COLOR_WHITE, SF_Center(pauseOption == 1)); GetNextLinePosition(&y); // Exit to title - AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_TO_TITLE), PRINTSTRING_COLOR_WHITE, SF_Center(pause_option == 2)); + AddString(MenuCenterEntry, y, g_GameFlow->GetString(STRING_EXIT_TO_TITLE), PRINTSTRING_COLOR_WHITE, SF_Center(pauseOption == 2)); break; case Menu::Statistics: @@ -387,7 +554,10 @@ namespace TEN::Renderer break; case Menu::Options: - case Menu::Controls: + case Menu::GeneralActions: + case Menu::VehicleActions: + case Menu::QuickActions: + case Menu::MenuActions: case Menu::Display: case Menu::OtherSettings: RenderOptionsMenu(menu, MenuVerticalOptionsPause); @@ -509,10 +679,10 @@ namespace TEN::Renderer void Renderer11::RenderNewInventory() { - g_Gui.DrawCurrentObjectList(LaraItem, (int)RingTypes::Inventory); + g_Gui.DrawCurrentObjectList(LaraItem, RingTypes::Inventory); - if (g_Gui.GetRings((int)RingTypes::Ammo)->RingActive) - g_Gui.DrawCurrentObjectList(LaraItem, (int)RingTypes::Ammo); + if (g_Gui.GetRing(RingTypes::Ammo).RingActive) + g_Gui.DrawCurrentObjectList(LaraItem, RingTypes::Ammo); g_Gui.DrawAmmoSelector(); g_Gui.FadeAmmoSelector(); @@ -645,7 +815,7 @@ namespace TEN::Renderer SetDepthState(DEPTH_STATE_WRITE_ZBUFFER); BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_NONE); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[bucket.Texture]), SAMPLER_ANISOTROPIC_CLAMP); if (bucket.BlendMode != BLENDMODE_OPAQUE) Renderer11::SetBlendMode(bucket.BlendMode, true); @@ -699,7 +869,7 @@ namespace TEN::Renderer static EulerAngles orient = EulerAngles::Zero; static float scaler = 1.2f; - short invItem = g_Gui.GetRings((int)RingTypes::Inventory)->CurrentObjectList[g_Gui.GetRings((int)RingTypes::Inventory)->CurrentObjectInList].InventoryItem; + short invItem = g_Gui.GetRing(RingTypes::Inventory).CurrentObjectList[g_Gui.GetRing(RingTypes::Inventory).CurrentObjectInList].InventoryItem; auto& object = InventoryObjectTable[invItem]; @@ -788,7 +958,7 @@ namespace TEN::Renderer // Set texture BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP); if (CurrentLevel == 0) { @@ -920,12 +1090,12 @@ namespace TEN::Renderer ROOM_INFO* r = &g_Level.Rooms[LaraItem->RoomNumber]; - switch (m_numDebugPage) + switch (DebugPage) { - case RENDERER_DEBUG_PAGE::NO_PAGE: + case RendererDebugPage::None: break; - case RENDERER_DEBUG_PAGE::RENDERER_STATS: + case RendererDebugPage::RendererStats: PrintDebugMessage("RENDERER STATS"); PrintDebugMessage("FPS: %3.2f", m_fps); PrintDebugMessage("Resolution: %d x %d", m_screenWidth, m_screenHeight); @@ -941,7 +1111,7 @@ namespace TEN::Renderer PrintDebugMessage(" Sprites: %d", m_numSpritesDrawCalls); PrintDebugMessage("Triangles: %d", m_numPolygons); PrintDebugMessage("Sprites: %d", view.SpritesToDraw.size()); - PrintDebugMessage("Transparent faces draw calls: %d", m_numTransparentDrawCalls); + PrintDebugMessage("Transparent face draw calls: %d", m_numTransparentDrawCalls); PrintDebugMessage(" Rooms: %d", m_numRoomsTransparentDrawCalls); PrintDebugMessage(" Movables: %d", m_numMoveablesTransparentDrawCalls); PrintDebugMessage(" Statics: %d", m_numStaticsTransparentDrawCalls); @@ -955,7 +1125,7 @@ namespace TEN::Renderer break; - case RENDERER_DEBUG_PAGE::DIMENSION_STATS: + case RendererDebugPage::DimensionStats: PrintDebugMessage("DIMENSION STATS"); PrintDebugMessage("Pos: %d %d %d", LaraItem->Pose.Position.x, LaraItem->Pose.Position.y, LaraItem->Pose.Position.z); PrintDebugMessage("Orient: %d %d %d", LaraItem->Pose.Orientation.x, LaraItem->Pose.Orientation.y, LaraItem->Pose.Orientation.z); @@ -967,12 +1137,12 @@ namespace TEN::Renderer PrintDebugMessage("Room.y, minFloor, maxCeiling: %d %d %d ", r->y, r->minfloor, r->maxceiling); PrintDebugMessage("Camera.pos: %d %d %d", Camera.pos.x, Camera.pos.y, Camera.pos.z); PrintDebugMessage("Camera.target: %d %d %d", Camera.target.x, Camera.target.y, Camera.target.z); - PrintDebugMessage("Camera.roomNumber: %d", Camera.pos.RoomNumber); + PrintDebugMessage("Camera.RoomNumber: %d", Camera.pos.RoomNumber); break; - case RENDERER_DEBUG_PAGE::LARA_STATS: + case RendererDebugPage::PlayerStats: PrintDebugMessage("PLAYER STATS"); - PrintDebugMessage("Anim ObjectID: %d", LaraItem->Animation.AnimObjectID); + PrintDebugMessage("AnimObjectID: %d", LaraItem->Animation.AnimObjectID); PrintDebugMessage("AnimNumber: %d", LaraItem->Animation.AnimNumber); PrintDebugMessage("FrameNumber: %d", LaraItem->Animation.FrameNumber); PrintDebugMessage("ActiveState: %d", LaraItem->Animation.ActiveState); @@ -982,9 +1152,10 @@ namespace TEN::Renderer PrintDebugMessage("HandStatus: %d", Lara.Control.HandStatus); PrintDebugMessage("WaterStatus: %d", Lara.Control.WaterStatus); PrintDebugMessage("CanClimbLadder: %d", Lara.Control.CanClimbLadder); + PrintDebugMessage("CanMonkeySwing: %d", Lara.Control.CanMonkeySwing); break; - case RENDERER_DEBUG_PAGE::LOGIC_STATS: + case RendererDebugPage::LogicStats: PrintDebugMessage("LOGIC STATS"); PrintDebugMessage("Target HitPoints: %d", Lara.TargetEntity ? Lara.TargetEntity->HitPoints : 0); PrintDebugMessage("Move axis vertical: %f", AxisMap[InputAxis::MoveVertical]); @@ -993,26 +1164,47 @@ namespace TEN::Renderer PrintDebugMessage("Look axis horizontal: %f", AxisMap[InputAxis::CameraHorizontal]); break; + case RendererDebugPage::CollisionStats: + PrintDebugMessage("COLLISION STATS"); + PrintDebugMessage("Collision type: %d", LaraCollision.CollisionType); + PrintDebugMessage("Bridge item ID: %d", LaraCollision.Middle.Bridge); + PrintDebugMessage("Front floor: %d", LaraCollision.Front.Floor); + PrintDebugMessage("Front left floor: %d", LaraCollision.FrontLeft.Floor); + PrintDebugMessage("Front right floor: %d", LaraCollision.FrontRight.Floor); + PrintDebugMessage("Front ceil: %d", LaraCollision.Front.Ceiling); + PrintDebugMessage("Front left ceil: %d", LaraCollision.FrontLeft.Ceiling); + PrintDebugMessage("Front right ceil: %d", LaraCollision.FrontRight.Ceiling); + break; + + case RendererDebugPage::PathfindingStats: + PrintDebugMessage("PATHFINDING STATS"); + PrintDebugMessage("BoxNumber: %d", LaraItem->BoxNumber); + break; + + case RendererDebugPage::WireframeMode: + PrintDebugMessage("WIREFRAME MODE"); + break; + default: break; } } } - void Renderer11::SwitchDebugPage(bool back) + void Renderer11::SwitchDebugPage(bool goBack) { - auto index = (int)m_numDebugPage; + int page = (int)DebugPage; + goBack ? --page : ++page; - if (back) - --index; - else - ++index; + if (page < (int)RendererDebugPage::None) + { + page = (int)RendererDebugPage::Count - 1; + } + else if (page > (int)RendererDebugPage::WireframeMode) + { + page = (int)RendererDebugPage::None; + } - if (index < RENDERER_DEBUG_PAGE::NO_PAGE) - index = RENDERER_DEBUG_PAGE::WIREFRAME_MODE; - else if (index > RENDERER_DEBUG_PAGE::WIREFRAME_MODE) - index = 0; - - m_numDebugPage = (RENDERER_DEBUG_PAGE)index; + DebugPage = (RendererDebugPage)page; } } diff --git a/TombEngine/Renderer/Renderer11Enums.h b/TombEngine/Renderer/Renderer11Enums.h index 0b8226311..ac8c582ed 100644 --- a/TombEngine/Renderer/Renderer11Enums.h +++ b/TombEngine/Renderer/Renderer11Enums.h @@ -113,14 +113,18 @@ enum RENDERER_FADE_STATUS FADE_OUT }; -enum RENDERER_DEBUG_PAGE +enum class RendererDebugPage { - NO_PAGE, - RENDERER_STATS, - DIMENSION_STATS, - LARA_STATS, - LOGIC_STATS, - WIREFRAME_MODE + None, + RendererStats, + DimensionStats, + PlayerStats, + LogicStats, + CollisionStats, + PathfindingStats, + WireframeMode, + + Count }; enum RendererTransparentFaceType @@ -189,6 +193,13 @@ enum ALPHA_TEST_MODES ALPHA_TEST_LESS_THAN = 2 }; +enum RendererPass +{ + ShadowMap, + Opaque, + Transparent +}; + constexpr auto TEXTURE_HEIGHT = 256; constexpr auto TEXTURE_WIDTH = 256; constexpr auto TEXTURE_PAGE = (TEXTURE_HEIGHT * TEXTURE_WIDTH); @@ -228,8 +239,8 @@ constexpr auto MAX_LIGHTS = 100; constexpr auto AMBIENT_LIGHT_INTERPOLATION_STEP = 1.0f / 10.0f; constexpr auto MAX_DYNAMIC_SHADOWS = 1; constexpr auto MAX_DYNAMIC_LIGHTS = 1024; -constexpr auto ITEM_LIGHT_COLLECTION_RADIUS = SECTOR(1); -constexpr auto CAMERA_LIGHT_COLLECTION_RADIUS = SECTOR(4); +constexpr auto ITEM_LIGHT_COLLECTION_RADIUS = BLOCK(1); +constexpr auto CAMERA_LIGHT_COLLECTION_RADIUS = BLOCK(4); constexpr auto MAX_TRANSPARENT_FACES = 16384; constexpr auto MAX_TRANSPARENT_VERTICES = (MAX_TRANSPARENT_FACES * 6); diff --git a/TombEngine/Renderer/Renderer11Frame.cpp b/TombEngine/Renderer/Renderer11Frame.cpp index e66dcd9b8..f0a6add7d 100644 --- a/TombEngine/Renderer/Renderer11Frame.cpp +++ b/TombEngine/Renderer/Renderer11Frame.cpp @@ -23,6 +23,8 @@ namespace TEN::Renderer void Renderer11::CollectRooms(RenderView& renderView, bool onlyRooms) { + m_visitedRoomsStack.clear(); + for (int i = 0; i < g_Level.Rooms.size(); i++) { RendererRoom* room = &m_rooms[i]; @@ -47,7 +49,7 @@ namespace TEN::Renderer m_invalidateCache = false; - // Prepae the real DX scissor test rectangle + // Prepare the real DX scissor test rectangle for (auto room : renderView.RoomsToDraw) { room->ClipBounds.left = (room->ViewPort.x + 1.0f) * m_screenWidth * 0.5f; @@ -216,6 +218,18 @@ namespace TEN::Renderer // See https://github.com/MontyTRC89/TombEngine/issues/947 for details. // NOTE by MontyTRC: I'd keep this as a failsafe solution for 0.00000001% of cases we could have problems + int stackSize = (int)m_visitedRoomsStack.size(); + int stackMinIndex = std::max(0, int(stackSize - 5)); + + for (int i = stackSize - 1; i >= stackMinIndex; i--) + { + if (m_visitedRoomsStack[i] == to) + { + TENLog("Circle detected! Room " + std::to_string(to), LogLevel::Warning, LogConfig::Debug); + return; + } + } + static constexpr int MAX_SEARCH_DEPTH = 64; if (m_rooms[to].Visited && count > MAX_SEARCH_DEPTH) { @@ -224,6 +238,8 @@ namespace TEN::Renderer return; } + m_visitedRoomsStack.push_back(to); + m_numGetVisibleRoomsCalls++; RendererRoom* room = &m_rooms[to]; @@ -287,10 +303,10 @@ namespace TEN::Renderer } if (from != door->RoomNumber && CheckPortal(to, door, viewPort, &clipPort, renderView)) - { GetVisibleRooms(to, door->RoomNumber, clipPort, water, count + 1, onlyRooms, renderView); - } } + + m_visitedRoomsStack.pop_back(); } void Renderer11::CollectItems(short roomNumber, RenderView& renderView) @@ -426,7 +442,7 @@ namespace TEN::Renderer continue; } - auto length = Vector3(mesh->VisibilityBox.Extents).Length(); + auto length = Vector3(mesh->VisibilityBox.Extents).Length() * mesh->Scale; if (!renderView.Camera.Frustum.SphereInFrustum(mesh->VisibilityBox.Center, length)) { continue; @@ -489,7 +505,7 @@ namespace TEN::Renderer SQUARE(position.z - light.Position.z); // Collect only lights nearer than 20 sectors - if (distanceSquared >= SQUARE(SECTOR(20))) + if (distanceSquared >= SQUARE(BLOCK(20))) { continue; } @@ -543,7 +559,7 @@ namespace TEN::Renderer SQUARE(position.z - light->Position.z); // Collect only lights nearer than 20 sectors - if (distanceSquared >= SQUARE(SECTOR(20))) + if (distanceSquared >= SQUARE(BLOCK(20))) { continue; } @@ -579,7 +595,7 @@ namespace TEN::Renderer SQUARE(position.z - light->Position.z); // Collect only lights nearer than 20 sectors - if (distanceSquared >= SQUARE(SECTOR(20))) + if (distanceSquared >= SQUARE(BLOCK(20))) { continue; } diff --git a/TombEngine/Renderer/Renderer11Helper.cpp b/TombEngine/Renderer/Renderer11Helper.cpp index c176b7acc..43c71cffb 100644 --- a/TombEngine/Renderer/Renderer11Helper.cpp +++ b/TombEngine/Renderer/Renderer11Helper.cpp @@ -1,6 +1,10 @@ #include "framework.h" #include +#include +#include +#include +#include #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" #include "Game/animation.h" @@ -358,7 +362,7 @@ namespace TEN::Renderer farView = DEFAULT_FAR_VIEW; m_farView = farView; - gameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.Width, g_Configuration.Height); + gameCamera = RenderView(cam, roll, fov, 32, farView, g_Configuration.ScreenWidth, g_Configuration.ScreenHeight); } bool Renderer11::SphereBoxIntersection(BoundingBox box, Vector3 sphereCentre, float sphereRadius) @@ -416,18 +420,25 @@ namespace TEN::Renderer if (!itemToDraw->DoneAnimations) { - if (itemNumber == Lara.ItemNumber) + if (itemNumber == LaraItem->Index) + { UpdateLaraAnimations(false); + } else + { UpdateItemAnimations(itemNumber, false); + } } - Matrix world; - + auto world = Matrix::Identity; if (worldSpace & SPHERES_SPACE_WORLD) + { world = Matrix::CreateTranslation(nativeItem->Pose.Position.x, nativeItem->Pose.Position.y, nativeItem->Pose.Position.z) * local; + } else + { world = Matrix::Identity * local; + } world = nativeItem->Pose.Orientation.ToRotationMatrix() * world; @@ -455,7 +466,7 @@ namespace TEN::Renderer void Renderer11::GetBoneMatrix(short itemNumber, int jointIndex, Matrix* outMatrix) { - if (itemNumber == Lara.ItemNumber) + if (itemNumber == LaraItem->Index) { auto& object = *m_moveableObjects[ID_LARA]; *outMatrix = object.AnimationTransforms[jointIndex] * m_LaraWorldMatrix; @@ -549,7 +560,7 @@ namespace TEN::Renderer if (!rendererItem->DoneAnimations) { - if (itemNumber == Lara.ItemNumber) + if (itemNumber == LaraItem->Index) UpdateLaraAnimations(false); else UpdateItemAnimations(itemNumber, false); @@ -561,4 +572,23 @@ namespace TEN::Renderer auto world = rendererItem->AnimationTransforms[jointIndex] * rendererItem->World; return Vector3::Transform(relOffset, world); } + + void Renderer11::SaveScreenshot() + { + char buffer[64]; + time_t rawtime; + + time(&rawtime); + auto time = localtime(&rawtime); + strftime(buffer, sizeof(buffer), "/TEN-%d-%m-%Y-%H-%M-%S.png", time); + + auto screenPath = g_GameFlow->GetGameDir() + "Screenshots"; + + if (!std::filesystem::is_directory(screenPath)) + std::filesystem::create_directory(screenPath); + + screenPath += buffer; + SaveWICTextureToFile(m_context.Get(), m_backBufferTexture, GUID_ContainerFormatPng, TEN::Utils::ToWString(screenPath).c_str(), + &GUID_WICPixelFormat24bppBGR, nullptr, true); + } } diff --git a/TombEngine/Renderer/Renderer11Init.cpp b/TombEngine/Renderer/Renderer11Init.cpp index 07fa18b4c..c1924023a 100644 --- a/TombEngine/Renderer/Renderer11Init.cpp +++ b/TombEngine/Renderer/Renderer11Init.cpp @@ -38,27 +38,28 @@ void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND han // Load shaders ComPtr blob; const D3D_SHADER_MACRO roomDefinesAnimated[] = { "ANIMATED", "", nullptr, nullptr }; - - m_vsRooms = Utils::compileVertexShader(m_device.Get(),GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "VS", "vs_4_0", nullptr, blob); + const D3D_SHADER_MACRO roomDefinesShadowMap[] = { "SHADOW_MAP", "", nullptr, nullptr }; - // Initialize input layout using the first vertex shader + m_vsRooms = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "VS", "vs_4_0", nullptr, blob); + + // Initialize input layout using first vertex shader. D3D11_INPUT_ELEMENT_DESC inputLayout[] = { - {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"ANIMATIONFRAMEOFFSET", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"EFFECTS", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"POLYINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"DRAWINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"HASH", 0, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0} + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "NORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TANGENT", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "BINORMAL", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "ANIMATIONFRAMEOFFSET", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "EFFECTS", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "BLENDINDICES", 0, DXGI_FORMAT_R32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "POLYINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "DRAWINDEX", 0, DXGI_FORMAT_R32_UINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "HASH", 0, DXGI_FORMAT_R32_SINT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 } }; - Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 11, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout)); + Utils::throwIfFailed(m_device->CreateInputLayout(inputLayout, 12, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayout)); - // TODO: If shader loading moves to a less hardcoded system we should take the opportunity to apply GetAssetPath more gracefully - squidshire 13/05/2023 m_vsRooms_Anim = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "VS", "vs_4_0", &roomDefinesAnimated[0], blob); m_psRooms = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Rooms.fx"), "PS", "ps_4_1", nullptr, blob); m_vsItems = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_Items.fx"), "VS", "vs_4_0", nullptr, blob); @@ -89,20 +90,7 @@ void TEN::Renderer::Renderer11::Initialize(int w, int h, bool windowed, HWND han m_psInstancedStaticMeshes = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedStatics.fx"), "PS", "ps_4_0", nullptr, blob); m_vsInstancedSprites = Utils::compileVertexShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedSprites.fx"), "VS", "vs_4_0", nullptr, blob); m_psInstancedSprites = Utils::compilePixelShader(m_device.Get(), GetAssetPath(L"Shaders\\DX11_InstancedSprites.fx"), "PS", "ps_4_0", nullptr, blob); - - // Initialize input layout using the first vertex - /*D3D11_INPUT_ELEMENT_DESC inputLayoutSprites[] = - { - {"POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0}, - {"WORLD", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1} - {"WORLD", 1, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, - {"WORLD", 2, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, - {"WORLD", 3, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1}, - {"COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_INSTANCE_DATA, 1} - }; - Utils::throwIfFailed(m_device->CreateInputLayout(inputLayoutSprites, 11, blob->GetBufferPointer(), blob->GetBufferSize(), &m_inputLayoutSprites));*/ - + // Initialize constant buffers m_cbCameraMatrices = CreateConstantBuffer(); m_cbItem = CreateConstantBuffer(); @@ -378,7 +366,7 @@ void TEN::Renderer::Renderer11::InitializeScreen(int w, int h, HWND handle, bool m_dumpScreenRenderTarget = RenderTarget2D(m_device.Get(), w, h, DXGI_FORMAT_R8G8B8A8_UNORM); m_depthMap = RenderTarget2D(m_device.Get(), w, h, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D16_UNORM); m_reflectionCubemap = RenderTargetCube(m_device.Get(), 128, DXGI_FORMAT_R8G8B8A8_UNORM_SRGB); - m_shadowMap = Texture2DArray(m_device.Get(), g_Configuration.ShadowMapSize, 6, DXGI_FORMAT_R16_UNORM, DXGI_FORMAT_D16_UNORM); + m_shadowMap = Texture2DArray(m_device.Get(), g_Configuration.ShadowMapSize, 6, DXGI_FORMAT_R32_FLOAT, DXGI_FORMAT_D16_UNORM); // Initialize viewport m_viewport.TopLeftX = 0; diff --git a/TombEngine/Renderer/Renderer11Lara.cpp b/TombEngine/Renderer/Renderer11Lara.cpp index 1493980b9..a38318744 100644 --- a/TombEngine/Renderer/Renderer11Lara.cpp +++ b/TombEngine/Renderer/Renderer11Lara.cpp @@ -79,8 +79,8 @@ bool shouldAnimateUpperBody(const LaraWeaponType& weapon) void Renderer11::UpdateLaraAnimations(bool force) { - auto& rItem = m_items[Lara.ItemNumber]; - rItem.ItemNumber = Lara.ItemNumber; + auto& rItem = m_items[LaraItem->Index]; + rItem.ItemNumber = LaraItem->Index; if (!force && rItem.DoneAnimations) return; @@ -275,7 +275,7 @@ void Renderer11::UpdateLaraAnimations(bool force) rItem.DoneAnimations = true; } -void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent) +void TEN::Renderer::Renderer11::DrawLara(RenderView& view, RendererPass rendererPass) { // Don't draw Lara if binoculars or sniper if (BinocularRange || SpotcamDontDrawLara) @@ -285,14 +285,14 @@ void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent) if (CurrentLevel == 0 && !g_GameFlow->IsLaraInTitleEnabled()) return; - RendererItem* item = &m_items[Lara.ItemNumber]; - ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber]; + auto* item = &m_items[LaraItem->Index]; + auto* nativeItem = &g_Level.Items[item->ItemNumber]; if (nativeItem->Flags & IFLAG_INVISIBLE) return; - UINT stride = sizeof(RendererVertex); - UINT offset = 0; + unsigned int stride = sizeof(RendererVertex); + unsigned int offset = 0; m_context->IASetVertexBuffers(0, 1, m_moveablesVertexBuffer.Buffer.GetAddressOf(), &stride, &offset); m_context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); @@ -303,8 +303,8 @@ void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent) m_context->PSSetShader(m_psItems.Get(), nullptr, 0); // Set texture - BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]), SAMPLER_LINEAR_CLAMP); - BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_NONE); + BindTexture(TEXTURE_COLOR_MAP, &std::get<0>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP); + BindTexture(TEXTURE_NORMAL_MAP, &std::get<1>(m_moveablesTextures[0]), SAMPLER_ANISOTROPIC_CLAMP); SetAlphaTest(ALPHA_TEST_GREATER_THAN, ALPHA_TEST_THRESHOLD); @@ -331,15 +331,15 @@ void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent) if (!nativeItem->MeshBits.Test(k)) continue; - DrawMoveableMesh(item, GetMesh(nativeItem->Model.MeshIndex[k]), room, k, transparent); + DrawMoveableMesh(item, GetMesh(nativeItem->Model.MeshIndex[k]), room, k, rendererPass); } - DrawLaraHolsters(item, room, transparent); - DrawLaraJoints(item, room, transparent); - DrawLaraHair(item, room, transparent); + DrawLaraHolsters(item, room, rendererPass); + DrawLaraJoints(item, room, rendererPass); + DrawLaraHair(item, room, rendererPass); } -void Renderer11::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, bool transparent) +void Renderer11::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, RendererPass rendererPass) { if (!Objects[ID_HAIR].loaded) return; @@ -376,14 +376,14 @@ void Renderer11::DrawLaraHair(RendererItem* itemToDraw, RendererRoom* room, bool for (int i = 0; i < hairObject.ObjectMeshes.size(); i++) { auto& rMesh = *hairObject.ObjectMeshes[i]; - DrawMoveableMesh(itemToDraw, &rMesh, room, i, transparent); + DrawMoveableMesh(itemToDraw, &rMesh, room, i, rendererPass); } isHead = false; } } -void Renderer11::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, bool transparent) +void Renderer11::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, RendererPass rendererPass) { if (!m_moveableObjects[ID_LARA_SKIN_JOINTS].has_value()) return; @@ -393,11 +393,11 @@ void Renderer11::DrawLaraJoints(RendererItem* itemToDraw, RendererRoom* room, bo for (int k = 1; k < laraSkinJoints.ObjectMeshes.size(); k++) { RendererMesh* mesh = laraSkinJoints.ObjectMeshes[k]; - DrawMoveableMesh(itemToDraw, mesh, room, k, transparent); + DrawMoveableMesh(itemToDraw, mesh, room, k, rendererPass); } } -void Renderer11::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, bool transparent) +void Renderer11::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, RendererPass rendererPass) { HolsterSlot leftHolsterID = Lara.Control.Weapon.HolsterInfo.LeftHolster; HolsterSlot rightHolsterID = Lara.Control.Weapon.HolsterInfo.RightHolster; @@ -407,20 +407,20 @@ void Renderer11::DrawLaraHolsters(RendererItem* itemToDraw, RendererRoom* room, { RendererObject& holsterSkin = *m_moveableObjects[static_cast(leftHolsterID)]; RendererMesh* mesh = holsterSkin.ObjectMeshes[LM_LTHIGH]; - DrawMoveableMesh(itemToDraw, mesh, room, LM_LTHIGH, transparent); + DrawMoveableMesh(itemToDraw, mesh, room, LM_LTHIGH, rendererPass); } if (m_moveableObjects[static_cast(rightHolsterID)]) { RendererObject& holsterSkin = *m_moveableObjects[static_cast(rightHolsterID)]; RendererMesh* mesh = holsterSkin.ObjectMeshes[LM_RTHIGH]; - DrawMoveableMesh(itemToDraw, mesh, room, LM_RTHIGH, transparent); + DrawMoveableMesh(itemToDraw, mesh, room, LM_RTHIGH, rendererPass); } if (backHolsterID != HolsterSlot::Empty && m_moveableObjects[static_cast(backHolsterID)]) { RendererObject& holsterSkin = *m_moveableObjects[static_cast(backHolsterID)]; RendererMesh* mesh = holsterSkin.ObjectMeshes[LM_TORSO]; - DrawMoveableMesh(itemToDraw, mesh, room, LM_TORSO, transparent); + DrawMoveableMesh(itemToDraw, mesh, room, LM_TORSO, rendererPass); } } diff --git a/TombEngine/Renderer/Renderer11String.cpp b/TombEngine/Renderer/Renderer11String.cpp index cefc11aea..28b38779c 100644 --- a/TombEngine/Renderer/Renderer11String.cpp +++ b/TombEngine/Renderer/Renderer11String.cpp @@ -5,13 +5,27 @@ namespace TEN::Renderer { - void Renderer11::AddString(int x, int y, const char* string, D3DCOLOR color, int flags) + void Renderer11::AddDebugString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags, RendererDebugPage page) { - AddString(std::string(string), Vector2(x, y), Color(color), 1.0f, flags); + constexpr auto FLAGS = PRINTSTRING_OUTLINE | PRINTSTRING_CENTER; + + if (DebugPage != page) + return; + + AddString(string, pos, color, scale, FLAGS); + } + + void Renderer11::AddString(int x, int y, const std::string& string, D3DCOLOR color, int flags) + { + AddString(string, Vector2(x, y), Color(color), 1.0f, flags); } void Renderer11::AddString(const std::string& string, const Vector2& pos, const Color& color, float scale, int flags) { + constexpr auto BLINK_VALUE_MAX = 1.0f; + constexpr auto BLINK_VALUE_MIN = 0.1f; + constexpr auto BLINK_TIME_STEP = 0.2f; + if (m_Locked) return; @@ -24,7 +38,7 @@ namespace TEN::Renderer auto factor = Vector2(screenRes.x / SCREEN_SPACE_RES.x, screenRes.y / SCREEN_SPACE_RES.y); float uiScale = (screenRes.x > screenRes.y) ? factor.y : factor.x; float fontSpacing = m_gameFont->GetLineSpacing(); - float fontScale = REFERENCE_FONT_SIZE / fontSpacing; + float fontScale = REFERENCE_FONT_SIZE / fontSpacing; auto stringLines = SplitString(string); float yOffset = 0.0f; @@ -36,7 +50,7 @@ namespace TEN::Renderer rString.Flags = flags; rString.X = 0; rString.Y = 0; - rString.Color = color.ToVector3() * UCHAR_MAX; + rString.Color = color.ToVector3(); rString.Scale = (uiScale * fontScale) * scale; // Measure string. @@ -47,30 +61,24 @@ namespace TEN::Renderer if (flags & PRINTSTRING_BLINK) { - rString.Color = Vector3(m_blinkColorValue, m_blinkColorValue, m_blinkColorValue); + rString.Color *= BlinkColorValue; - if (!m_blinkUpdated) + if (!IsBlinkUpdated) { - m_blinkColorValue += m_blinkColorDirection * 16; - m_blinkUpdated = true; + // Calculate blink increment based on sine wave. + BlinkColorValue = ((sin(BlinkTime) + BLINK_VALUE_MAX) * 0.5f) + BLINK_VALUE_MIN; - if (m_blinkColorValue < 0) - { - m_blinkColorValue = 0; - m_blinkColorDirection = 1; - } + // Update blink time. + BlinkTime += BLINK_TIME_STEP; + if (BlinkTime > PI_MUL_2) + BlinkTime -= PI_MUL_2; - if (m_blinkColorValue > UCHAR_MAX) - { - m_blinkColorValue = UCHAR_MAX; - m_blinkColorDirection = -1; - } + IsBlinkUpdated = true; } } - m_strings.push_back(rString); - yOffset += size.y; + m_strings.push_back(rString); } } catch (std::exception& ex) @@ -81,7 +89,7 @@ namespace TEN::Renderer void Renderer11::DrawAllStrings() { - float shadeOffset = 1.5f / (REFERENCE_FONT_SIZE / m_gameFont->GetLineSpacing()); + float shadowOffset = 1.5f / (REFERENCE_FONT_SIZE / m_gameFont->GetLineSpacing()); m_spriteBatch->Begin(); @@ -92,7 +100,7 @@ namespace TEN::Renderer { m_gameFont->DrawString( m_spriteBatch.get(), rString.String.c_str(), - Vector2(rString.X + shadeOffset * rString.Scale, rString.Y + shadeOffset * rString.Scale), + Vector2(rString.X + shadowOffset * rString.Scale, rString.Y + shadowOffset * rString.Scale), Vector4(0.0f, 0.0f, 0.0f, 1.0f) * ScreenFadeCurrent, 0.0f, Vector4::Zero, rString.Scale); } @@ -101,13 +109,13 @@ namespace TEN::Renderer m_gameFont->DrawString( m_spriteBatch.get(), rString.String.c_str(), Vector2(rString.X, rString.Y), - Vector4(rString.Color.x / UCHAR_MAX, rString.Color.y / UCHAR_MAX, rString.Color.z / UCHAR_MAX, 1.0f) * ScreenFadeCurrent, + Vector4(rString.Color.x, rString.Color.y, rString.Color.z, 1.0f) * ScreenFadeCurrent, 0.0f, Vector4::Zero, rString.Scale); } m_spriteBatch->End(); - m_blinkUpdated = false; + IsBlinkUpdated = false; m_strings.clear(); } } diff --git a/TombEngine/Renderer/RendererVertex.h b/TombEngine/Renderer/RendererVertex.h index 6190fda61..76240ea70 100644 --- a/TombEngine/Renderer/RendererVertex.h +++ b/TombEngine/Renderer/RendererVertex.h @@ -9,6 +9,7 @@ namespace TEN::Renderer Vector2 UV = Vector2::Zero; Vector4 Color = Vector4::Zero; Vector3 Tangent = Vector3::Zero; + Vector3 Binormal = Vector3::Zero; unsigned int AnimationFrameOffset = 0; Vector4 Effects = Vector4::Zero; diff --git a/TombEngine/Renderer/Utils.cpp b/TombEngine/Renderer/Utils.cpp index e140d126b..7f136d0ea 100644 --- a/TombEngine/Renderer/Utils.cpp +++ b/TombEngine/Renderer/Utils.cpp @@ -62,7 +62,7 @@ namespace TEN::Renderer::Utils } else { - TENLog("Error while compiling shader: " + TEN::Utils::ToString(fileName.c_str()), LogLevel::Error); + TENLog("Error while compiling VS shader: " + TEN::Utils::ToString(fileName.c_str()), LogLevel::Error); throwIfFailed(res); } } @@ -83,12 +83,27 @@ namespace TEN::Renderer::Utils ComPtr compilePixelShader(ID3D11Device* device, const wstring& fileName, const string& function, const string& model, const D3D_SHADER_MACRO* defines, ComPtr& bytecode) { ComPtr errors; - UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_DEBUG | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR | D3DCOMPILE_SKIP_OPTIMIZATION; - throwIfFailed(D3DCompileFromFile(fileName.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, function.c_str(), model.c_str(), GetShaderFlags(), 0, bytecode.GetAddressOf(), errors.GetAddressOf())); + HRESULT res = (D3DCompileFromFile(fileName.c_str(), defines, D3D_COMPILE_STANDARD_FILE_INCLUDE, function.c_str(), model.c_str(), GetShaderFlags(), 0, bytecode.GetAddressOf(), errors.GetAddressOf())); + if (FAILED(res)) + { + ID3D10Blob* errorObj = errors.Get(); + if (errorObj != nullptr) + { + auto error = std::string((char*)errorObj->GetBufferPointer()); + TENLog(error, LogLevel::Error); + throw std::runtime_error(error); + } + else + { + TENLog("Error while compiling PS shader: " + TEN::Utils::ToString(fileName.c_str()), LogLevel::Error); + throwIfFailed(res); + } + } + ComPtr shader; throwIfFailed(device->CreatePixelShader(bytecode->GetBufferPointer(), bytecode->GetBufferSize(), nullptr, shader.GetAddressOf())); - - if constexpr(DebugBuild) + + if constexpr (DebugBuild) { char buffer[100]; unsigned int size = (unsigned int)std::wcstombs(buffer, fileName.c_str(), 100); @@ -98,14 +113,18 @@ namespace TEN::Renderer::Utils return shader; } - constexpr UINT Utils::GetShaderFlags() + constexpr unsigned int Utils::GetShaderFlags() { - UINT flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; + unsigned int flags = D3DCOMPILE_ENABLE_STRICTNESS | D3DCOMPILE_PACK_MATRIX_ROW_MAJOR; - //if constexpr(DebugBuild) + if constexpr (DebugBuild) + { flags |= D3DCOMPILE_DEBUG | D3DCOMPILE_SKIP_OPTIMIZATION; - //else - // flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS; + } + else + { + flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3 | D3DCOMPILE_IEEE_STRICTNESS; + } return flags; } diff --git a/TombEngine/Renderer/Utils.h b/TombEngine/Renderer/Utils.h index 0944eebca..a54165d09 100644 --- a/TombEngine/Renderer/Utils.h +++ b/TombEngine/Renderer/Utils.h @@ -10,6 +10,6 @@ namespace TEN::Renderer::Utils void throwIfFailed(const HRESULT& res, const std::wstring& info); [[nodiscard]] Microsoft::WRL::ComPtr compileVertexShader(ID3D11Device* device, const std::wstring& fileName, const std::string& function, const std::string& model, const D3D_SHADER_MACRO* defines, Microsoft::WRL::ComPtr& bytecode); - constexpr [[nodiscard]] UINT GetShaderFlags(); + constexpr [[nodiscard]] unsigned int GetShaderFlags(); [[nodiscard]] Microsoft::WRL::ComPtr compilePixelShader(ID3D11Device* device, const std::wstring& fileName, const std::string& function, const std::string& model, const D3D_SHADER_MACRO* defines, Microsoft::WRL::ComPtr& bytecode); } diff --git a/TombEngine/Resources.rc b/TombEngine/Resources.rc index 245c897fd..165a25172 100644 --- a/TombEngine/Resources.rc +++ b/TombEngine/Resources.rc @@ -26,8 +26,8 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,9,0 - PRODUCTVERSION 1,6,7,0 + FILEVERSION 1,1,0,0 + PRODUCTVERSION 1,6,8,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BLOCK "000904b0" BEGIN VALUE "CompanyName", "Tomb Engine Development Community" - VALUE "FileVersion", "1.0.9.0" + VALUE "FileVersion", "1.1.0.0" VALUE "InternalName", "TombEngine.exe" VALUE "LegalCopyright", "Copyright (c) 2023" VALUE "OriginalFilename", "TombEngine.exe" VALUE "ProductName", "Tomb Engine" - VALUE "ProductVersion", "1.6.7.0" + VALUE "ProductVersion", "1.6.8.0" END END BLOCK "VarFileInfo" diff --git a/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h b/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h index 4b8ab98d2..6dd95c79e 100644 --- a/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h +++ b/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h @@ -11,7 +11,6 @@ class ScriptInterfaceLevel; class ScriptInterfaceFlowHandler { public: - std::string IntroImagePath{}; int SelectedLevelForNewGame{ 0 }; int SelectedSaveGame{ 0 }; @@ -21,11 +20,14 @@ public: TITLE_TYPE TitleType{ TITLE_TYPE::FLYBY }; virtual ~ScriptInterfaceFlowHandler() = default; + virtual void LoadFlowScript() = 0; + virtual void SetGameDir(const std::string& assetDir) = 0; virtual std::string GetGameDir() = 0; virtual int GetNumLevels() const = 0; virtual char const* GetString(const char* id) const = 0; + virtual bool IsFlyCheatEnabled() const = 0; virtual bool IsMassPickupEnabled() const = 0; virtual bool IsLaraInTitleEnabled() const = 0; @@ -38,9 +40,11 @@ public: virtual bool HasOverhangClimb() const = 0; virtual bool HasSlideExtended() const = 0; virtual bool HasLedgeJumps() const = 0; + virtual ScriptInterfaceLevel * GetLevel(int level) = 0; virtual int GetLevelNumber(std::string const& fileName) = 0; virtual bool IsLevelSelectEnabled() const = 0; + virtual bool DoFlow() = 0; }; diff --git a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h index b770da376..84c713226 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceLevel.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceLevel.h @@ -22,12 +22,13 @@ enum class LaraType class ScriptInterfaceLevel { public: - bool Horizon{ false }; - bool Rumble{ false }; - std::string NameStringKey; - std::string FileName; - std::string ScriptFileName; - std::string LoadScreenFileName; + bool Horizon = false; + bool Rumble = false; + + std::string NameStringKey = {}; + std::string FileName = {}; + std::string ScriptFileName = {}; + std::string LoadScreenFileName = {}; virtual ~ScriptInterfaceLevel() = default; diff --git a/TombEngine/Scripting/Include/Strings/ScriptInterfaceStringsHandler.h b/TombEngine/Scripting/Include/Strings/ScriptInterfaceStringsHandler.h index 3e53823f7..885bb48ea 100644 --- a/TombEngine/Scripting/Include/Strings/ScriptInterfaceStringsHandler.h +++ b/TombEngine/Scripting/Include/Strings/ScriptInterfaceStringsHandler.h @@ -11,6 +11,7 @@ class ScriptInterfaceStringsHandler { public: virtual ~ScriptInterfaceStringsHandler() = default; + virtual void ProcessDisplayStrings(float deltaTime) = 0; virtual void ClearDisplayStrings() = 0; virtual void SetCallbackDrawString(CallbackDrawString) = 0; diff --git a/TombEngine/Scripting/Internal/AudioTracks.h b/TombEngine/Scripting/Internal/AudioTracks.h index 217fe5a54..917220578 100644 --- a/TombEngine/Scripting/Internal/AudioTracks.h +++ b/TombEngine/Scripting/Internal/AudioTracks.h @@ -139,4 +139,4 @@ std::array kAudioTracks "xa17_Andrea4.wav", "xa17_Andy9.wav", "xa17_Andy11.wav" -}; \ No newline at end of file +}; diff --git a/TombEngine/Scripting/Internal/LanguageScript.h b/TombEngine/Scripting/Internal/LanguageScript.h index ab1ecc1e3..eb9366775 100644 --- a/TombEngine/Scripting/Internal/LanguageScript.h +++ b/TombEngine/Scripting/Internal/LanguageScript.h @@ -43,6 +43,7 @@ #define STRING_SEPARATE "separate" #define STRING_CHOOSE_AMMO "choose_ammo" #define STRING_SELECT_LEVEL "select_level" +#define STRING_GENERAL_ACTIONS "general_actions" #define STRING_GRENADE_LAUNCHER "grenade_launcher" #define STRING_GRENADE_LAUNCHER_AMMO_1 "grenade_launcher_normal_ammo" #define STRING_GRENADE_LAUNCHER_AMMO_2 "grenade_launcher_super_ammo" @@ -83,30 +84,33 @@ #define STRING_RUMBLE "rumble" #define STRING_THUMBSTICK_CAMERA "thumbstick_camera" #define STRING_SUBTITLES "subtitles" -#define STRING_CONTROLS_MOVE_FORWARD "controls_move_forward" -#define STRING_CONTROLS_MOVE_BACKWARD "controls_move_backward" -#define STRING_CONTROLS_MOVE_LEFT "controls_move_left" -#define STRING_CONTROLS_MOVE_RIGHT "controls_move_right" -#define STRING_CONTROLS_CROUCH "controls_crouch" -#define STRING_CONTROLS_SPRINT "controls_sprint" -#define STRING_CONTROLS_WALK "controls_walk" -#define STRING_CONTROLS_JUMP "controls_jump" -#define STRING_CONTROLS_ACTION "controls_action" -#define STRING_CONTROLS_DRAW_WEAPON "controls_draw_weapon" -#define STRING_CONTROLS_USE_FLARE "controls_use_flare" -#define STRING_CONTROLS_LOOK "controls_look" -#define STRING_CONTROLS_ROLL "controls_roll" -#define STRING_CONTROLS_INVENTORY "controls_inventory" -#define STRING_CONTROLS_PAUSE "controls_pause" -#define STRING_CONTROLS_STEP_LEFT "controls_step_left" -#define STRING_CONTROLS_STEP_RIGHT "controls_step_right" -#define STRING_CONTROLS_V_ACCELERATE "controls_accelerate" -#define STRING_CONTROLS_V_REVERSE "controls_reverse" -#define STRING_CONTROLS_V_SPEED "controls_speed" -#define STRING_CONTROLS_V_SLOW "controls_slow" -#define STRING_CONTROLS_V_BRAKE "controls_brake" -#define STRING_CONTROLS_V_FIRE "controls_fire" -#define STRING_CONTROLS_DEFAULTS "controls_defaults" +#define STRING_ACTIONS_FORWARD "actions_forward" +#define STRING_ACTIONS_BACKWARD "actions_backward" +#define STRING_ACTIONS_LEFT "actions_left" +#define STRING_ACTIONS_RIGHT "actions_right" +#define STRING_ACTIONS_CROUCH "actions_crouch" +#define STRING_ACTIONS_SPRINT "actions_sprint" +#define STRING_ACTIONS_WALK "actions_walk" +#define STRING_ACTIONS_JUMP "actions_jump" +#define STRING_ACTIONS_ACTION "actions_action" +#define STRING_ACTIONS_DRAW "actions_draw" +#define STRING_ACTIONS_LOOK "actions_look" +#define STRING_ACTIONS_ROLL "actions_roll" +#define STRING_ACTIONS_INVENTORY "actions_inventory" +#define STRING_ACTIONS_PAUSE "actions_pause" +#define STRING_ACTIONS_SAVE "actions_save" +#define STRING_ACTIONS_LOAD "actions_load" +#define STRING_ACTIONS_SELECT "actions_select" +#define STRING_ACTIONS_DESELECT "actions_deselect" +#define STRING_ACTIONS_STEP_LEFT "actions_step_left" +#define STRING_ACTIONS_STEP_RIGHT "actions_step_right" +#define STRING_ACTIONS_ACCELERATE "actions_accelerate" +#define STRING_ACTIONS_REVERSE "actions_reverse" +#define STRING_ACTIONS_SPEED "actions_speed" +#define STRING_ACTIONS_SLOW "actions_slow" +#define STRING_ACTIONS_BRAKE "actions_brake" +#define STRING_ACTIONS_FIRE "actions_fire" +#define STRING_RESET_TO_DEFAULTS "reset_to_defaults" #define STRING_TITLE_ITEMS "items" #define STRING_TITLE_PUZZLES "puzzles" #define STRING_TITLE_SETTINGS "settings" @@ -132,6 +136,23 @@ #define STRING_AMMO_USED "ammo_used" #define STRING_TOTAL_SECRETS_FOUND "total_secrets_found" #define STRING_LEVEL_SECRETS_FOUND "level_secrets_found" +#define STRING_MENU_ACTIONS "menu_actions" +#define STRING_QUICK_ACTIONS "quick_actions" +#define STRING_ACTIONS_LARGE_MEDIPACK "actions_large_medipack" +#define STRING_ACTIONS_FLARE "actions_flare" +#define STRING_ACTIONS_NEXT_WEAPON "actions_next_weapon" +#define STRING_ACTIONS_PREVIOUS_WEAPON "actions_previous_weapon" +#define STRING_ACTIONS_SMALL_MEDIPACK "actions_small_medipack" +#define STRING_ACTIONS_WEAPON_1 "actions_weapon_1" +#define STRING_ACTIONS_WEAPON_2 "actions_weapon_2" +#define STRING_ACTIONS_WEAPON_3 "actions_weapon_3" +#define STRING_ACTIONS_WEAPON_4 "actions_weapon_4" +#define STRING_ACTIONS_WEAPON_5 "actions_weapon_5" +#define STRING_ACTIONS_WEAPON_6 "actions_weapon_6" +#define STRING_ACTIONS_WEAPON_7 "actions_weapon_7" +#define STRING_ACTIONS_WEAPON_8 "actions_weapon_8" +#define STRING_ACTIONS_WEAPON_9 "actions_weapon_9" +#define STRING_ACTIONS_WEAPON_10 "actions_weapon_10" #define STRING_WATERSKIN_SMALL_EMPTY "waterskin_small_empty" #define STRING_WATERSKIN_SMALL_1L "waterskin_small_1l" #define STRING_WATERSKIN_SMALL_2L "waterskin_small_2l" @@ -146,3 +167,4 @@ #define STRING_MECHANICAL_SCARAB "mechanical_scarab" #define STRING_MECHANICAL_SCARAB_1 "mechanical_scarab_1" #define STRING_MECHANICAL_SCARAB_2 "mechanical_scarab_2" +#define STRING_VEHICLE_ACTIONS "vehicle_actions" diff --git a/TombEngine/Scripting/Internal/LuaHandler.cpp b/TombEngine/Scripting/Internal/LuaHandler.cpp index 727db06b3..c73ee0078 100644 --- a/TombEngine/Scripting/Internal/LuaHandler.cpp +++ b/TombEngine/Scripting/Internal/LuaHandler.cpp @@ -8,7 +8,7 @@ LuaHandler::LuaHandler(sol::state* lua) : m_lua{ lua } void LuaHandler::ResetGlobals() { - sol::table mt = sol::table{ *m_lua, sol::create }; + auto mt = sol::table{ *m_lua, sol::create }; m_globals = sol::table{ *m_lua, sol::create }; mt.set(sol::meta_function::new_index, m_globals); mt.set(sol::meta_function::index, m_globals); @@ -16,7 +16,8 @@ void LuaHandler::ResetGlobals() m_lua->set(sol::metatable_key, mt); } -void LuaHandler::ExecuteScript(std::string const& luaFilename) { +void LuaHandler::ExecuteScript(const std::string& luaFilename) +{ auto result = m_lua->safe_script_file(luaFilename, sol::script_pass_on_error); if (!result.valid()) { @@ -25,7 +26,8 @@ void LuaHandler::ExecuteScript(std::string const& luaFilename) { } } -void LuaHandler::ExecuteString(std::string const& command) { +void LuaHandler::ExecuteString(const std::string& command) +{ auto result = m_lua->safe_script(command, sol::environment(m_lua->lua_state(), sol::create, m_lua->globals()), sol::script_pass_on_error); if (!result.valid()) { diff --git a/TombEngine/Scripting/Internal/LuaHandler.h b/TombEngine/Scripting/Internal/LuaHandler.h index 34d65f491..448c6cadf 100644 --- a/TombEngine/Scripting/Internal/LuaHandler.h +++ b/TombEngine/Scripting/Internal/LuaHandler.h @@ -1,68 +1,69 @@ #pragma once #include "framework.h" + #include "Scripting/Internal/ScriptAssert.h" -class LuaHandler { +class LuaHandler +{ protected: sol::state* m_lua; sol::table m_globals; public: LuaHandler(sol::state* lua); - LuaHandler(LuaHandler const &) = delete; - LuaHandler& operator=(LuaHandler const &) = delete; + LuaHandler(const LuaHandler&) = delete; + LuaHandler& operator=(const LuaHandler&) = delete; ~LuaHandler() = default; - void ExecuteScript(const std::string & luaFilename); - void ExecuteString(const std::string & command); + void ExecuteScript(const std::string& luaFilename); + void ExecuteString(const std::string& command); void ResetGlobals(); - sol::state* GetState() { + sol::state* GetState() + { return m_lua; }; - template void MakeReadOnlyTable(sol::table & parent, std::string const& tableName, T const& container) + template void MakeReadOnlyTable(sol::table parent, const std::string& tableName, const T& container) { - auto mt = tableName + "Meta"; - // Put all the data in the metatable - m_lua->set(mt, sol::as_table(container)); + // Put all data into metatable. + auto metatable = tableName + "Meta"; + m_lua->set(metatable, sol::as_table(container)); auto mtmt = tableName + "MetaMeta"; auto mtmtTable = m_lua->create_named_table(mtmt); - // Make the metatable's metatable's __index fail an assert so that trying to use a variable - // that doesn't exist will generate a warning or error. + // Make metatable's metatable's __index fail an assert to generate warning/error when trying to use missing variable. auto lam = [tableName](sol::table tab, std::string const& key) { ScriptAssertF(false, tableName + " has no member \"" + key +"\""); }; mtmtTable[sol::meta_method::index] = lam; - m_lua->safe_script("setmetatable(" + mt + ", " + mtmt + ")"); + m_lua->safe_script("setmetatable(" + metatable + ", " + mtmt + ")"); - // Make the metatable's __index refer to itself so that requests - // to the main table will go through to the metatable (and thus the - // container's members) - m_lua->safe_script(mt + ".__index = " + mt); + // Make metatable's __index refer to itself so that requests to main table will go through to metatable + // (and thus container's members). + m_lua->safe_script(metatable + ".__index = " + metatable); - m_lua->safe_script(mt + ".__type = \"readonly\""); + m_lua->safe_script(metatable + ".__type = \"readonly\""); - // Don't allow the table to have new elements put into it - m_lua->safe_script(mt + ".__newindex = function() error('" + tableName + " is read-only') end"); + // Don't allow table to have new elements put into it. + m_lua->safe_script(metatable + ".__newindex = function() error('" + tableName + " is read-only') end"); - // Protect the metatable - m_lua->safe_script(mt + ".__metatable = 'metatable is protected'"); + // Protect metatable. + m_lua->safe_script(metatable + ".__metatable = 'metatable is protected'"); auto tab = m_lua->create_named_table(tableName); - m_lua->safe_script("setmetatable(" + tableName + ", " + mt + ")"); + m_lua->safe_script("setmetatable(" + tableName + ", " + metatable + ")"); - // point the initial metatable variable away from its contents. this is just for cleanliness + // Point initial metatable variable away from its contents. This is just for cleanliness. parent.set(tableName, tab); m_lua->safe_script(tableName + " = nil"); - m_lua->safe_script(mt + " = nil"); + m_lua->safe_script(metatable + " = nil"); m_lua->safe_script(mtmt + " = nil"); } }; diff --git a/TombEngine/Scripting/Internal/ScriptInterfaceState.cpp b/TombEngine/Scripting/Internal/ScriptInterfaceState.cpp index 8ac412bf1..2a70d7613 100644 --- a/TombEngine/Scripting/Internal/ScriptInterfaceState.cpp +++ b/TombEngine/Scripting/Internal/ScriptInterfaceState.cpp @@ -2,8 +2,8 @@ #include "Scripting/Include/ScriptInterfaceState.h" #include "Scripting/Internal/ReservedScriptNames.h" -#include "Scripting/Internal/TEN/Flow/FlowHandler.h" #include "Scripting/Internal/TEN/Effects/EffectsFunctions.h" +#include "Scripting/Internal/TEN/Flow/FlowHandler.h" #include "Scripting/Internal/TEN/Inventory/InventoryHandler.h" #include "Scripting/Internal/TEN/Logic/LogicHandler.h" #include "Scripting/Internal/TEN/Misc/Miscellaneous.h" diff --git a/TombEngine/Scripting/Internal/ScriptUtil.cpp b/TombEngine/Scripting/Internal/ScriptUtil.cpp index c193a7e1f..40a0a445e 100644 --- a/TombEngine/Scripting/Internal/ScriptUtil.cpp +++ b/TombEngine/Scripting/Internal/ScriptUtil.cpp @@ -6,10 +6,13 @@ sol::table MakeSpecialTableBase(sol::state* state, const std::string& name) std::string metaName{ name + "Meta" }; auto meta = sol::table{ *state, sol::create }; state->set(metaName, meta); + meta.set("__metatable", "\"metatable is protected\""); state->safe_script("rawset(_G, \"" + name + "\", {})"); + auto tab = (*state)[name]; tab[sol::metatable_key] = meta; state->set(metaName, sol::nil); + return meta; } diff --git a/TombEngine/Scripting/Internal/TEN/Color/Color.cpp b/TombEngine/Scripting/Internal/TEN/Color/Color.cpp index 7d4e0eb0c..ab08c199c 100644 --- a/TombEngine/Scripting/Internal/TEN/Color/Color.cpp +++ b/TombEngine/Scripting/Internal/TEN/Color/Color.cpp @@ -1,5 +1,6 @@ #include "framework.h" -#include "Color.h" +#include "Scripting/Internal/TEN/Color/Color.h" + #include /*** @@ -10,10 +11,11 @@ Components are specified in bytes; all values are clamped to [0, 255]. @pragma nostrip */ -void ScriptColor::Register(sol::table & parent) +void ScriptColor::Register(sol::table& parent) { using ctors = sol::constructors; - parent.new_usertype("Color", + parent.new_usertype( + "Color", ctors(), sol::call_constructor, ctors(), sol::meta_function::to_string, &ScriptColor::ToString, @@ -30,7 +32,7 @@ void ScriptColor::Register(sol::table & parent) //@mem b "b", sol::property(&ScriptColor::GetB, &ScriptColor::SetB), -/// (int) alpha component (255 is opaque, 0 is invisible) +/// (int) alpha component (255 = opaque, 0 = invisible) //@mem a "a", sol::property(&ScriptColor::GetA, &ScriptColor::SetA) ); @@ -61,18 +63,18 @@ ScriptColor::ScriptColor(byte r, byte g, byte b, byte a) : ScriptColor(r, g, b) SetA(a); } -ScriptColor::ScriptColor(Vector3 const& col) : - m_color(col) +ScriptColor::ScriptColor(const Vector3& color) : + m_color(color) { } -ScriptColor::ScriptColor(Vector4 const& col) : - m_color(col) +ScriptColor::ScriptColor(const Vector4& color) : + m_color(color) { } -ScriptColor::ScriptColor(D3DCOLOR col) : - m_color(col) +ScriptColor::ScriptColor(D3DCOLOR color) : + m_color(color) { } @@ -102,9 +104,9 @@ byte ScriptColor::GetR() const return m_color.GetR(); } -void ScriptColor::SetR(byte v) +void ScriptColor::SetR(byte value) { - m_color.SetR(v); + m_color.SetR(value); } byte ScriptColor::GetG() const @@ -112,9 +114,9 @@ byte ScriptColor::GetG() const return m_color.GetG(); } -void ScriptColor::SetG(byte v) +void ScriptColor::SetG(byte value) { - m_color.SetG(v); + m_color.SetG(value); } byte ScriptColor::GetB() const @@ -122,9 +124,9 @@ byte ScriptColor::GetB() const return m_color.GetB(); } -void ScriptColor::SetB(byte v) +void ScriptColor::SetB(byte value) { - m_color.SetB(v); + m_color.SetB(value); } byte ScriptColor::GetA() const @@ -132,9 +134,9 @@ byte ScriptColor::GetA() const return m_color.GetA(); } -void ScriptColor::SetA(byte v) +void ScriptColor::SetA(byte value) { - m_color.SetA(v); + m_color.SetA(value); } /*** @@ -144,5 +146,5 @@ void ScriptColor::SetA(byte v) */ std::string ScriptColor::ToString() const { - return "{" + std::to_string(GetR()) + ", " + std::to_string(GetG()) + ", " + std::to_string(GetB()) + ", " + std::to_string(GetA()) + "}"; + return "{" + std::to_string(GetR()) + ", " + std::to_string(GetG()) + ", " + std::to_string(GetB()) + ", " + std::to_string(GetA()) + "}"; } diff --git a/TombEngine/Scripting/Internal/TEN/Color/Color.h b/TombEngine/Scripting/Internal/TEN/Color/Color.h index deb6b60a2..359ab3791 100644 --- a/TombEngine/Scripting/Internal/TEN/Color/Color.h +++ b/TombEngine/Scripting/Internal/TEN/Color/Color.h @@ -3,17 +3,19 @@ typedef DWORD D3DCOLOR; -namespace sol { +namespace sol +{ class state; template struct as_table_t; } -class ScriptColor { +class ScriptColor +{ public: ScriptColor(byte r, byte g, byte b); ScriptColor(byte r, byte g, byte b, byte a); - ScriptColor(Vector3 const &); - ScriptColor(Vector4 const &); + ScriptColor(const Vector3& color); + ScriptColor(const Vector4& color); ScriptColor(D3DCOLOR); operator Vector3() const; @@ -22,17 +24,18 @@ public: operator RGBAColor8Byte() const; byte GetR() const; - void SetR(byte v); + void SetR(byte value); byte GetG() const; - void SetG(byte v); + void SetG(byte value); byte GetB() const; - void SetB(byte v); + void SetB(byte value); byte GetA() const; - void SetA(byte v); + void SetA(byte value); std::string ToString() const; - static void Register(sol::table & parent); + static void Register(sol::table& parent); + private: RGBAColor8Byte m_color; -}; \ No newline at end of file +}; diff --git a/TombEngine/Scripting/Internal/TEN/Effects/BlendIDs.h b/TombEngine/Scripting/Internal/TEN/Effects/BlendIDs.h index c50decab1..3c5a91726 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/BlendIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Effects/BlendIDs.h @@ -35,7 +35,7 @@ The following constants are inside BlendID. */ -static const std::unordered_map kBlendIDs +static const std::unordered_map BLEND_IDS { {"OPAQUE", BLENDMODE_OPAQUE}, {"ALPHATEST", BLENDMODE_ALPHATEST}, diff --git a/TombEngine/Scripting/Internal/TEN/Effects/EffectIDs.h b/TombEngine/Scripting/Internal/TEN/Effects/EffectIDs.h index 508d9822f..478c60f85 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/EffectIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Effects/EffectIDs.h @@ -1,7 +1,7 @@ #pragma once - -#include #include +#include + #include "Game/items.h" /*** @@ -30,7 +30,7 @@ The following constants are inside EffectID. @table CONSTANT_STRING_HERE */ -static const std::unordered_map kEffectIDs +static const std::unordered_map EFFECT_IDS { {"NONE", EffectType::None}, {"FIRE", EffectType::Fire}, diff --git a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp index 201152b61..435313898 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp +++ b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.cpp @@ -1,7 +1,6 @@ #include "framework.h" #include "Scripting/Internal/TEN/Effects/EffectsFunctions.h" -#include "Scripting/Internal/TEN/Effects/BlendIDs.h" #include "Game/camera.h" #include "Game/collision/collide_room.h" #include "Game/effects/effects.h" @@ -145,16 +144,16 @@ namespace Effects s->spriteIndex = Objects[ID_DEFAULT_SPRITES].meshIndex + spriteIndex; - ScriptColor sCol = USE_IF_HAVE(ScriptColor, startColor, ScriptColor( 255, 255, 255 )); - ScriptColor eCol = USE_IF_HAVE(ScriptColor, endColor, ScriptColor( 255, 255, 255 )); + ScriptColor colorStart = USE_IF_HAVE(ScriptColor, startColor, ScriptColor( 255, 255, 255 )); + ScriptColor colorEnd = USE_IF_HAVE(ScriptColor, endColor, ScriptColor( 255, 255, 255 )); - s->sR = sCol.GetR(); - s->sG = sCol.GetG(); - s->sB = sCol.GetB(); + s->sR = colorStart.GetR(); + s->sG = colorStart.GetG(); + s->sB = colorStart.GetB(); - s->dR = eCol.GetR(); - s->dG = eCol.GetG(); - s->dB = eCol.GetB(); + s->dR = colorEnd.GetR(); + s->dG = colorEnd.GetG(); + s->dB = colorEnd.GetB(); //there is no blend mode 7 BLEND_MODES bMode = USE_IF_HAVE(BLEND_MODES, blendMode, BLENDMODE_ALPHABLEND); @@ -211,7 +210,6 @@ namespace Effects s->gravity = grav; } - /***Emit a shockwave, similar to that seen when a harpy projectile hits something. @function EmitShockwave @@ -224,34 +222,34 @@ namespace Effects @tparam int angle (default 0) Angle about the X axis - a value of 90 will cause the shockwave to be entirely vertical @tparam bool hurtsLara (default false) If true, the shockwave will hurt Lara, with the damage being relative to the shockwave's current speed */ - static void EmitShockwave(Vec3 pos, TypeOrNil innerRadius, TypeOrNil outerRadius, TypeOrNil col, TypeOrNil lifetime, TypeOrNil speed, TypeOrNil angle, TypeOrNil hurtsLara) + static void EmitShockwave(Vec3 pos, TypeOrNil innerRadius, TypeOrNil outerRadius, TypeOrNil col, + TypeOrNil lifetime, TypeOrNil speed, TypeOrNil angle, TypeOrNil hurtPlayer) { - Pose p; - p.Position.x = pos.x; - p.Position.y = pos.y; - p.Position.z = pos.z; + constexpr auto LIFE_IN_SECONDS_MAX = 8.5f; + constexpr auto SECONDS_PER_FRAME = 1 / (float)FPS; - int iRad = USE_IF_HAVE(int, innerRadius, 0); - int oRad = USE_IF_HAVE(int, outerRadius, 128); + auto pose = Pose(pos.x, pos.y, pos.z); - ScriptColor color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); + int innerRad = USE_IF_HAVE(int, innerRadius, 0); + int outerRad = USE_IF_HAVE(int, outerRadius, 128); + auto color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); int spd = USE_IF_HAVE(int, speed, 50); - int ang = USE_IF_HAVE(int, angle, 0); - - constexpr auto kMaxLifeSeconds = 8.5f; + float life = USE_IF_HAVE(float, lifetime, 1.0f); - life = std::clamp(life, 0.0f, kMaxLifeSeconds); + life = std::clamp(life, 0.0f, LIFE_IN_SECONDS_MAX); - constexpr float secsPerFrame = 1.0f / (float)FPS; + // Normalize to range [0, 255]. + int lifeInFrames = (int)round(life / SECONDS_PER_FRAME); - // This will put us in the range [0, 255] - int lifeInFrames = (int)round(life / secsPerFrame); + bool doDamage = USE_IF_HAVE(bool, hurtPlayer, false); - bool damage = USE_IF_HAVE(bool, hurtsLara, false); - - TriggerShockwave(&p, iRad, oRad, spd, color.GetR(), color.GetG(), color.GetB(), lifeInFrames, EulerAngles(ANGLE(ang), 0.0f, 0.0f), short(damage), true, false, (int)ShockwaveStyle::Normal); + TriggerShockwave( + &pose, innerRad, outerRad, spd, + color.GetR(), color.GetG(), color.GetB(), + lifeInFrames, EulerAngles(ANGLE(ang), 0.0f, 0.0f), + (short)doDamage, true, false, (int)ShockwaveStyle::Normal); } /***Emit dynamic light that lasts for a single frame. @@ -263,12 +261,11 @@ namespace Effects */ static void EmitLight(Vec3 pos, TypeOrNil col, TypeOrNil radius) { - ScriptColor color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); + auto color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); int rad = USE_IF_HAVE(int, radius, 20); TriggerDynamicLight(pos.x, pos.y, pos.z, rad, color.GetR(), color.GetG(), color.GetB()); } - /***Emit blood. @function EmitBlood @tparam Vec3 pos @@ -286,7 +283,6 @@ namespace Effects */ static void EmitFire(Vec3 pos, TypeOrNil size) { - AddFire(pos.x, pos.y, pos.z, FindRoomNumber(Vector3i(pos.x, pos.y, pos.z)), USE_IF_HAVE(float, size, 1), 0); } @@ -314,33 +310,31 @@ namespace Effects /***Flash screen. @function FlashScreen @tparam Color color (default Color(255, 255, 255)) -@tparam float speed (default 1.0). Speed in "amount" per second. A value of 1 will make the flash take one second. Clamped to [0.005, 1.0] +@tparam float speed (default 1.0). Speed in "amount" per second. Value of 1 will make flash take one second. Clamped to [0.005, 1.0]. */ static void FlashScreen(TypeOrNil col, TypeOrNil speed) { - ScriptColor color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); - Weather.Flash(color.GetR(), color.GetG(), color.GetB(), (USE_IF_HAVE(float, speed, 1.0))/ float(FPS)); + auto color = USE_IF_HAVE(ScriptColor, col, ScriptColor(255, 255, 255)); + Weather.Flash(color.GetR(), color.GetG(), color.GetB(), (USE_IF_HAVE(float, speed, 1.0)) / (float)FPS); } void Register(sol::state* state, sol::table& parent) { - sol::table table_effects{ state->lua_state(), sol::create }; - parent.set(ScriptReserved_Effects, table_effects); + sol::table tableEffects = { state->lua_state(), sol::create }; + parent.set(ScriptReserved_Effects, tableEffects); - table_effects.set_function(ScriptReserved_EmitLightningArc, &EmitLightningArc); - table_effects.set_function(ScriptReserved_EmitParticle, &EmitParticle); - table_effects.set_function(ScriptReserved_EmitShockwave, &EmitShockwave); - table_effects.set_function(ScriptReserved_EmitLight, &EmitLight); - table_effects.set_function(ScriptReserved_EmitBlood, &EmitBlood); - table_effects.set_function(ScriptReserved_MakeExplosion, &MakeExplosion); - table_effects.set_function(ScriptReserved_EmitFire, &EmitFire); - table_effects.set_function(ScriptReserved_FlashScreen, &FlashScreen); - table_effects.set_function(ScriptReserved_MakeEarthquake, &Earthquake); + tableEffects.set_function(ScriptReserved_EmitLightningArc, &EmitLightningArc); + tableEffects.set_function(ScriptReserved_EmitParticle, &EmitParticle); + tableEffects.set_function(ScriptReserved_EmitShockwave, &EmitShockwave); + tableEffects.set_function(ScriptReserved_EmitLight, &EmitLight); + tableEffects.set_function(ScriptReserved_EmitBlood, &EmitBlood); + tableEffects.set_function(ScriptReserved_MakeExplosion, &MakeExplosion); + tableEffects.set_function(ScriptReserved_EmitFire, &EmitFire); + tableEffects.set_function(ScriptReserved_FlashScreen, &FlashScreen); + tableEffects.set_function(ScriptReserved_MakeEarthquake, &Earthquake); LuaHandler handler{ state }; - handler.MakeReadOnlyTable(table_effects, ScriptReserved_BlendID, kBlendIDs); - handler.MakeReadOnlyTable(table_effects, ScriptReserved_EffectID, kEffectIDs); + handler.MakeReadOnlyTable(tableEffects, ScriptReserved_BlendID, BLEND_IDS); + handler.MakeReadOnlyTable(tableEffects, ScriptReserved_EffectID, EFFECT_IDS); } } - - diff --git a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.h b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.h index 797bf9b4a..952d8e633 100644 --- a/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.h +++ b/TombEngine/Scripting/Internal/TEN/Effects/EffectsFunctions.h @@ -1,9 +1,8 @@ #pragma once -namespace sol { - class state; -}; -namespace Effects { - void Register(sol::state* lua, sol::table &); -}; +namespace sol { class state; }; +namespace Effects +{ + void Register(sol::state* lua, sol::table&); +}; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp index a029f9e47..d8a5d46b7 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp @@ -152,7 +152,7 @@ This is equivalent to TRNG's LevelFarView variable. void Level::SetLevelFarView(short val) { static_assert(MIN_FAR_VIEW == 3200.0f, "Please update the comment, docs, and warning message if this number changes."); - const short min = std::ceil(MIN_FAR_VIEW / SECTOR(1)); + const short min = std::ceil(MIN_FAR_VIEW / BLOCK(1)); bool cond = val >= min; std::string msg{ "farView value must be 4 or greater." }; diff --git a/TombEngine/Scripting/Internal/TEN/Misc/ActionIDs.h b/TombEngine/Scripting/Internal/TEN/Misc/ActionIDs.h index e6898c46d..c92982c4d 100644 --- a/TombEngine/Scripting/Internal/TEN/Misc/ActionIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Misc/ActionIDs.h @@ -20,19 +20,46 @@ The following constants are inside ActionID. BACK LEFT RIGHT - CROUCH - SPRINT + STEP_LEFT + STEP_RIGHT WALK + SPRINT + CROUCH JUMP + ROLL ACTION DRAW - FLARE LOOK - ROLL - INVENTORY + + ACCELERATE + REVERSE + SPEED + SLOW + BRAKE + FIRE + + FLARE + SMALL_MEDIPACK + LARGE_MEDIPACK + PREVIOUS_WEAPON + NEXT_WEAPON + WEAPON_1 + WEAPON_2 + WEAPON_3 + WEAPON_4 + WEAPON_5 + WEAPON_6 + WEAPON_7 + WEAPON_8 + WEAPON_9 + WEAPON_10 + + SELECT + DESELECT PAUSE - STEPLEFT - STEPRIGHT + INVENTORY + SAVE + LOAD @section Misc.ActionID */ @@ -43,21 +70,48 @@ The following constants are inside ActionID. static const std::unordered_map ACTION_IDS { - { "FORWARD", ActionID::Forward }, - { "BACK", ActionID::Back }, - { "LEFT", ActionID::Left }, - { "RIGHT", ActionID::Right }, - { "CROUCH", ActionID::Crouch }, - { "SPRINT", ActionID::Sprint }, - { "WALK", ActionID::Walk }, - { "JUMP", ActionID::Jump }, - { "ACTION", ActionID::Action }, - { "DRAW", ActionID::DrawWeapon }, - { "FLARE", ActionID::Flare}, - { "LOOK", ActionID::Look }, - { "ROLL", ActionID::Roll }, - { "INVENTORY", ActionID::Option }, - { "PAUSE", ActionID::Pause }, - { "STEPLEFT", ActionID::LeftStep }, - { "STEPRIGHT", ActionID::RightStep } + { "FORWARD", In::Forward }, + { "BACK", In::Back }, + { "LEFT", In::Left }, + { "RIGHT", In::Right }, + { "STEP_LEFT", In::StepLeft }, + { "STEP_RIGHT", In::StepRight }, + { "WALK", In::Walk }, + { "SPRINT", In::Sprint }, + { "CROUCH", In::Crouch }, + { "JUMP", In::Jump }, + { "ROLL", In::Roll }, + { "ACTION", In::Action }, + { "DRAW", In::Draw }, + { "LOOK", In::Look }, + + { "ACCELERATE", In::Accelerate }, + { "REVERSE", In::Reverse }, + { "SPEED", In::Speed }, + { "SLOW", In::Slow }, + { "BRAKE", In::Brake }, + { "FIRE", In::Fire }, + + { "FLARE", In::Flare }, + { "SMALL_MEDIPACK", In::SmallMedipack }, + { "LARGE_MEDIPACK", In::LargeMedipack }, + { "PREVIOUS_WEAPON", In::PreviousWeapon }, + { "NEXT_WEAPON", In::NextWeapon }, + { "WEAPON_1", In::Weapon1 }, + { "WEAPON_2", In::Weapon2 }, + { "WEAPON_3", In::Weapon3 }, + { "WEAPON_4", In::Weapon4 }, + { "WEAPON_5", In::Weapon5 }, + { "WEAPON_6", In::Weapon6 }, + { "WEAPON_7", In::Weapon7 }, + { "WEAPON_8", In::Weapon8 }, + { "WEAPON_9", In::Weapon9 }, + { "WEAPON_10", In::Weapon10 }, + + { "SELECT", In::Select }, + { "DESELECT", In::Deselect }, + { "PAUSE", In::Pause }, + { "INVENTORY", In::Inventory }, + { "SAVE", In::Save }, + { "LOAD", In::Load } }; diff --git a/TombEngine/Scripting/Internal/TEN/Misc/Miscellaneous.cpp b/TombEngine/Scripting/Internal/TEN/Misc/Miscellaneous.cpp index 7ad3e6a7f..ec72e44bd 100644 --- a/TombEngine/Scripting/Internal/TEN/Misc/Miscellaneous.cpp +++ b/TombEngine/Scripting/Internal/TEN/Misc/Miscellaneous.cpp @@ -340,8 +340,8 @@ namespace Misc //end static std::tuple PercentToScreen(double x, double y) { - auto fWidth = static_cast(g_Configuration.Width); - auto fHeight = static_cast(g_Configuration.Height); + auto fWidth = static_cast(g_Configuration.ScreenWidth); + auto fHeight = static_cast(g_Configuration.ScreenHeight); int resX = static_cast(std::round(fWidth / 100.0 * x)); int resY = static_cast(std::round(fHeight / 100.0 * y)); //todo this still assumes a resolution of 800/600. account for this somehow @@ -357,8 +357,8 @@ namespace Misc //@treturn float y coordinate as percentage static std::tuple ScreenToPercent(int x, int y) { - auto fWidth = static_cast(g_Configuration.Width); - auto fHeight = static_cast(g_Configuration.Height); + auto fWidth = static_cast(g_Configuration.ScreenWidth); + auto fHeight = static_cast(g_Configuration.ScreenHeight); double resX = x / fWidth * 100.0; double resY = y / fHeight * 100.0; return std::make_tuple(resX, resY); diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 81c4d69fd..05568ed8e 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -9,9 +9,6 @@ #include "Game/Lara/lara_helpers.h" #include "Game/Setup.h" #include "Objects/objectslist.h" -#include "Specific/level.h" -#include "Math/Math.h" - #include "Scripting/Internal/ReservedScriptNames.h" #include "Scripting/Internal/ScriptAssert.h" #include "Scripting/Internal/ScriptUtil.h" @@ -21,6 +18,8 @@ #include "Scripting/Internal/TEN/Objects/ObjectsHandler.h" #include "Scripting/Internal/TEN/Rotation/Rotation.h" #include "Scripting/Internal/TEN/Vec3/Vec3.h" +#include "Specific/level.h" +#include "Math/Math.h" using namespace TEN::Collision::Floordata; using namespace TEN::Effects::Items; @@ -43,9 +42,7 @@ static auto newindex_error = newindex_error_maker(Moveable, LUA_CLASS_NAME); Moveable::Moveable(short num, bool alreadyInitialized) : m_item{ &g_Level.Items[num] }, m_num{ num }, m_initialized{ alreadyInitialized } { if (alreadyInitialized) - { dynamic_cast(g_GameScriptEntities)->AddMoveableToMap(m_item, this); - } }; Moveable::Moveable(Moveable&& other) noexcept : @@ -60,14 +57,13 @@ Moveable::Moveable(Moveable&& other) noexcept : } } - Moveable::~Moveable() { if (m_item && g_GameScriptEntities) dynamic_cast(g_GameScriptEntities)->RemoveMoveableFromMap(m_item, this); } -bool operator==(Moveable const& first, Moveable const& second) +bool operator ==(const Moveable& first, const Moveable& second) { return first.m_item == second.m_item; } @@ -96,15 +92,15 @@ most can just be ignored (see usage). */ static std::unique_ptr Create( GAME_OBJECT_ID objID, - std::string const & name, - Vec3 const & pos, - TypeOrNil const & rot, + const std::string& name, + const Vec3& pos, + const TypeOrNil& rot, TypeOrNil room, TypeOrNil animNumber, TypeOrNil frameNumber, TypeOrNil hp, TypeOrNil ocb, - TypeOrNil const & aiBits + const TypeOrNil& aiBits ) { short num = CreateItem(); @@ -112,17 +108,21 @@ static std::unique_ptr Create( if (ScriptAssert(ptr->SetName(name), "Could not set name for Moveable; returning an invalid object.")) { - ItemInfo* item = &g_Level.Items[num]; + auto* item = &g_Level.Items[num]; + + ptr->SetObjectID(objID); + if (std::holds_alternative(room)) { ptr->SetPos(pos, false); ptr->SetRoomNumber(std::get(room)); } else + { ptr->SetPos(pos, true); + } ptr->SetRot(USE_IF_HAVE(Rotation, rot, Rotation{})); - ptr->SetObjectID(objID); ptr->Init(); ptr->SetAnimNumber(USE_IF_HAVE(int, animNumber, 0)); @@ -137,10 +137,11 @@ static std::unique_ptr Create( dynamic_cast(g_GameScriptEntities)->AddMoveableToMap(item, ptr.get()); // add to name map too? } + return ptr; } -void Moveable::Register(sol::table & parent) +void Moveable::Register(sol::table& parent) { parent.new_usertype(LUA_CLASS_NAME, sol::call_constructor, Create, @@ -420,13 +421,16 @@ void Moveable::Init() { bool cond = IsPointInRoom(m_item->Pose.Position, m_item->RoomNumber); std::string err{ "Position of item \"{}\" does not match its room ID." }; + if (!ScriptAssertF(cond, err, m_item->Name)) { - ScriptWarn("Resetting to the center of the room."); + ScriptWarn("Resetting to room center."); auto center = GetRoomCenter(m_item->RoomNumber); - // reset position but not rotation + + // Reset position, but not orientation. m_item->Pose.Position = center; } + InitializeItem(m_num); m_initialized = true; } @@ -442,7 +446,7 @@ void Moveable::SetObjectID(GAME_OBJECT_ID id) m_item->ResetModelToDefault(); } -void SetLevelFuncCallback(TypeOrNil const & cb, std::string const & callerName, Moveable & mov, std::string & toModify) +void SetLevelFuncCallback(const TypeOrNil& cb, const std::string& callerName, Moveable& mov, std::string& toModify) { if (std::holds_alternative(cb)) { @@ -456,7 +460,8 @@ void SetLevelFuncCallback(TypeOrNil const & cb, std::string const & c } else { - ScriptAssert(false, "Tried giving " + mov.m_item->Name + ScriptAssert( + false, "Tried giving " + mov.m_item->Name + " a non-LevelFunc object as an arg to " + callerName); } @@ -468,12 +473,12 @@ short Moveable::GetIndex() const return m_num; } -void Moveable::SetOnHit(TypeOrNil const & cb) +void Moveable::SetOnHit(const TypeOrNil& cb) { SetLevelFuncCallback(cb, ScriptReserved_SetOnHit, *this, m_item->Callbacks.OnHit); } -void Moveable::SetOnKilled(TypeOrNil const & cb) +void Moveable::SetOnKilled(const TypeOrNil& cb) { SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->Callbacks.OnKilled); } @@ -486,7 +491,7 @@ void Moveable::SetOnKilled(TypeOrNil const & cb) // print(obj1:GetName() .. " collided with " .. obj2:GetName()) // end // baddy:SetOnCollidedWithObject(LevelFuncs.objCollided) -void Moveable::SetOnCollidedWithObject(TypeOrNil const & cb) +void Moveable::SetOnCollidedWithObject(const TypeOrNil& cb) { SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->Callbacks.OnObjectCollided); } @@ -499,7 +504,7 @@ void Moveable::SetOnCollidedWithObject(TypeOrNil const & cb) // print(obj:GetName() .. " collided with room geometry") // end // baddy:SetOnCollidedWithRoom(LevelFuncs.roomCollided) -void Moveable::SetOnCollidedWithRoom(TypeOrNil const & cb) +void Moveable::SetOnCollidedWithRoom(const TypeOrNil& cb) { SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithRoom, *this, m_item->Callbacks.OnRoomCollided); } @@ -509,20 +514,19 @@ std::string Moveable::GetName() const return m_item->Name; } -bool Moveable::SetName(std::string const & id) +bool Moveable::SetName(const std::string& id) { if (!ScriptAssert(!id.empty(), "Name cannot be blank. Not setting name.")) - { return false; - } if (s_callbackSetName(id, m_num)) { - // remove the old name if we have one + // Remove old name if it exists. if (id != m_item->Name) { - if(!m_item->Name.empty()) + if (!m_item->Name.empty()) s_callbackRemoveName(m_item->Name); + m_item->Name = id; } } @@ -533,6 +537,7 @@ bool Moveable::SetName(std::string const & id) return false; } + return true; } @@ -551,7 +556,7 @@ Vec3 Moveable::GetPos() const // @function Moveable:SetPosition // @tparam Vec3 position the new position of the moveable // @bool[opt] updateRoom Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true) -void Moveable::SetPos(Vec3 const& pos, sol::optional updateRoom) +void Moveable::SetPos(const Vec3& pos, sol::optional updateRoom) { auto prevPos = m_item->Pose.Position.ToVector3(); pos.StoreInPose(m_item->Pose); @@ -560,17 +565,10 @@ void Moveable::SetPos(Vec3 const& pos, sol::optional updateRoom) if (m_initialized && willUpdate) { - bool roomUpdated = false; + bool isRoomUpdated = m_item->IsLara() ? UpdateLaraRoom(m_item, pos.y) : UpdateItemRoom(m_item->Index); - if (m_item->IsLara()) - roomUpdated = UpdateLaraRoom(m_item, pos.y); - else - roomUpdated = UpdateItemRoom(m_item->Index); - - // In case direct portal room update didn't happen, and distance between old and new - // points is significant, do a predictive room update. - - if (!roomUpdated && + // In case direct portal room update didn't happen and distance between old and new points is significant, do predictive room update. + if (!isRoomUpdated && (willUpdate || Vector3::Distance(prevPos, m_item->Pose.Position.ToVector3()) > BLOCK(1))) { int potentialNewRoom = FindRoomNumber(m_item->Pose.Position, m_item->RoomNumber); @@ -629,7 +627,7 @@ short Moveable::GetHP() const // @tparam int HP the amount of HP to give the moveable void Moveable::SetHP(short hp) { - if(Objects[m_item->ObjectNumber].intelligent && hp < 0) + if (Objects[m_item->ObjectNumber].intelligent && hp < 0) { if (hp != NOT_TARGETABLE) { @@ -726,7 +724,7 @@ short Moveable::GetLocationAI() const return creature->LocationAI; } - TENLog("Trying to get LocationAI value from a non creature moveable. Value does not exist so it's returning 0.", LogLevel::Error); + TENLog("Trying to get LocationAI value from non-creature moveable. Value does not exist so it's returning 0.", LogLevel::Error); return 0; } @@ -1144,8 +1142,7 @@ void Moveable::SetVisible(bool isVisible) void Moveable::Invalidate() { - // keep m_item as it is so that we can properly remove it from the moveables set when - // its destructor is called + // Keep m_item as-is so it can be properly removed from moveables set when destructor is called. m_num = NO_ITEM; m_initialized = false; } diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h index 44852d803..62419180f 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h @@ -31,17 +31,17 @@ public: Moveable(short num, bool alreadyInitialized = true); ~Moveable(); - Moveable& operator=(Moveable const& other) = delete; - Moveable(Moveable const& other) = delete; - Moveable(Moveable && other) noexcept; + Moveable& operator =(const Moveable& other) = delete; + Moveable(const Moveable& other) = delete; + Moveable(Moveable&& other) noexcept; - static void Register(sol::table & parent); + static void Register(sol::table& parent); [[nodiscard]] GAME_OBJECT_ID GetObjectID() const; void SetObjectID(GAME_OBJECT_ID id); [[nodiscard]] std::string GetName() const; - bool SetName(std::string const &); + bool SetName(const std::string&); [[nodiscard]] bool GetValid() const; void Invalidate(); @@ -50,10 +50,10 @@ public: [[nodiscard]] Vec3 GetPos() const; [[nodiscard]] Vec3 GetJointPos(int index) const; - void SetPos(Vec3 const& pos, sol::optional updateRoom); + void SetPos(const Vec3& pos, sol::optional updateRoom); [[nodiscard]] Rotation GetRot() const; - void SetRot(Rotation const& rot); + void SetRot(const Rotation& rot); [[nodiscard]] int GetStateNumber() const; void SetStateNumber(int stateNumber); @@ -118,17 +118,17 @@ public: void Explode(); void Shatter(); - void SetOnHit(TypeOrNil const& cb); - void SetOnKilled(TypeOrNil const& cb); - void SetOnCollidedWithObject(TypeOrNil const& cb); - void SetOnCollidedWithRoom(TypeOrNil const& cb); + void SetOnHit(const TypeOrNil& cb); + void SetOnKilled(const TypeOrNil& cb); + void SetOnCollidedWithObject(const TypeOrNil& cb); + void SetOnCollidedWithRoom(const TypeOrNil& cb); [[nodiscard]] short GetStatus() const; void Init(); - friend bool operator==(Moveable const&, Moveable const&); - friend void SetLevelFuncCallback(TypeOrNil const& cb, std::string const & callerName, Moveable& mov, std::string& toModify); + friend bool operator ==(const Moveable&, const Moveable&); + friend void SetLevelFuncCallback(const TypeOrNil& cb, const std::string& callerName, Moveable& mov, std::string& toModify); short GetIndex() const; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h index a1fd7aeb6..0453eba25 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectIDs.h @@ -168,9 +168,7 @@ The following constants are inside ObjID. CENTAUR_MUTANT DOPPELGANGER NATLA - WINGED_NATLA GIANT_MUTANT - PROJ_NATLA PROJ_SHARD PROJ_BOMB YETI @@ -768,7 +766,7 @@ The following constants are inside ObjID. LARA_START_POS TELEPORTER LIFT_TELEPORTER - LASERS + LASER_BARRIER STEAM_LASERS FLOOR_LASERS KILL_ALL_TRIGGERS @@ -802,7 +800,7 @@ The following constants are inside ObjID. WATERFALLSS1 WATERFALLSS2 FISHTANK - BACON_REFERENCE + DOPPELGANGER_ORIGIN CORPSE WRAITH_TRAP MESHSWAP1 @@ -1343,9 +1341,7 @@ static const std::unordered_map kObjIDs { { "CENTAUR_MUTANT", ID_CENTAUR_MUTANT }, { "DOPPELGANGER", ID_DOPPELGANGER }, { "NATLA", ID_NATLA }, - { "WINGED_NATLA", ID_WINGED_NATLA }, { "GIANT_MUTANT", ID_GIANT_MUTANT }, - { "PROJ_NATLA", ID_PROJ_NATLA }, { "PROJ_SHARD", ID_PROJ_SHARD }, { "PROJ_BOMB", ID_PROJ_BOMB }, { "YETI", ID_YETI }, @@ -1976,7 +1972,7 @@ static const std::unordered_map kObjIDs { { "WATERFALLSS1", ID_WATERFALLSS1 }, { "WATERFALLSS2", ID_WATERFALLSS2 }, { "FISHTANK", ID_FISHTANK }, - { "BACON_REFERENCE", ID_BACON_REFERENCE }, + { "DOPPELGANGER_ORIGIN", ID_DOPPELGANGER_ORIGIN }, { "CORPSE", ID_CORPSE }, { "WRAITH_TRAP", ID_WRAITH_TRAP }, { "MESHSWAP1", ID_MESHSWAP1 }, diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp index c1971998f..ee5fc97c4 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp @@ -160,8 +160,8 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) : [this](auto && ... param) { return RemoveName(std::forward(param)...); }); m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_ObjID, kObjIDs); - m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomFlagID, kRoomFlagIDs); - m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomReverb, kRoomReverbTypes); + m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomFlagID, TOOM_FLAG_IDS); + m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomReverb, ROOM_REVERB_TYPES); m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_LaraWeaponType, LaraWeaponTypeMap); m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_HandStatus, HandStatusMap); } @@ -200,7 +200,7 @@ void ObjectsHandler::TestCollidingObjects() void ObjectsHandler::AssignLara() { - m_table_objects.set(ScriptReserved_Lara, LaraObject(Lara.ItemNumber, true)); + m_table_objects.set(ScriptReserved_Lara, LaraObject(LaraItem->Index, true)); } bool ObjectsHandler::NotifyKilled(ItemInfo* key) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomFlags.h b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomFlags.h index 5517f0dd6..8499ed1c8 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomFlags.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomFlags.h @@ -29,13 +29,13 @@ The following constants are inside RoomFlagID. @table CONSTANT_STRING_HERE */ -static const std::unordered_map kRoomFlagIDs +static const std::unordered_map TOOM_FLAG_IDS { - {"WATER", RoomEnvFlags::ENV_FLAG_WATER}, - {"QUICKSAND", RoomEnvFlags::ENV_FLAG_SWAMP}, - {"SKYBOX", RoomEnvFlags::ENV_FLAG_OUTSIDE}, - {"WIND", RoomEnvFlags::ENV_FLAG_WIND}, - {"COLD", RoomEnvFlags::ENV_FLAG_COLD}, - {"DAMAGE", RoomEnvFlags::ENV_FLAG_DAMAGE}, - {"NOLENSFLARE", RoomEnvFlags::ENV_FLAG_NO_LENSFLARE} + { "WATER", RoomEnvFlags::ENV_FLAG_WATER }, + { "QUICKSAND", RoomEnvFlags::ENV_FLAG_SWAMP }, + { "SKYBOX", RoomEnvFlags::ENV_FLAG_OUTSIDE }, + { "WIND", RoomEnvFlags::ENV_FLAG_WIND }, + { "COLD", RoomEnvFlags::ENV_FLAG_COLD }, + { "DAMAGE", RoomEnvFlags::ENV_FLAG_DAMAGE }, + { "NOLENSFLARE", RoomEnvFlags::ENV_FLAG_NO_LENSFLARE } }; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp index 95478ba37..ff0b8f5a8 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.cpp @@ -102,7 +102,7 @@ void Room::SetName(const std::string& name) if (!ScriptAssert(!name.empty(), "Unable to set name. Name cannot be blank.")) return; - // Remove the old name if we have one. + // Remove old name if it already exists. if (s_callbackSetName(name, m_room)) { s_callbackRemoveName(m_room.name); @@ -123,9 +123,13 @@ bool Room::GetFlag(RoomEnvFlags flag) const void Room::SetFlag(RoomEnvFlags flag, bool value) { if (value) + { m_room.flags |= flag; + } else + { m_room.flags &= ~flag; + } } bool Room::IsTagPresent(const std::string& tag) const @@ -133,6 +137,7 @@ bool Room::IsTagPresent(const std::string& tag) const if (m_room.tags.empty()) return false; - return std::any_of(m_room.tags.begin(), m_room.tags.end(), + return std::any_of( + m_room.tags.begin(), m_room.tags.end(), [&tag](const std::string& value) { return (value == tag); }); } diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.h index 555522da0..41a1e132f 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomObject.h @@ -2,14 +2,10 @@ #include "Game/room.h" #include "Scripting/Internal/TEN/Objects/NamedBase.h" -namespace sol -{ - class state; -} - +namespace sol { class state; } +enum class ReverbType; class ScriptColor; class Vec3; -enum class ReverbType; class Room : public NamedBase { diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomReverbTypes.h b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomReverbTypes.h index f391134d8..5c9e78bfb 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomReverbTypes.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Room/RoomReverbTypes.h @@ -27,11 +27,11 @@ The following constants are inside RoomReverb. @table CONSTANT_STRING_HERE */ -static const std::unordered_map kRoomReverbTypes +static const std::unordered_map ROOM_REVERB_TYPES { - {"OUTSIDE", ReverbType::Outside}, - {"SMALL", ReverbType::Small}, - {"MEDIUM", ReverbType::Medium}, - {"LARGE", ReverbType::Large}, - {"PIPE", ReverbType::Pipe} + { "OUTSIDE", ReverbType::Outside }, + { "SMALL", ReverbType::Small }, + { "MEDIUM", ReverbType::Medium }, + { "LARGE", ReverbType::Large }, + { "PIPE", ReverbType::Pipe } }; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp index db7899343..417416730 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp @@ -17,7 +17,7 @@ Sink static auto index_error = index_error_maker(Sink, ScriptReserved_Sink); static auto newindex_error = newindex_error_maker(Sink, ScriptReserved_Sink); -Sink::Sink(SinkInfo & ref) : m_sink{ref} +Sink::Sink(SinkInfo& ref) : m_sink{ref} {}; void Sink::Register(sol::table& parent) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.h index 88f2d1e30..8c01b14d0 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.h @@ -3,10 +3,7 @@ #include "Objects/Sink.h" #include "Math/Math.h" -namespace sol -{ - class state; -} +namespace sol { class state; } class Vec3; class Sink : public NamedBase @@ -16,18 +13,18 @@ public: Sink(SinkInfo& ref); ~Sink() = default; - Sink& operator=(Sink const& other) = delete; + Sink& operator =(const Sink& other) = delete; Sink(Sink const& other) = delete; - static void Register(sol::table &); + static void Register(sol::table& parent); Vec3 GetPos() const; - void SetPos(Vec3 const& pos); + void SetPos(const Vec3& pos); int GetStrength() const; void SetStrength(int strength); std::string GetName() const; - void SetName(std::string const &); + void SetName(const std::string&); private: SinkInfo& m_sink; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h index 8b4a463b8..fba9bb0ec 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Volume/VolumeObject.h @@ -3,11 +3,7 @@ #include "Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h" #include "Scripting/Internal/TEN/Objects/NamedBase.h" -namespace sol -{ - class state; -} - +namespace sol { class state; } class Rotation; class Vec3; diff --git a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp index 365f6f069..b33d67ff3 100644 --- a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp +++ b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp @@ -78,7 +78,7 @@ void Rotation::StoreInPHDPos(Pose& pose) const Rotation::operator Vector3() const { - return Vector3{ x, y, z }; + return Vector3(x, y, z); }; /*** diff --git a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.h b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.h index d5a6a135a..7abacbbaf 100644 --- a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.h +++ b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.h @@ -1,19 +1,15 @@ #pragma once #include "Math/Objects/EulerAngles.h" -namespace sol -{ - class state; -} - +namespace sol { class state; } class Pose; class Rotation { public: - float x { 0 }; - float y { 0 }; - float z { 0 }; + float x = 0; + float y = 0; + float z = 0; Rotation() = default; Rotation(float aX, float aY, float aZ); diff --git a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp index 5be48c13c..788bfbe98 100644 --- a/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Strings/StringsHandler.cpp @@ -113,7 +113,7 @@ void StringsHandler::ProcessDisplayStrings(float deltaTime) { if (!endOfLife || str.m_isInfinite) { - char const* cstr = str.m_isTranslated ? g_GameFlow->GetString(str.m_key.c_str()) : str.m_key.c_str(); + auto cstr = str.m_isTranslated ? g_GameFlow->GetString(str.m_key.c_str()) : str.m_key.c_str(); int flags = 0; if (str.m_flags[static_cast(DisplayStringOptions::CENTER)]) diff --git a/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h b/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h index 63af2c55d..8325fbda7 100644 --- a/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h +++ b/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h @@ -3,6 +3,7 @@ class GameVector; class Pose; class Vector3i; + namespace sol { class state; } class Vec3 diff --git a/TombEngine/Shaders/Blending.hlsli b/TombEngine/Shaders/Blending.hlsli index aaeb09be4..2d119c00c 100644 --- a/TombEngine/Shaders/Blending.hlsli +++ b/TombEngine/Shaders/Blending.hlsli @@ -135,7 +135,7 @@ float4 DoLaserBarrierEffect(float3 input, float4 output, float2 uv, float faceFa noisix.x = noisix.x > 0.9 ? 0.7 : noisix.x; noisix.y = noisix.y > 0.9 ? 0.7 : noisix.y; noisix.z = noisix.z > 0.9 ? 0.7 : noisix.z; - color.rgb *= noisix + 1.3f; + color.rgb += noisix + 0.5f; color.rgb -= noisix + 0.2f; float frequency = 0.1; @@ -161,8 +161,7 @@ float4 DoLaserBarrierEffect(float3 input, float4 output, float2 uv, float faceFa noiseValue2 += AnimatedNebula(uv/2, timeUniform * 0.05f); - color.rgb -= noiseValue - 0.7f; - color.rgb *= noiseValue2 + 1.0f; + color.rgb *= noiseValue2 + 0.6f; color.rgb += noiseValue3; color.a *= noiseValue + 0.01f; diff --git a/TombEngine/Shaders/DX11_InstancedSprites.fx b/TombEngine/Shaders/DX11_InstancedSprites.fx index 58b8b1e15..43fcc019a 100644 --- a/TombEngine/Shaders/DX11_InstancedSprites.fx +++ b/TombEngine/Shaders/DX11_InstancedSprites.fx @@ -16,6 +16,7 @@ struct PixelShaderInput float4 PositionCopy: TEXCOORD2; float4 FogBulbs : TEXCOORD3; float DistanceFog : FOG; + uint InstanceID : SV_InstanceID; }; struct InstancedSprite @@ -58,6 +59,7 @@ PixelShaderInput VS(VertexShaderInput input, uint InstanceID : SV_InstanceID) output.PositionCopy = output.Position; output.Color = Sprites[InstanceID].Color; output.UV = float2(Sprites[InstanceID].UV[0][input.PolyIndex], Sprites[InstanceID].UV[1][input.PolyIndex]); + output.InstanceID = InstanceID; output.FogBulbs = DoFogBulbsForVertex(worldPosition); output.DistanceFog = DoDistanceFogForVertex(worldPosition); @@ -81,13 +83,11 @@ float Contrast(float Input, float ContrastPower) #endif } -float4 PS(PixelShaderInput input, uint InstanceID : SV_InstanceID) : SV_TARGET +float4 PS(PixelShaderInput input) : SV_TARGET { float4 output = Texture.Sample(Sampler, input.UV) * input.Color; - //DoAlphaTest(output); - - if (Sprites[InstanceID].IsSoftParticle == 1) + if (Sprites[input.InstanceID].IsSoftParticle == 1) { float particleDepth = input.PositionCopy.z / input.PositionCopy.w; input.PositionCopy.xy /= input.PositionCopy.w; diff --git a/TombEngine/Shaders/DX11_InstancedStatics.fx b/TombEngine/Shaders/DX11_InstancedStatics.fx index 99ee5a8f7..26a0249a6 100644 --- a/TombEngine/Shaders/DX11_InstancedStatics.fx +++ b/TombEngine/Shaders/DX11_InstancedStatics.fx @@ -81,13 +81,15 @@ PixelShaderOutput PS(PixelShaderInput input) uint mode = StaticMeshes[input.InstanceID].LightInfo.y; uint numLights = StaticMeshes[input.InstanceID].LightInfo.x; + float3 normal = normalize(input.Normal); + float3 color = (mode == 0) ? CombineLights( StaticMeshes[input.InstanceID].AmbientLight.xyz, input.Color.xyz, tex.xyz, input.WorldPosition, - normalize(input.Normal), + normal, input.Sheen, StaticMeshes[input.InstanceID].InstancedStaticLights, numLights, diff --git a/TombEngine/Shaders/DX11_Items.fx b/TombEngine/Shaders/DX11_Items.fx index c4441c9d2..e34e5915a 100644 --- a/TombEngine/Shaders/DX11_Items.fx +++ b/TombEngine/Shaders/DX11_Items.fx @@ -28,7 +28,6 @@ struct PixelShaderInput float2 UV: TEXCOORD1; float4 Color: COLOR; float Sheen: SHEEN; - float3x3 TBN: TBN; float4 PositionCopy: TEXCOORD2; float4 FogBulbs : TEXCOORD3; float DistanceFog : FOG; @@ -45,8 +44,7 @@ Texture2D Texture : register(t0); SamplerState Sampler : register(s0); Texture2D NormalTexture : register(t1); - -//TextureCube Reflection : register (t4); +SamplerState NormalSampler : register(s1); PixelShaderInput VS(VertexShaderInput input) { @@ -60,12 +58,6 @@ PixelShaderInput VS(VertexShaderInput input) output.Normal = normal; output.UV = input.UV; output.WorldPosition = worldPosition; - - float3 Tangent = mul(float4(input.Tangent, 0), world).xyz; - float3 Bitangent = cross(normal, Tangent); - float3x3 TBN = float3x3(Tangent, Bitangent, normal); - - output.TBN = transpose(TBN); // Calculate vertex effects float wibble = Wibble(input.Effects.xyz, input.Hash); @@ -95,9 +87,7 @@ PixelShaderOutput PS(PixelShaderInput input) float4 tex = Texture.Sample(Sampler, input.UV); DoAlphaTest(tex); - float3 normal = NormalTexture.Sample(Sampler, input.UV).rgb; - normal = normal * 2 - 1; - normal = normalize(mul(input.TBN, normal)); + float3 normal = normalize(input.Normal); float3 color = (BoneLightModes[input.Bone / 4][input.Bone % 4] == 0) ? CombineLights( diff --git a/TombEngine/Shaders/DX11_Rooms.fx b/TombEngine/Shaders/DX11_Rooms.fx index 9a2b288e0..038af9b97 100644 --- a/TombEngine/Shaders/DX11_Rooms.fx +++ b/TombEngine/Shaders/DX11_Rooms.fx @@ -26,18 +26,21 @@ struct PixelShaderInput float3 Normal: NORMAL; float2 UV: TEXCOORD0; float4 Color: COLOR; - float3x3 TBN : TBN; float4 PositionCopy : TEXCOORD1; float4 FogBulbs : TEXCOORD2; float DistanceFog : FOG; + float3 Tangent: TANGENT; + float3 Binormal: BINORMAL; }; Texture2D Texture : register(t0); SamplerState Sampler : register(s0); Texture2D NormalTexture : register(t1); +SamplerState NormalTextureSampler : register(s1); Texture2D CausticsTexture : register(t2); +SamplerState CausticsTextureSampler : register(s2); struct PixelShaderOutput { @@ -87,9 +90,8 @@ PixelShaderInput VS(VertexShaderInput input) #endif output.WorldPosition = input.Position.xyz; - - float3x3 TBN = float3x3(input.Tangent, cross(input.Normal,input.Tangent), input.Normal); - output.TBN = TBN; + output.Tangent = input.Tangent; + output.Binormal = input.Binormal; output.FogBulbs = DoFogBulbsForVertex(output.WorldPosition); output.DistanceFog = DoDistanceFogForVertex(output.WorldPosition); @@ -97,13 +99,11 @@ PixelShaderInput VS(VertexShaderInput input) return output; } -float3 UnpackNormalMap(float3 compressedNormalMap) +float3 UnpackNormalMap(float4 n) { - float2 normalXY = compressedNormalMap.rg; - - normalXY = normalXY * float2(2.0f, 2.0f) - float2(1.0f, 1.0f); - float normalZ = sqrt(saturate(1.0f - dot(normalXY, normalXY))); - return float3(normalXY.xy, normalZ); + n = n * 2.0f - 1.0f; + n.z = saturate(1.0f - dot(n.xy, n.xy)); + return n.xyz; } PixelShaderOutput PS(PixelShaderInput input) @@ -114,8 +114,9 @@ PixelShaderOutput PS(PixelShaderInput input) DoAlphaTest(output.Color); - float3 normal = UnpackNormalMap(NormalTexture.Sample(Sampler, input.UV).rgb); - normal = normalize(mul(normal, input.TBN)); + float3x3 TBN = float3x3(input.Tangent, input.Binormal, input.Normal); + float3 normal = UnpackNormalMap(NormalTexture.Sample(NormalTextureSampler, input.UV)); + normal = normalize(mul(normal, TBN)); float3 lighting = input.Color.xyz; bool doLights = true; @@ -132,7 +133,7 @@ PixelShaderOutput PS(PixelShaderInput input) DoSpotLightShadow(input.WorldPosition, lighting); } } - + DoBlobShadows(input.WorldPosition, lighting); if (doLights) @@ -149,7 +150,7 @@ PixelShaderOutput PS(PixelShaderInput input) continue; lightVec = normalize(lightVec); - float d = saturate(dot(normal, -lightVec )); + float d = saturate(dot(normal, lightVec )); if (d < 0) continue; @@ -167,7 +168,7 @@ PixelShaderOutput PS(PixelShaderInput input) float fracY = position.y - floor(position.y / 2048.0f) * 2048.0f; float fracZ = position.z - floor(position.z / 2048.0f) * 2048.0f; - float attenuation = saturate(dot(float3(0.0f, 1.0f, 0.0f), normal)); + float attenuation = saturate(dot(float3(0.0f, -1.0f, 0.0f), normal)); float3 blending = abs(normal); blending = normalize(max(blending, 0.00001f)); @@ -175,13 +176,13 @@ PixelShaderOutput PS(PixelShaderInput input) blending /= float3(b, b, b); float3 p = float3(fracX, fracY, fracZ) / 2048.0f; - float3 xaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.y * CausticsScale.x, p.z * CausticsScale.y)).xyz; - float3 yaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.z * CausticsScale.y)).xyz; - float3 zaxis = CausticsTexture.Sample(Sampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.y * CausticsScale.y)).xyz; + float3 xaxis = CausticsTexture.Sample(CausticsTextureSampler, CausticsStartUV + float2(p.y * CausticsScale.x, p.z * CausticsScale.y)).xyz; + float3 yaxis = CausticsTexture.Sample(CausticsTextureSampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.z * CausticsScale.y)).xyz; + float3 zaxis = CausticsTexture.Sample(CausticsTextureSampler, CausticsStartUV + float2(p.x * CausticsScale.x, p.y * CausticsScale.y)).xyz; lighting += float3((xaxis * blending.x + yaxis * blending.y + zaxis * blending.z).xyz) * attenuation * 2.0f; } - + output.Depth = output.Color.w > 0.0f ? float4(input.PositionCopy.z / input.PositionCopy.w, 0.0f, 0.0f, 1.0f) : float4(0.0f, 0.0f, 0.0f, 0.0f); diff --git a/TombEngine/Shaders/DX11_Sprites.fx b/TombEngine/Shaders/DX11_Sprites.fx index 154b7756b..5f1df82fb 100644 --- a/TombEngine/Shaders/DX11_Sprites.fx +++ b/TombEngine/Shaders/DX11_Sprites.fx @@ -60,7 +60,8 @@ float4 PS(PixelShaderInput input) : SV_TARGET { float particleDepth = input.PositionCopy.z / input.PositionCopy.w; input.PositionCopy.xy /= input.PositionCopy.w; - float2 texCoord = 0.5f * (float2(input.PositionCopy.x, -input.PositionCopy.y) + 1); + + float2 texCoord = 0.5f * (float2(input.PositionCopy.x, -input.PositionCopy.y) + 1.0f); float sceneDepth = DepthMap.Sample(DepthMapSampler, texCoord).r; sceneDepth = LinearizeDepth(sceneDepth, NearPlane, FarPlane); diff --git a/TombEngine/Shaders/DX11_Statics.fx b/TombEngine/Shaders/DX11_Statics.fx index 95a5c8d81..0f129f918 100644 --- a/TombEngine/Shaders/DX11_Statics.fx +++ b/TombEngine/Shaders/DX11_Statics.fx @@ -71,13 +71,15 @@ PixelShaderOutput PS(PixelShaderInput input) float4 tex = Texture.Sample(Sampler, input.UV); DoAlphaTest(tex); + float3 normal = normalize(input.Normal); + float3 color = (LightType == 0) ? CombineLights( AmbientLight.xyz, input.Color.xyz, tex.xyz, input.WorldPosition, - normalize(input.Normal), + normal, input.Sheen, StaticLights, NumStaticLights, diff --git a/TombEngine/Shaders/ShaderLight.hlsli b/TombEngine/Shaders/ShaderLight.hlsli index 3aab7fe50..33f0ff065 100644 --- a/TombEngine/Shaders/ShaderLight.hlsli +++ b/TombEngine/Shaders/ShaderLight.hlsli @@ -33,7 +33,7 @@ float3 DoSpecularSun(float3 n, ShaderLight light, float strength) return float3(0, 0, 0); else { - float3 lightDir = normalize(light.Direction); + float3 lightDir = -normalize(light.Direction); float3 reflectDir = reflect(lightDir, n); float3 color = light.Color.xyz; @@ -51,22 +51,43 @@ float3 DoSpecularSpot(float3 pos, float3 n, ShaderLight light, float strength) else { float3 lightPos = light.Position.xyz; - float radius = light.OutRange; + float3 direction = light.Direction.xyz; + float innerRange = light.In; + float outerRange = light.Out; + float coneIn = light.InRange; + float coneOut = light.OutRange; - float dist = distance(lightPos, pos); - if (dist > radius) + float3 lightVec = normalize(pos - lightPos); + float distance = length(lightVec); + + if (distance > outerRange) return float3(0, 0, 0); else { - float3 lightDir = normalize(lightPos - pos); - float3 reflectDir = reflect(lightDir, n); + float cosine = dot(lightVec, direction); - float3 color = light.Color.xyz; - float intensity = saturate(light.Intensity); - float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * SPEC_FACTOR); - float attenuation = (radius - dist) / radius; + float minCosineIn = cos(coneIn * (PI / 180.0f)); + float attenuationIn = max((cosine - minCosineIn), 0.0f) / (1.0f - minCosineIn); - return attenuation * spec * color * intensity; + float minCosineOut = cos(coneOut * (PI / 180.0f)); + float attenuationOut = max((cosine - minCosineOut), 0.0f) / (1.0f - minCosineOut); + + float attenuation = saturate(attenuationIn * 2.0f + attenuationOut); + + if (attenuation > 0.0f) + { + float3 lightDir = -lightVec; + float3 reflectDir = reflect(lightDir, n); + + float3 color = light.Color.xyz; + float intensity = saturate(light.Intensity); + float spec = pow(saturate(dot(CamDirectionWS.xyz, reflectDir)), strength * SPEC_FACTOR); + float attenuation = (outerRange - distance) / outerRange; + + return attenuation * spec * color * intensity; + } + else + return float3(0, 0, 0); } } } @@ -127,27 +148,25 @@ float3 DoSpotLight(float3 pos, float3 n, ShaderLight light) float3 lightPos = light.Position.xyz; float3 color = light.Color.xyz; float intensity = saturate(light.Intensity); - float3 direction = -light.Direction.xyz; + float3 direction = light.Direction.xyz; float innerRange = light.In; float outerRange = light.Out; float coneIn = light.InRange; float coneOut = light.OutRange; - float3 lightVec = (lightPos - pos); + float3 lightVec = normalize(pos - lightPos); float distance = length(lightVec); if (distance > outerRange) return float3(0, 0, 0); else { - lightVec = normalize(lightVec); - - float d = saturate(dot(n, lightVec)); + float d = saturate(dot(n, -lightVec)); if (d < 0) return float3(0, 0, 0); else { - float cosine = dot(-lightVec, direction); + float cosine = dot(lightVec, direction); float minCosineIn = cos(coneIn * (PI / 180.0f)); float attenuationIn = max((cosine - minCosineIn), 0.0f) / (1.0f - minCosineIn); @@ -172,18 +191,15 @@ float3 DoDirectionalLight(float3 pos, float3 n, ShaderLight light) { float3 color = light.Color.xyz; float3 intensity = light.Intensity; - float3 direction = light.Direction.xyz; + float3 direction = -light.Direction.xyz; - direction = normalize(direction+pos); - - //the scalar representing the line from the direction - //to the normal n - float d = max(dot(direction,n), .0f); + float d = max(dot(direction, n), .0f); if (d > 0.f) { - return (color*intensity*d); + return (color * intensity * d); } + return float3(0, 0, 0); } diff --git a/TombEngine/Shaders/VertexInput.hlsli b/TombEngine/Shaders/VertexInput.hlsli index b79c21885..197c17d80 100644 --- a/TombEngine/Shaders/VertexInput.hlsli +++ b/TombEngine/Shaders/VertexInput.hlsli @@ -1,14 +1,16 @@ -struct VertexShaderInput -{ - float3 Position: POSITION0; - float3 Normal: NORMAL0; - float2 UV: TEXCOORD0; - float4 Color: COLOR0; - float3 Tangent: TANGENT0; - unsigned int AnimationFrameOffset: ANIMATIONFRAMEOFFSET; - float4 Effects: EFFECTS; - float Bone: BLENDINDICES; - unsigned int PolyIndex : POLYINDEX; - unsigned int Index: DRAWINDEX; - int Hash : HASH; -}; \ No newline at end of file + +struct VertexShaderInput +{ + float3 Position: POSITION0; + float3 Normal: NORMAL0; + float2 UV: TEXCOORD0; + float4 Color: COLOR0; + float3 Tangent: TANGENT0; + float3 Binormal: BINORMAL0; + unsigned int AnimationFrameOffset: ANIMATIONFRAMEOFFSET; + float4 Effects: EFFECTS; + float Bone: BLENDINDICES; + unsigned int PolyIndex : POLYINDEX; + unsigned int Index: DRAWINDEX; + int Hash : HASH; +}; diff --git a/TombEngine/Sound/sound.cpp b/TombEngine/Sound/sound.cpp index 262125766..783366db5 100644 --- a/TombEngine/Sound/sound.cpp +++ b/TombEngine/Sound/sound.cpp @@ -19,6 +19,8 @@ HSAMPLE BASS_SamplePointer[SOUND_MAX_SAMPLES]; HSTREAM BASS_3D_Mixdown; HFX BASS_FXHandler[(int)SoundFilter::Count]; +HMODULE ADPCMLibrary = NULL; // Temporary hack for unexpected ADPCM codec unload on Win11 systems. + SoundEffectSlot SoundSlot[SOUND_MAX_CHANNELS]; SoundTrackSlot SoundtrackSlot[(int)SoundTrackType::Count]; @@ -39,10 +41,10 @@ std::map SoundTrackMap; std::unordered_map SoundTracks; std::vector Subtitles; -static int SecretSoundIndex = 5; constexpr int LegacyLoopingTrackMin = 98; constexpr int LegacyLoopingTrackMax = 111; +static int SecretSoundIndex = 5; static int GlobalMusicVolume; static int GlobalFXVolume; @@ -175,7 +177,7 @@ bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition, float // We set it to -2 afterwards to prevent further debug message firings. if (sampleIndex == -1) { - TENLog("Non present effect: " + std::to_string(effectID), LogLevel::Warning); + TENLog("Missing sound effect: " + std::to_string(effectID), LogLevel::Warning); g_Level.SoundMap[effectID] = -2; return false; } @@ -214,7 +216,7 @@ bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition, float pitch += ((static_cast(GetRandomControl()) / static_cast(RAND_MAX)) - 0.5f) * SOUND_MAX_PITCH_CHANGE * 2.0f; // Calculate sound radius and distance to sound - float radius = (float)(sampleInfo->Radius) * SECTOR(1); + float radius = (float)(sampleInfo->Radius) * BLOCK(1); float distance = Sound_DistanceToListener(position); // Don't play sound if it's too far from listener's position. @@ -940,6 +942,9 @@ void Sound_Init(const std::string& gameDirectory) if (!g_Configuration.EnableSound) return; + + // HACK: Manually force-load ADPCM codec, because on Win11 systems it may suddenly unload otherwise. + ADPCMLibrary = LoadLibrary("msadp32.acm"); BASS_Init(g_Configuration.SoundDevice, 44100, BASS_DEVICE_3D, WindowsHandle, NULL); if (Sound_CheckBASSError("Initializing BASS sound device", true)) @@ -997,11 +1002,15 @@ void Sound_Init(const std::string& gameDirectory) // Must be called on engine quit. void Sound_DeInit() { - if (g_Configuration.EnableSound) - { - TENLog("Shutting down BASS...", LogLevel::Info); - BASS_Free(); - } + if (!g_Configuration.EnableSound) + return; + + TENLog("Shutting down BASS...", LogLevel::Info); + BASS_Free(); + + // HACK: Manually unload previously loaded ADPCM codec. + if (ADPCMLibrary != NULL) + FreeLibrary(ADPCMLibrary); } bool Sound_CheckBASSError(const char* message, bool verbose, ...) diff --git a/TombEngine/Sound/sound.h b/TombEngine/Sound/sound.h index de5913331..5b5c5cfab 100644 --- a/TombEngine/Sound/sound.h +++ b/TombEngine/Sound/sound.h @@ -150,7 +150,6 @@ struct SoundSourceInfo extern std::map SoundTrackMap; extern std::unordered_map SoundTracks; -extern int SecretSoundIndex; bool SoundEffect(int effectID, Pose* position, SoundEnvironment condition = SoundEnvironment::Land, float pitchMultiplier = 1.0f, float gainMultiplier = 1.0f); void StopSoundEffect(short effectID); diff --git a/TombEngine/Specific/Input/Input.cpp b/TombEngine/Specific/Input/Input.cpp index bb0460a3e..571500ed2 100644 --- a/TombEngine/Specific/Input/Input.cpp +++ b/TombEngine/Specific/Input/Input.cpp @@ -8,12 +8,10 @@ #include #include "Game/items.h" -#include "Game/Lara/lara.h" -#include "Game/Lara/lara_helpers.h" -#include "Game/Lara/lara_tests.h" #include "Game/savegame.h" #include "Renderer/Renderer11.h" #include "Sound/sound.h" +#include "Specific/clock.h" #include "Specific/trutils.h" #include "Specific/winmain.h" @@ -26,51 +24,6 @@ namespace TEN::Input { constexpr int AXIS_DEADZONE = 8000; - const char* g_KeyNames[] = - { - "", "Esc", "1", "2", "3", "4", "5", "6", - "7", "8", "9", "0", "-", "+", "Back", "Tab", - "Q", "W", "E", "R", "T", "Y", "U", "I", - "O", "P", "<", ">", "Enter", "Ctrl", "A", "S", - "D", "F", "G", "H", "J", "K", "L", ";", - "'", "`", "Shift", "#", "Z", "X", "C", "V", - "B", "N", "M", ",", ".", "/", "Shift", "Pad X", - "Alt", "Space", "Caps Lock", NULL, NULL, NULL, NULL, NULL, - - NULL, NULL, NULL, NULL, NULL, "Num Lock", "Scroll Lock", "Pad 7", - "Pad 8", "Pad 9", "Pad -", "Pad 4", "Pad 5", "Pad 6", "Pad +", "Pad 1", - "Pad 2", "Pad 3", "Pad 0", "Pad.", NULL, NULL, "\\", NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, "Pad Enter", "Ctrl", NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, "Shift", NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, "Pad /", NULL, NULL, - "Alt", NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - NULL, NULL, NULL, NULL, NULL, NULL, NULL, "Home", - "Up", "Page Up", NULL, "Left", NULL, "Right", NULL, "End", - "Down", "Page Down", "Insert", "Del", NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - - "Joy 1", "Joy 2", "Joy 3", "Joy 4", "Joy 5", "Joy 6", "Joy 7", "Joy 8", - "Joy 9", "Joy 10", "Joy 11", "Joy 12", "Joy 13", "Joy 14", "Joy 15", "Joy 16", - - "X-", "X+", "Y-", "Y+", "Z-", "Z+", "W-", "W+", - "Joy LT", "Joy LT", "Joy RT", "Joy RT", "D-Pad Up", "D-Pad Down", "D-Pad Left", "D-Pad Right" - }; - // OIS interfaces InputManager* OisInputManager = nullptr; Keyboard* OisKeyboard = nullptr; @@ -85,36 +38,99 @@ namespace TEN::Input std::vector KeyMap = {}; std::vector AxisMap = {}; + // Deprecated legacy input bit fields. int DbInput = 0; int TrInput = 0; - auto DefaultBindings = std::vector + const std::vector g_KeyNames = { - KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_PERIOD, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_RCONTROL, KC_SPACE, KC_COMMA, KC_NUMPAD0, KC_END, KC_ESCAPE, KC_P, KC_PGUP, KC_PGDOWN, - /*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/ // TODO: Dedicated vehicle actions. - KC_F5, KC_F6, KC_RETURN, KC_ESCAPE, KC_NUMPAD0 - }; - auto XInputBindings = std::vector - { - XB_AXIS_X_NEG, XB_AXIS_X_POS, XB_AXIS_Y_NEG, XB_AXIS_Y_POS, XB_AXIS_LTRIGGER_NEG, XB_AXIS_RTRIGGER_NEG, XB_RSHIFT, XB_X, XB_A, XB_Y, XB_DPAD_DOWN, XB_LSHIFT, XB_B, XB_SELECT, XB_START, XB_LSTICK, XB_RSTICK, - /*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE,*/ // TODO: Dedicated vehicle actions. - KC_F5, KC_F6, KC_RETURN, KC_ESCAPE, KC_NUMPAD0 + "", "Esc", "1", "2", "3", "4", "5", "6", + "7", "8", "9", "0", "-", "+", "Back", "Tab", + "Q", "W", "E", "R", "T", "Y", "U", "I", + "O", "P", "[", "]", "Enter", "Ctrl", "A", "S", + "D", "F", "G", "H", "J", "K", "L", ";", + "'", "`", "Shift", "#", "Z", "X", "C", "V", + "B", "N", "M", ",", ".", "/", "Shift", "Pad X", + "Alt", "Space", "Caps Lock", "F1", "F2", "F3", "F4", "F5", + + "F6", "F7", "F8", "F9", "F10", "Num Lock", "Scroll Lock", "Pad 7", + "Pad 8", "Pad 9", "Pad -", "Pad 4", "Pad 5", "Pad 6", "Pad +", "Pad 1", + "Pad 2", "Pad 3", "Pad 0", "Pad .", "", "", "\\", "F11", + "F12", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "Pad Enter", "Ctrl", "", "", + "", "", "", "", "", "", "", "", + "", "", "Shift", "", "", "", "", "", + "", "", "", "", "", "Pad /", "", "", + "Alt", "", "", "", "", "", "", "", + + "", "", "", "", "", "", "", "Home", + "Up", "Page Up", "", "Left", "", "Right", "", "End", + "Down", "Page Down", "Insert", "Del", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", "", "", + + "Joy 1", "Joy 2", "Joy 3", "Joy 4", "Joy 5", "Joy 6", "Joy 7", "Joy 8", + "Joy 9", "Joy 10", "Joy 11", "Joy 12", "Joy 13", "Joy 14", "Joy 15", "Joy 16", + + "X-", "X+", "Y-", "Y+", "Z-", "Z+", "W-", "W+", + "Joy LT", "Joy LT", "Joy RT", "Joy RT", "D-Pad Up", "D-Pad Down", "D-Pad Left", "D-Pad Right" }; - // Input bindings. These are primitive mappings to actions. - bool ConflictingKeys[KEY_COUNT]; - short KeyboardLayout[2][KEY_COUNT] = + // Binding rows: + // 1. General actions + // 2. Vehicle actions + // 3. Quick actions + // 4. Menu actions + + std::vector> Bindings = { { - KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_PERIOD, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_RCONTROL, KC_SPACE, KC_COMMA, KC_NUMPAD0, KC_END, KC_ESCAPE, KC_P, KC_PGUP, KC_PGDOWN, - /*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE*/ // TODO: Dedicated vehicle actions. - }, - { - KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_PERIOD, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_RCONTROL, KC_SPACE, KC_COMMA, KC_NUMPAD0, KC_END, KC_ESCAPE, KC_P, KC_PGUP, KC_PGDOWN, - /*KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE*/ // TODO: Dedicated vehicle actions. + // Default + { + KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_DELETE, KC_PGDOWN, KC_RSHIFT, KC_SLASH, KC_PERIOD, KC_RMENU, KC_END, KC_RCONTROL, KC_SPACE, KC_NUMPAD0, + KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE, + KC_COMMA, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_RETURN, KC_ESCAPE, KC_P, KC_ESCAPE, KC_F5, KC_F6 + }, + + // User + { + KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_DELETE, KC_PGDOWN, KC_RSHIFT, KC_SLASH, KC_PERIOD, KC_RMENU, KC_END, KC_RCONTROL, KC_SPACE, KC_NUMPAD0, + KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE, + KC_COMMA, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_RETURN, KC_ESCAPE, KC_P, KC_ESCAPE, KC_F5, KC_F6 + } } }; + const auto DefaultGenericBindings = std::vector + { + KC_UP, KC_DOWN, KC_LEFT, KC_RIGHT, KC_DELETE, KC_PGDOWN, KC_RSHIFT, KC_SLASH, KC_PERIOD, KC_RMENU, KC_END, KC_RCONTROL, KC_SPACE, KC_NUMPAD0, + KC_RCONTROL, KC_DOWN, KC_SLASH, KC_RSHIFT, KC_RMENU, KC_SPACE, + KC_COMMA, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_RETURN, KC_ESCAPE, KC_P, KC_ESCAPE, KC_F5, KC_F6, KC_NUMPAD0 + }; + const auto DefaultXInputBindings = std::vector + { + XB_AXIS_X_NEG, XB_AXIS_X_POS, XB_AXIS_Y_NEG, XB_AXIS_Y_POS, XB_LSTICK, XB_RSTICK, XB_RSHIFT, XB_AXIS_RTRIGGER_NEG, XB_AXIS_LTRIGGER_NEG, XB_X, XB_B, XB_A, XB_Y, XB_LSHIFT, + XB_A, XB_AXIS_X_POS, XB_AXIS_RTRIGGER_NEG, XB_RSHIFT, XB_X, XB_AXIS_LTRIGGER_NEG, + XB_DPAD_DOWN, KC_MINUS, KC_EQUALS, KC_LBRACKET, KC_RBRACKET, KC_1, KC_2, KC_3, KC_4, KC_5, KC_6, KC_7, KC_8, KC_9, KC_0, + KC_RETURN, XB_SELECT, XB_START, XB_SELECT, KC_F5, KC_F6, KC_NUMPAD0 + }; + + auto ConflictingKeys = std::array{}; + void InitializeEffect() { OisEffect = new Effect(Effect::ConstantForce, Effect::Constant); @@ -154,9 +170,13 @@ namespace TEN::Input OisInputManager->enableAddOnFactory(InputManager::AddOn_All); if (OisInputManager->getNumberOfDevices(OISKeyboard) == 0) + { TENLog("Keyboard not found!", LogLevel::Warning); + } else + { OisKeyboard = (Keyboard*)OisInputManager->createInputObject(OISKeyboard, true); + } } catch (OIS::Exception& ex) { @@ -185,7 +205,7 @@ namespace TEN::Input if (ApplyDefaultXInputBindings()) { g_Configuration.EnableRumble = (OisRumble != nullptr); - g_Configuration.EnableThumbstickCameraControl = true; + g_Configuration.EnableThumbstickCamera = true; SaveConfiguration(); } } @@ -259,7 +279,7 @@ namespace TEN::Input { for (int i = 0; i < KEY_COUNT; i++) { - if (KeyboardLayout[layout][i] == index) + if (Bindings[layout][i] == index) return true; } } @@ -269,7 +289,7 @@ namespace TEN::Input int WrapSimilarKeys(int source) { - // Merge right/left Ctrl, Shift, and Alt. + // Merge right/left Ctrl, Shift, Alt. switch (source) { @@ -290,13 +310,13 @@ namespace TEN::Input { for (int i = 0; i < KEY_COUNT; i++) { - int key = KeyboardLayout[0][i]; + int key = Bindings[0][i]; ConflictingKeys[i] = false; for (int j = 0; j < KEY_COUNT; j++) { - if (key != KeyboardLayout[1][j]) + if (key != Bindings[1][j]) continue; ConflictingKeys[i] = true; @@ -309,14 +329,22 @@ namespace TEN::Input { for (int layout = 0; layout <= 1; layout++) { - if (KeyboardLayout[layout][KEY_FORWARD] == index) + if (Bindings[layout][KEY_FORWARD] == index) + { AxisMap[(unsigned int)InputAxis::MoveVertical] = 1.0f; - else if (KeyboardLayout[layout][KEY_BACK] == index) + } + else if (Bindings[layout][KEY_BACK] == index) + { AxisMap[(unsigned int)InputAxis::MoveVertical] = -1.0f; - else if (KeyboardLayout[layout][KEY_LEFT] == index) + } + else if (Bindings[layout][KEY_LEFT] == index) + { AxisMap[(unsigned int)InputAxis::MoveHorizontal] = -1.0f; - else if (KeyboardLayout[layout][KEY_RIGHT] == index) + } + else if (Bindings[layout][KEY_RIGHT] == index) + { AxisMap[(unsigned int)InputAxis::MoveHorizontal] = 1.0f; + } } } @@ -369,14 +397,22 @@ namespace TEN::Input // Otherwise, register as camera movement input (for future). // NOTE: abs() operations are needed to avoid issues with inverted axes on different controllers. - if (KeyboardLayout[1][KEY_FORWARD] == usedIndex) + if (Bindings[1][KEY_FORWARD] == usedIndex) + { AxisMap[InputAxis::MoveVertical] = abs(scaledValue); - else if (KeyboardLayout[1][KEY_BACK] == usedIndex) + } + else if (Bindings[1][KEY_BACK] == usedIndex) + { AxisMap[InputAxis::MoveVertical] = -abs(scaledValue); - else if (KeyboardLayout[1][KEY_LEFT] == usedIndex) + } + else if (Bindings[1][KEY_LEFT] == usedIndex) + { AxisMap[InputAxis::MoveHorizontal] = -abs(scaledValue); - else if (KeyboardLayout[1][KEY_RIGHT] == usedIndex) + } + else if (Bindings[1][KEY_RIGHT] == usedIndex) + { AxisMap[InputAxis::MoveHorizontal] = abs(scaledValue); + } else if (!LayoutContainsIndex(usedIndex)) { unsigned int camAxisIndex = (unsigned int)std::clamp((unsigned int)InputAxis::CameraVertical + axis % 2, @@ -467,7 +503,7 @@ namespace TEN::Input { for (int layout = 1; layout >= 0; layout--) { - int key = KeyboardLayout[layout][number]; + int key = Bindings[layout][number]; if (layout == 0 && ConflictingKeys[number]) continue; @@ -489,148 +525,35 @@ namespace TEN::Input } } - void HandlePlayerHotkeys(ItemInfo* item) + static void HandleHotkeyActions() { - static const auto UNAVAILABLE_FLARE_STATES = std::vector - { - LS_CRAWL_FORWARD, - LS_CRAWL_TURN_LEFT, - LS_CRAWL_TURN_RIGHT, - LS_CRAWL_BACK, - LS_CRAWL_TO_HANG, - LS_CRAWL_TURN_180 - }; - - auto& lara = *GetLaraInfo(item); - - // Handle hardcoded action-to-key mappings. - ActionMap[(int)In::Save].Update(KeyMap[KC_F5] ? true : false); - ActionMap[(int)In::Load].Update(KeyMap[KC_F6] ? true : false); - ActionMap[(int)In::Select].Update((KeyMap[KC_RETURN] || Key(KEY_ACTION)) ? true : false); - ActionMap[(int)In::Deselect].Update((KeyMap[KC_ESCAPE] || Key(KEY_DRAW)) ? true : false); - - // Handle target switch when locked on to an entity. - if (lara.Control.HandStatus == HandStatus::WeaponReady && - lara.TargetEntity != nullptr) - { - if (IsClicked(In::Look)) - { - ActionMap[(int)In::SwitchTarget].Update(true); - //ActionMap[(int)In::Look].Clear(); - } - else - { - ClearAction(In::SwitchTarget); - } - } - else - { - ClearAction(In::SwitchTarget); - } - - // Handle flares. - if (IsClicked(In::Flare)) - { - if (TestState(item->Animation.ActiveState, UNAVAILABLE_FLARE_STATES)) - SayNo(); - } - - // Handle weapon hotkeys. - if (KeyMap[KC_1] && lara.Weapons[(int)LaraWeaponType::Pistol].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::Pistol; - - if (KeyMap[KC_2] && lara.Weapons[(int)LaraWeaponType::Shotgun].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::Shotgun; - - if (KeyMap[KC_3] && lara.Weapons[(int)LaraWeaponType::Uzi].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::Uzi; - - if (KeyMap[KC_4] && lara.Weapons[(int)LaraWeaponType::Revolver].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::Revolver; - - if (KeyMap[KC_5] && lara.Weapons[(int)LaraWeaponType::GrenadeLauncher].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::GrenadeLauncher; - - if (KeyMap[KC_6] && lara.Weapons[(int)LaraWeaponType::Crossbow].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::Crossbow; - - if (KeyMap[KC_7] && lara.Weapons[(int)LaraWeaponType::HarpoonGun].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::HarpoonGun; - - if (KeyMap[KC_8] && lara.Weapons[(int)LaraWeaponType::HK].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::HK; - - if (KeyMap[KC_9] && lara.Weapons[(int)LaraWeaponType::RocketLauncher].Present) - lara.Control.Weapon.RequestGunType = LaraWeaponType::RocketLauncher; - - // Handle medipack hotkeys. - static bool dbMedipack = true; - if ((KeyMap[KC_MINUS] || KeyMap[KC_EQUALS]) && dbMedipack) - { - if ((item->HitPoints > 0 && item->HitPoints < LARA_HEALTH_MAX) || - lara.Status.Poison) - { - bool hasUsedMedipack = false; - - if (KeyMap[KC_MINUS] && - lara.Inventory.TotalSmallMedipacks != 0) - { - hasUsedMedipack = true; - - item->HitPoints += LARA_HEALTH_MAX / 2; - if (item->HitPoints > LARA_HEALTH_MAX) - item->HitPoints = LARA_HEALTH_MAX; - - if (lara.Inventory.TotalSmallMedipacks != -1) - lara.Inventory.TotalSmallMedipacks--; - } - else if (KeyMap[KC_EQUALS] && - lara.Inventory.TotalLargeMedipacks != 0) - { - hasUsedMedipack = true; - item->HitPoints = LARA_HEALTH_MAX; - - if (lara.Inventory.TotalLargeMedipacks != -1) - lara.Inventory.TotalLargeMedipacks--; - } - - if (hasUsedMedipack) - { - lara.Status.Poison = 0; - SoundEffect(SFX_TR4_MENU_MEDI, nullptr, SoundEnvironment::Always); - Statistics.Game.HealthUsed++; - } - } - } - dbMedipack = (KeyMap[KC_MINUS] || KeyMap[KC_EQUALS]) ? false : true; - - // Handle saying "no". - static bool dbNo = true; - if (KeyMap[KC_N] && dbNo) - SayNo(); - dbNo = KeyMap[KC_N] ? false : true; + // Save screenshot. + static bool dbScreenshot = true; + if (KeyMap[KC_SYSRQ] && dbScreenshot) + g_Renderer.SaveScreenshot(); + dbScreenshot = !KeyMap[KC_SYSRQ]; // Toggle fullscreen. static bool dbFullscreen = true; if ((KeyMap[KC_LMENU] || KeyMap[KC_RMENU]) && KeyMap[KC_RETURN] && dbFullscreen) { - g_Configuration.Windowed = !g_Configuration.Windowed; + g_Configuration.EnableWindowedMode = !g_Configuration.EnableWindowedMode; SaveConfiguration(); g_Renderer.ToggleFullScreen(); } - dbFullscreen = ((KeyMap[KC_LMENU] || KeyMap[KC_RMENU]) && KeyMap[KC_RETURN]) ? false : true; + dbFullscreen = !((KeyMap[KC_LMENU] || KeyMap[KC_RMENU]) && KeyMap[KC_RETURN]); if (!DebugMode) return; - // Handle debug page switch. + // Switch debug page. static bool dbDebugPage = true; if ((KeyMap[KC_F10] || KeyMap[KC_F11]) && dbDebugPage) g_Renderer.SwitchDebugPage(KeyMap[KC_F10]); - dbDebugPage = (KeyMap[KC_F10] || KeyMap[KC_F11]) ? false : true; + dbDebugPage = !(KeyMap[KC_F10] || KeyMap[KC_F11]); } - void UpdateRumble() + static void UpdateRumble() { if (!OisRumble || !OisEffect || !RumbleInfo.Power) return; @@ -686,24 +609,26 @@ namespace TEN::Input ReadGameController(); DefaultConflict(); - // Update action map (mappable actions only). + // Update action map. for (int i = 0; i < KEY_COUNT; i++) - { - // TODO: Poll analog value of key. Potentially, any can be a trigger. - ActionMap[i].Update(Key(i) ? true : false); - } + ActionMap[i].Update(Key(i)); if (applyQueue) ApplyActionQueue(); // Additional handling. - HandlePlayerHotkeys(item); + HandleHotkeyActions(); SolveActionCollisions(); // Port actions back to legacy bit fields. for (const auto& action : ActionMap) { - int actionBit = 1 << (int)action.GetID(); + // TEMP FIX: Only port up to 32 bits. + auto actionID = action.GetID(); + if ((int)actionID >= 32) + break; + + int actionBit = 1 << (int)actionID; DbInput |= action.IsClicked() ? actionBit : 0; TrInput |= action.IsHeld() ? actionBit : 0; @@ -755,13 +680,13 @@ namespace TEN::Input if (i >= KEY_COUNT) break; - KeyboardLayout[1][i] = bindings[i]; + Bindings[1][i] = bindings[i]; } } void ApplyDefaultBindings() { - ApplyBindings(DefaultBindings); + ApplyBindings(DefaultGenericBindings); ApplyDefaultXInputBindings(); } @@ -772,21 +697,20 @@ namespace TEN::Input for (int i = 0; i < KEY_COUNT; i++) { - if (KeyboardLayout[1][i] != KC_UNASSIGNED && KeyboardLayout[1][i] != KeyboardLayout[0][i]) + if (Bindings[1][i] != KC_UNASSIGNED && Bindings[1][i] != Bindings[0][i]) return false; } auto vendor = TEN::Utils::ToLower(OisGamepad->vendor()); - if (vendor.find("xbox") != std::string::npos || vendor.find("xinput") != std::string::npos) { - ApplyBindings(XInputBindings); + ApplyBindings(DefaultXInputBindings); for (int i = 0; i < KEY_COUNT; i++) - g_Configuration.KeyboardLayout[i] = KeyboardLayout[1][i]; + g_Configuration.Bindings[i] = Bindings[1][i]; // Additionally turn on thumbstick camera and vibration. - g_Configuration.EnableRumble = g_Configuration.EnableThumbstickCameraControl = true; + g_Configuration.EnableRumble = g_Configuration.EnableThumbstickCamera = true; return true; } @@ -800,6 +724,10 @@ namespace TEN::Input { ActionMap[(int)actionID].Clear(); + // TEMP FIX: Only port up to 32 bits. + if ((int)actionID >= 32) + return; + int actionBit = 1 << (int)actionID; DbInput &= ~actionBit; TrInput &= ~actionBit; @@ -851,16 +779,16 @@ namespace TEN::Input return ActionMap[(int)actionID].GetTimeInactive(); } - bool IsDirectionActionHeld() + bool IsDirectionalActionHeld() { return (IsHeld(In::Forward) || IsHeld(In::Back) || IsHeld(In::Left) || IsHeld(In::Right)); } bool IsWakeActionHeld() { - if (IsDirectionActionHeld() || IsHeld(In::LeftStep) || IsHeld(In::RightStep) || + if (IsDirectionalActionHeld() || IsHeld(In::StepLeft) || IsHeld(In::StepRight) || IsHeld(In::Walk) || IsHeld(In::Jump) || IsHeld(In::Sprint) || IsHeld(In::Roll) || IsHeld(In::Crouch) || - IsHeld(In::DrawWeapon) || IsHeld(In::Flare) || IsHeld(In::Action)) + IsHeld(In::Draw) || IsHeld(In::Flare) || IsHeld(In::Action)) { return true; } @@ -870,6 +798,6 @@ namespace TEN::Input bool IsOpticActionHeld() { - return (IsDirectionActionHeld() || IsHeld(In::Action) || IsHeld(In::Crouch) || IsHeld(In::Sprint)); + return (IsDirectionalActionHeld() || IsHeld(In::Action) || IsHeld(In::Crouch) || IsHeld(In::Sprint)); } } diff --git a/TombEngine/Specific/Input/Input.h b/TombEngine/Specific/Input/Input.h index 37fcae3a5..cd01ff3d2 100644 --- a/TombEngine/Specific/Input/Input.h +++ b/TombEngine/Specific/Input/Input.h @@ -12,7 +12,7 @@ namespace TEN::Input constexpr int MAX_INPUT_SLOTS = MAX_KEYBOARD_KEYS + MAX_GAMEPAD_KEYS + MAX_GAMEPAD_POV_AXES + MAX_GAMEPAD_AXES * 2; - enum XInputButtons + enum XInputButton { XB_START = MAX_KEYBOARD_KEYS, XB_SELECT, @@ -45,89 +45,78 @@ namespace TEN::Input XB_DPAD_RIGHT }; + // Deprecated. enum InputKey { KEY_FORWARD, KEY_BACK, KEY_LEFT, KEY_RIGHT, - KEY_CROUCH, - KEY_SPRINT, + KEY_LEFT_STEP, + KEY_RIGHT_STEP, KEY_WALK, + KEY_SPRINT, + KEY_CROUCH, KEY_JUMP, + KEY_ROLL, KEY_ACTION, KEY_DRAW, - KEY_FLARE, KEY_LOOK, - KEY_ROLL, - KEY_OPTION, - KEY_PAUSE, - KEY_LSTEP, - KEY_RSTEP, - /*KEY_ACCELERATE, + + KEY_ACCELERATE, KEY_REVERSE, KEY_SPEED, KEY_SLOW, KEY_BRAKE, - KEY_FIRE,*/ + KEY_FIRE, + + KEY_FLARE, + KEY_SMALL_MEDIPACK, + KEY_LARGE_MEDIPACK, + KEY_PREVIOUS_WEAPON, + KEY_NEXT_WEAPON, + KEY_WEAPON_1, + KEY_WEAPON_2, + KEY_WEAPON_3, + KEY_WEAPON_4, + KEY_WEAPON_5, + KEY_WEAPON_6, + KEY_WEAPON_7, + KEY_WEAPON_8, + KEY_WEAPON_9, + KEY_WEAPON_10, + + KEY_SELECT, + KEY_DESELECT, + KEY_PAUSE, + KEY_INVENTORY, + KEY_SAVE, + KEY_LOAD, KEY_COUNT }; + // Deprecated. enum InputActions { - IN_NONE = 0, - IN_FORWARD = (1 << KEY_FORWARD), - IN_BACK = (1 << KEY_BACK), - IN_LEFT = (1 << KEY_LEFT), - IN_RIGHT = (1 << KEY_RIGHT), - IN_CROUCH = (1 << KEY_CROUCH), - IN_SPRINT = (1 << KEY_SPRINT), - IN_WALK = (1 << KEY_WALK), - IN_JUMP = (1 << KEY_JUMP), - IN_ACTION = (1 << KEY_ACTION), - IN_DRAW = (1 << KEY_DRAW), - IN_FLARE = (1 << KEY_FLARE), - IN_LOOK = (1 << KEY_LOOK), - IN_ROLL = (1 << KEY_ROLL), - IN_OPTION = (1 << KEY_OPTION), - IN_PAUSE = (1 << KEY_PAUSE), - IN_LSTEP = (1 << KEY_LSTEP), - IN_RSTEP = (1 << KEY_RSTEP), - /*IN_ACCELERATE = (1 << KEY_ACCELERATE), - IN_REVERSE = (1 << KEY_REVERSE), - IN_SPEED = (1 << KEY_SPEED), - IN_SLOW = (1 << KEY_SLOW), - IN_BRAKE = (1 << KEY_BRAKE), - IN_FIRE = (1 << KEY_FIRE),*/ + IN_NONE = 0, - // Additional input actions without direct key relation - - IN_SAVE = (1 << (KEY_COUNT + 0)), - IN_LOAD = (1 << (KEY_COUNT + 1)), - IN_SELECT = (1 << (KEY_COUNT + 2)), - IN_DESELECT = (1 << (KEY_COUNT + 3)), - IN_LOOKSWITCH = (1 << (KEY_COUNT + 4)) + IN_FORWARD = (1 << KEY_FORWARD), + IN_BACK = (1 << KEY_BACK), + IN_LEFT = (1 << KEY_LEFT), + IN_RIGHT = (1 << KEY_RIGHT), + IN_LSTEP = (1 << KEY_LEFT_STEP), + IN_RSTEP = (1 << KEY_RIGHT_STEP), + IN_WALK = (1 << KEY_WALK), + IN_SPRINT = (1 << KEY_SPRINT), + IN_CROUCH = (1 << KEY_CROUCH), + IN_JUMP = (1 << KEY_JUMP), + IN_ROLL = (1 << KEY_ROLL), + IN_ACTION = (1 << KEY_ACTION), + IN_DRAW = (1 << KEY_DRAW), + IN_LOOK = (1 << KEY_LOOK) }; - // Temporary input constants for use with vehicles: - - // TODO: Not needed. Thought too far ahead. - constexpr int VEHICLE_IN_UP = IN_FORWARD; - constexpr int VEHICLE_IN_DOWN = IN_BACK; - constexpr int VEHICLE_IN_LEFT = IN_LEFT; - constexpr int VEHICLE_IN_RIGHT = IN_RIGHT; - - constexpr int VEHICLE_IN_ACCELERATE = IN_ACTION; - constexpr int VEHICLE_IN_REVERSE = IN_BACK; - constexpr int VEHICLE_IN_SPEED = IN_SPRINT; - constexpr int VEHICLE_IN_SLOW = IN_WALK; - constexpr int VEHICLE_IN_BRAKE = IN_JUMP; - constexpr int VEHICLE_IN_FIRE = IN_DRAW | IN_CROUCH; - - // TODO: Not needed since BRAKE is explicitly associated with dismounts anyway. - constexpr int VEHICLE_IN_DISMOUNT = IN_JUMP | IN_ROLL; - enum InputAxis { MoveVertical, @@ -154,24 +143,22 @@ namespace TEN::Input struct RumbleData { - RumbleMode Mode = RumbleMode::None; float Power = 0.0f; + RumbleMode Mode = RumbleMode::None; float LastPower = 0.0f; float FadeSpeed = 0.0f; }; - extern const char* g_KeyNames[]; - extern std::vector ActionMap; extern std::vector ActionQueue; extern std::vector KeyMap; extern std::vector AxisMap; - // Legacy input bit fields. extern int DbInput; // Debounce input. extern int TrInput; // Throttle input. - extern short KeyboardLayout[2][KEY_COUNT]; + extern const std::vector g_KeyNames; + extern std::vector> Bindings; void InitializeInput(HWND handle); void DeinitializeInput(); @@ -197,7 +184,7 @@ namespace TEN::Input float GetActionTimeActive(ActionID actionID); float GetActionTimeInactive(ActionID actionID); - bool IsDirectionActionHeld(); + bool IsDirectionalActionHeld(); bool IsWakeActionHeld(); bool IsOpticActionHeld(); } diff --git a/TombEngine/Specific/Input/InputAction.h b/TombEngine/Specific/Input/InputAction.h index d5b1605c6..25835091d 100644 --- a/TombEngine/Specific/Input/InputAction.h +++ b/TombEngine/Specific/Input/InputAction.h @@ -4,42 +4,36 @@ namespace TEN::Input { typedef enum class ActionID { - None = -1, - - // Basic control + // General actions Forward, Back, Left, Right, - Crouch, - Sprint, + StepLeft, + StepRight, Walk, + Sprint, + Crouch, Jump, - Action, - DrawWeapon, - Flare, // Convert to generic Light button under Item hotkeys section. - Look, Roll, - Option, // Move to GUI control section. - Pause, // Move to GUI control section. - LeftStep, - RightStep, + Action, + Draw, + Look, - // Vehicle control - /*Accelerate, + // Vehicle actions + Accelerate, Reverse, Speed, Slow, Brake, - Fire,*/ + Fire, - // Item hotkeys - /*Light, // Generic light button may be used for flares. - Binoculars, + // Quick actions + Flare, SmallMedipack, - BigMedipack, - NextWeapon, + LargeMedipack, PreviousWeapon, + NextWeapon, Weapon1, Weapon2, Weapon3, @@ -49,16 +43,16 @@ namespace TEN::Input Weapon7, Weapon8, Weapon9, - Weapon10,*/ + Weapon10, - // GUI control - /*Option, - Pause,*/ - Save, - Load, + // Menu actions Select, Deselect, - SwitchTarget, // Look -> SwitchTarget conversion must be handled differently. + Pause, + Inventory, + Save, + Load, + SwitchTarget, // TODO: Look -> SwitchTarget conversion must be handled differently. Count } In; @@ -68,7 +62,7 @@ namespace TEN::Input { private: // Members - ActionID ID = In::None; + ActionID ID = In::Forward; float Value = 0.0f; float PrevValue = 0.0f; float TimeActive = 0.0f; diff --git a/TombEngine/Specific/configuration.cpp b/TombEngine/Specific/configuration.cpp index b48f3c368..e29309728 100644 --- a/TombEngine/Specific/configuration.cpp +++ b/TombEngine/Specific/configuration.cpp @@ -2,17 +2,17 @@ #include "Specific/configuration.h" #include -#include "resource.h" + #include "Renderer/Renderer11.h" -#include "Scripting/Internal/LanguageScript.h" +#include "resource.h" #include "Scripting/Include/Flow/ScriptInterfaceFlowHandler.h" +#include "Scripting/Internal/LanguageScript.h" #include "Specific/Input/Input.h" #include "Specific/winmain.h" #include "Sound/sound.h" -using std::vector; -using namespace TEN::Renderer; using namespace TEN::Input; +using namespace TEN::Renderer; GameConfiguration g_Configuration; @@ -83,11 +83,11 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam) LoadResolutionsInCombobox(handle); LoadSoundDevicesInCombobox(handle); - // Set some default values + // Set some default values. g_Configuration.EnableAutoTargeting = true; g_Configuration.EnableTargetHighlighter = true; - g_Configuration.Antialiasing = AntialiasingMode::Low; + g_Configuration.AntialiasingMode = AntialiasingMode::Low; SendDlgItemMessage(handle, IDC_ANTIALIASING, BM_SETCHECK, 1, 0); g_Configuration.ShadowType = ShadowMode::Lara; @@ -96,7 +96,7 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam) g_Configuration.EnableCaustics = true; SendDlgItemMessage(handle, IDC_CAUSTICS, BM_SETCHECK, 1, 0); - g_Configuration.Windowed = true; + g_Configuration.EnableWindowedMode = true; SendDlgItemMessage(handle, IDC_WINDOWED, BM_SETCHECK, 1, 0); g_Configuration.EnableSound = true; @@ -113,19 +113,19 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam) switch (LOWORD(wParam)) { case IDOK: - // Get values from dialog components - g_Configuration.Windowed = (SendDlgItemMessage(handle, IDC_WINDOWED, BM_GETCHECK, 0, 0)); + // Get values from dialog components. + g_Configuration.EnableWindowedMode = (SendDlgItemMessage(handle, IDC_WINDOWED, BM_GETCHECK, 0, 0)); g_Configuration.ShadowType = (ShadowMode)(SendDlgItemMessage(handle, IDC_SHADOWS, BM_GETCHECK, 0, 0)); g_Configuration.EnableCaustics = (SendDlgItemMessage(handle, IDC_CAUSTICS, BM_GETCHECK, 0, 0)); - g_Configuration.Antialiasing = (AntialiasingMode)(SendDlgItemMessage(handle, IDC_ANTIALIASING, BM_GETCHECK, 0, 0)); + g_Configuration.AntialiasingMode = (AntialiasingMode)(SendDlgItemMessage(handle, IDC_ANTIALIASING, BM_GETCHECK, 0, 0)); g_Configuration.EnableSound = (SendDlgItemMessage(handle, IDC_ENABLE_SOUNDS, BM_GETCHECK, 0, 0)); selectedMode = (SendDlgItemMessage(handle, IDC_RESOLUTION, CB_GETCURSEL, 0, 0)); mode = g_Configuration.SupportedScreenResolutions[selectedMode]; - g_Configuration.Width = mode.x; - g_Configuration.Height = mode.y; + g_Configuration.ScreenWidth = mode.x; + g_Configuration.ScreenHeight = mode.y; g_Configuration.SoundDevice = (SendDlgItemMessage(handle, IDC_SNDADAPTER, CB_GETCURSEL, 0, 0)) + 1; - // Save the configuration + // Save configuration. SaveConfiguration(); EndDialog(handle, wParam); return 1; @@ -150,7 +150,7 @@ BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam) int SetupDialog() { - HRSRC res = FindResource(nullptr, MAKEINTRESOURCE(IDD_SETUP), RT_DIALOG); + auto res = FindResource(nullptr, MAKEINTRESOURCE(IDD_SETUP), RT_DIALOG); ShowCursor(true); int result = DialogBoxParamA(nullptr, MAKEINTRESOURCE(IDD_SETUP), 0, (DLGPROC)DialogProc, 0); @@ -161,135 +161,123 @@ int SetupDialog() bool SaveConfiguration() { - // Try to open the root key + // Open root key. HKEY rootKey = NULL; if (RegOpenKeyA(HKEY_CURRENT_USER, REGKEY_ROOT, &rootKey) != ERROR_SUCCESS) { - // Create the new key + // Create new key. if (RegCreateKeyA(HKEY_CURRENT_USER, REGKEY_ROOT, &rootKey) != ERROR_SUCCESS) return false; } - if (SetDWORDRegKey(rootKey, REGKEY_SCREEN_WIDTH, g_Configuration.Width) != ERROR_SUCCESS) + // Open Graphics subkey. + HKEY graphicsKey = NULL; + if (RegCreateKeyExA(rootKey, REGKEY_GRAPHICS, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &graphicsKey, NULL) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); return false; } - if (SetDWORDRegKey(rootKey, REGKEY_SCREEN_HEIGHT, g_Configuration.Height) != ERROR_SUCCESS) + // Set Graphics keys. + if (SetDWORDRegKey(graphicsKey, REGKEY_SCREEN_WIDTH, g_Configuration.ScreenWidth) != ERROR_SUCCESS || + SetDWORDRegKey(graphicsKey, REGKEY_SCREEN_HEIGHT, g_Configuration.ScreenHeight) != ERROR_SUCCESS || + SetBoolRegKey(graphicsKey, REGKEY_ENABLE_WINDOWED_MODE, g_Configuration.EnableWindowedMode) != ERROR_SUCCESS || + SetDWORDRegKey(graphicsKey, REGKEY_SHADOWS, DWORD(g_Configuration.ShadowType)) != ERROR_SUCCESS || + SetDWORDRegKey(graphicsKey, REGKEY_SHADOW_MAP_SIZE, g_Configuration.ShadowMapSize) != ERROR_SUCCESS || + SetDWORDRegKey(graphicsKey, REGKEY_SHADOW_BLOBS_MAX, g_Configuration.ShadowBlobsMax) != ERROR_SUCCESS || + SetBoolRegKey(graphicsKey, REGKEY_ENABLE_CAUSTICS, g_Configuration.EnableCaustics) != ERROR_SUCCESS || + SetDWORDRegKey(graphicsKey, REGKEY_ANTIALIASING_MODE, (DWORD)g_Configuration.AntialiasingMode) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); return false; } - if (SetBoolRegKey(rootKey, REGKEY_WINDOWED, g_Configuration.Windowed) != ERROR_SUCCESS) + // Open Sound subkey. + HKEY soundKey = NULL; + if (RegCreateKeyExA(rootKey, REGKEY_SOUND, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &soundKey, NULL) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); return false; } - if (SetDWORDRegKey(rootKey, REGKEY_SHADOWS, DWORD(g_Configuration.ShadowType)) != ERROR_SUCCESS) + // Set Sound keys. + if (SetDWORDRegKey(soundKey, REGKEY_SOUND_DEVICE, g_Configuration.SoundDevice) != ERROR_SUCCESS || + SetBoolRegKey(soundKey, REGKEY_ENABLE_SOUND, g_Configuration.EnableSound) != ERROR_SUCCESS || + SetBoolRegKey(soundKey, REGKEY_ENABLE_REVERB, g_Configuration.EnableReverb) != ERROR_SUCCESS || + SetDWORDRegKey(soundKey, REGKEY_MUSIC_VOLUME, g_Configuration.MusicVolume) != ERROR_SUCCESS || + SetDWORDRegKey(soundKey, REGKEY_SFX_VOLUME, g_Configuration.SfxVolume) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); return false; } - if (SetDWORDRegKey(rootKey, REGKEY_SHADOW_MAP, g_Configuration.ShadowMapSize) != ERROR_SUCCESS) { - RegCloseKey(rootKey); - return false; - } - - if (SetDWORDRegKey(rootKey, REGKEY_SHADOW_BLOBS, g_Configuration.ShadowMaxBlobs) != ERROR_SUCCESS) + // Open Gameplay subkey. + HKEY gameplayKey = NULL; + if (RegCreateKeyExA(rootKey, REGKEY_GAMEPLAY, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &gameplayKey, NULL) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); return false; } - if (SetBoolRegKey(rootKey, REGKEY_CAUSTICS, g_Configuration.EnableCaustics) != ERROR_SUCCESS) + // Set Gameplay keys. + if (SetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, g_Configuration.EnableSubtitles) != ERROR_SUCCESS || + SetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_TARGETING, g_Configuration.EnableAutoTargeting) != ERROR_SUCCESS || + SetBoolRegKey(gameplayKey, REGKEY_ENABLE_TARGET_HIGHLIGHTER, g_Configuration.EnableTargetHighlighter) != ERROR_SUCCESS || + SetBoolRegKey(gameplayKey, REGKEY_ENABLE_RUMBLE, g_Configuration.EnableRumble) != ERROR_SUCCESS || + SetBoolRegKey(gameplayKey, REGKEY_ENABLE_THUMBSTICK_CAMERA, g_Configuration.EnableThumbstickCamera) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); return false; } - if (SetDWORDRegKey(rootKey, REGKEY_ANTIALIASING, DWORD(g_Configuration.Antialiasing)) != ERROR_SUCCESS) + // Open Input subkey. + HKEY inputKey = NULL; + if (RegCreateKeyExA(rootKey, REGKEY_INPUT, 0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, NULL, &inputKey, NULL) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); + RegCloseKey(inputKey); return false; } - if (SetBoolRegKey(rootKey, REGKEY_ENABLE_SOUND, g_Configuration.EnableSound) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetDWORDRegKey(rootKey, REGKEY_SOUND_DEVICE, g_Configuration.SoundDevice) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetBoolRegKey(rootKey, REGKEY_SOUND_SPECIAL_FX, g_Configuration.EnableReverb) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetDWORDRegKey(rootKey, REGKEY_MUSIC_VOLUME, g_Configuration.MusicVolume) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetDWORDRegKey(rootKey, REGKEY_SFX_VOLUME, g_Configuration.SfxVolume) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - - if (SetBoolRegKey(rootKey, REGKEY_ENABLE_RUMBLE, g_Configuration.EnableRumble) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetBoolRegKey(rootKey, REGKEY_ENABLE_THUMBSTICK_CAMERA, g_Configuration.EnableThumbstickCameraControl) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetBoolRegKey(rootKey, REGKEY_ENABLE_SUBTITLES, g_Configuration.EnableSubtitles) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetBoolRegKey(rootKey, REGKEY_AUTOTARGET, g_Configuration.EnableAutoTargeting) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - if (SetBoolRegKey(rootKey, REGKEY_TARGET_HIGHLIGHTER, g_Configuration.EnableTargetHighlighter) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - + // Set Input keys. + g_Configuration.Bindings.resize(KEY_COUNT); for (int i = 0; i < KEY_COUNT; i++) { - char buffer[6]; - sprintf(buffer, "Key%d", i); + char buffer[9]; + sprintf(buffer, "Action%d", i); - if (SetDWORDRegKey(rootKey, buffer, g_Configuration.KeyboardLayout[i]) != ERROR_SUCCESS) + if (SetDWORDRegKey(inputKey, buffer, g_Configuration.Bindings[i]) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); + RegCloseKey(inputKey); return false; } } + // Close registry keys. + RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); + RegCloseKey(inputKey); return true; } @@ -306,27 +294,33 @@ void InitDefaultConfiguration() auto currentScreenResolution = GetScreenResolution(); + g_Configuration.ScreenWidth = currentScreenResolution.x; + g_Configuration.ScreenHeight = currentScreenResolution.y; + g_Configuration.ShadowType = ShadowMode::Lara; + g_Configuration.ShadowMapSize = 512; + g_Configuration.ShadowBlobsMax = 16; + g_Configuration.EnableCaustics = true; + g_Configuration.AntialiasingMode = AntialiasingMode::Low; + + g_Configuration.SoundDevice = 1; + g_Configuration.EnableSound = true; + g_Configuration.EnableReverb = true; + g_Configuration.MusicVolume = 100; + g_Configuration.SfxVolume = 100; + g_Configuration.EnableSubtitles = true; g_Configuration.EnableAutoTargeting = true; g_Configuration.EnableTargetHighlighter = true; - g_Configuration.SoundDevice = 1; - g_Configuration.EnableReverb = true; - g_Configuration.EnableCaustics = true; - g_Configuration.ShadowType = ShadowMode::Lara; - g_Configuration.EnableSound = true; - g_Configuration.Antialiasing = AntialiasingMode::Low; - g_Configuration.MusicVolume = 100; - g_Configuration.SfxVolume = 100; - g_Configuration.Width = currentScreenResolution.x; - g_Configuration.Height = currentScreenResolution.y; - g_Configuration.ShadowMapSize = 512; + g_Configuration.EnableRumble = true; + g_Configuration.EnableThumbstickCamera = false; + g_Configuration.SupportedScreenResolutions = GetAllSupportedScreenResolutions(); g_Configuration.AdapterName = g_Renderer.GetDefaultAdapterName(); } bool LoadConfiguration() { - // Try to open the root key + // Open root key. HKEY rootKey = NULL; if (RegOpenKeyA(HKEY_CURRENT_USER, REGKEY_ROOT, &rootKey) != ERROR_SUCCESS) { @@ -334,154 +328,144 @@ bool LoadConfiguration() return false; } - // Load configuration keys + // Open Graphics subkey. + HKEY graphicsKey = NULL; + if (RegOpenKeyExA(rootKey, REGKEY_GRAPHICS, 0, KEY_READ, &graphicsKey) != ERROR_SUCCESS) + { + RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + return false; + } + DWORD screenWidth = 0; - if (GetDWORDRegKey(rootKey, REGKEY_SCREEN_WIDTH, &screenWidth, 0) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - DWORD screenHeight = 0; - if (GetDWORDRegKey(rootKey, REGKEY_SCREEN_HEIGHT, &screenHeight, 0) != ERROR_SUCCESS) - return false; - - bool windowed = false; - if (GetBoolRegKey(rootKey, REGKEY_WINDOWED, &windowed, false) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - bool caustics = false; - if (GetBoolRegKey(rootKey, REGKEY_CAUSTICS, &caustics, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - DWORD antialiasing = 1; - if (GetDWORDRegKey(rootKey, REGKEY_ANTIALIASING, &antialiasing, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - + bool enableWindowedMode = false; DWORD shadowMode = 1; - if (GetDWORDRegKey(rootKey, REGKEY_SHADOWS, &shadowMode, 1) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - DWORD shadowMapSize = 512; - if (GetDWORDRegKey(rootKey, REGKEY_SHADOW_MAP, &shadowMapSize, 512) != ERROR_SUCCESS) + DWORD shadowBlobsMax = 16; + bool enableCaustics = false; + DWORD antialiasingMode = 1; + + // Load Graphics keys. + if (GetDWORDRegKey(graphicsKey, REGKEY_SCREEN_WIDTH, &screenWidth, 0) != ERROR_SUCCESS || + GetDWORDRegKey(graphicsKey, REGKEY_SCREEN_HEIGHT, &screenHeight, 0) != ERROR_SUCCESS || + GetBoolRegKey(graphicsKey, REGKEY_ENABLE_WINDOWED_MODE, &enableWindowedMode, false) != ERROR_SUCCESS || + GetDWORDRegKey(graphicsKey, REGKEY_SHADOWS, &shadowMode, 1) != ERROR_SUCCESS || + GetDWORDRegKey(graphicsKey, REGKEY_SHADOW_MAP_SIZE, &shadowMapSize, 512) != ERROR_SUCCESS || + GetDWORDRegKey(graphicsKey, REGKEY_SHADOW_BLOBS_MAX, &shadowBlobsMax, 16) != ERROR_SUCCESS || + GetBoolRegKey(graphicsKey, REGKEY_ENABLE_CAUSTICS, &enableCaustics, true) != ERROR_SUCCESS || + GetDWORDRegKey(graphicsKey, REGKEY_ANTIALIASING_MODE, &antialiasingMode, true) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); return false; } - DWORD shadowBlobs = 16; - if (GetDWORDRegKey(rootKey, REGKEY_SHADOW_BLOBS, &shadowBlobs, 16) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - bool enableSound = true; - if (GetBoolRegKey(rootKey, REGKEY_ENABLE_SOUND, &enableSound, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - bool enableReverb = true; - if (GetBoolRegKey(rootKey, REGKEY_SOUND_SPECIAL_FX, &enableReverb, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - DWORD musicVolume = 100; - if (GetDWORDRegKey(rootKey, REGKEY_MUSIC_VOLUME, &musicVolume, 100) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - DWORD sfxVolume = 100; - if (GetDWORDRegKey(rootKey, REGKEY_SFX_VOLUME, &sfxVolume, 100) != ERROR_SUCCESS) + // Open Sound subkey. + HKEY soundKey = NULL; + if (RegOpenKeyExA(rootKey, REGKEY_SOUND, 0, KEY_READ, &soundKey) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); return false; } DWORD soundDevice = 0; - if (GetDWORDRegKey(rootKey, REGKEY_SOUND_DEVICE, &soundDevice, 1) != ERROR_SUCCESS) + bool enableSound = true; + bool enableReverb = true; + DWORD musicVolume = 100; + DWORD sfxVolume = 100; + + // Load Sound keys. + if (GetDWORDRegKey(soundKey, REGKEY_SOUND_DEVICE, &soundDevice, 1) != ERROR_SUCCESS || + GetBoolRegKey(soundKey, REGKEY_ENABLE_SOUND, &enableSound, true) != ERROR_SUCCESS || + GetBoolRegKey(soundKey, REGKEY_ENABLE_REVERB, &enableReverb, true) != ERROR_SUCCESS || + GetDWORDRegKey(soundKey, REGKEY_MUSIC_VOLUME, &musicVolume, 100) != ERROR_SUCCESS || + GetDWORDRegKey(soundKey, REGKEY_SFX_VOLUME, &sfxVolume, 100) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); return false; } - bool enableThumbstickCamera = true; - if (GetBoolRegKey(rootKey, REGKEY_ENABLE_THUMBSTICK_CAMERA, &enableThumbstickCamera, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - bool enableRumble = true; - if (GetBoolRegKey(rootKey, REGKEY_ENABLE_RUMBLE, &enableRumble, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - bool autoTarget = true; - if (GetBoolRegKey(rootKey, REGKEY_AUTOTARGET, &autoTarget, true) != ERROR_SUCCESS) - { - RegCloseKey(rootKey); - return false; - } - - bool enableTargetHighlighter = true; - if (GetBoolRegKey(rootKey, REGKEY_TARGET_HIGHLIGHTER, &enableTargetHighlighter, true) != ERROR_SUCCESS) + // Open Gameplay subkey. + HKEY gameplayKey = NULL; + if (RegOpenKeyExA(rootKey, REGKEY_GAMEPLAY, 0, KEY_READ, &gameplayKey) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); return false; } bool enableSubtitles = true; - if (GetBoolRegKey(rootKey, REGKEY_ENABLE_SUBTITLES, &enableSubtitles, true) != ERROR_SUCCESS) + bool enableAutoTargeting = true; + bool enableTargetHighlighter = true; + bool enableRumble = true; + bool enableThumbstickCamera = true; + + // Load Gameplay keys. + if (GetBoolRegKey(gameplayKey, REGKEY_ENABLE_SUBTITLES, &enableSubtitles, true) != ERROR_SUCCESS || + GetBoolRegKey(gameplayKey, REGKEY_ENABLE_AUTO_TARGETING, &enableAutoTargeting, true) != ERROR_SUCCESS || + GetBoolRegKey(gameplayKey, REGKEY_ENABLE_TARGET_HIGHLIGHTER, &enableTargetHighlighter, true) != ERROR_SUCCESS || + GetBoolRegKey(gameplayKey, REGKEY_ENABLE_RUMBLE, &enableRumble, true) != ERROR_SUCCESS || + GetBoolRegKey(gameplayKey, REGKEY_ENABLE_THUMBSTICK_CAMERA, &enableThumbstickCamera, true) != ERROR_SUCCESS) { RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); return false; } - for (int i = 0; i < KEY_COUNT; i++) + // Load Input keys. + HKEY inputKey = NULL; + if (RegOpenKeyExA(rootKey, REGKEY_INPUT, 0, KEY_READ, &inputKey) == ERROR_SUCCESS) { - DWORD tempKey; - char buffer[6]; - sprintf(buffer, "Key%d", i); - - if (GetDWORDRegKey(rootKey, buffer, &tempKey, KeyboardLayout[0][i]) != ERROR_SUCCESS) + for (int i = 0; i < KEY_COUNT; i++) { - RegCloseKey(rootKey); - return false; + DWORD tempKey; + char buffer[9]; + sprintf(buffer, "Action%d", i); + + if (GetDWORDRegKey(inputKey, buffer, &tempKey, Bindings[0][i]) != ERROR_SUCCESS) + { + RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); + RegCloseKey(inputKey); + return false; + } + + g_Configuration.Bindings.push_back(tempKey); + Bindings[1][i] = tempKey; } - g_Configuration.KeyboardLayout[i] = (short)tempKey; - KeyboardLayout[1][i] = (short)tempKey; + RegCloseKey(inputKey); + } + else + { + // "Input" key does not exist; use default bindings. + g_Configuration.Bindings = Bindings[0]; } - // All configuration values were found, so I can apply configuration to the engine - g_Configuration.Width = screenWidth; - g_Configuration.Height = screenHeight; - g_Configuration.Windowed = windowed; + RegCloseKey(rootKey); + RegCloseKey(graphicsKey); + RegCloseKey(soundKey); + RegCloseKey(gameplayKey); + + // All configuration values found; apply configuration to engine. + g_Configuration.ScreenWidth = screenWidth; + g_Configuration.ScreenHeight = screenHeight; + g_Configuration.EnableWindowedMode = enableWindowedMode; g_Configuration.ShadowType = ShadowMode(shadowMode); - g_Configuration.ShadowMaxBlobs = shadowBlobs; - g_Configuration.EnableCaustics = caustics; - g_Configuration.Antialiasing = AntialiasingMode(antialiasing); + g_Configuration.ShadowBlobsMax = shadowBlobsMax; + g_Configuration.EnableCaustics = enableCaustics; + g_Configuration.AntialiasingMode = AntialiasingMode(antialiasingMode); g_Configuration.ShadowMapSize = shadowMapSize; g_Configuration.EnableSound = enableSound; @@ -490,18 +474,16 @@ bool LoadConfiguration() g_Configuration.SfxVolume = sfxVolume; g_Configuration.SoundDevice = soundDevice; - g_Configuration.EnableAutoTargeting = autoTarget; + g_Configuration.EnableAutoTargeting = enableAutoTargeting; g_Configuration.EnableTargetHighlighter = enableTargetHighlighter; g_Configuration.EnableRumble = enableRumble; - g_Configuration.EnableThumbstickCameraControl = enableThumbstickCamera; + g_Configuration.EnableThumbstickCamera = enableThumbstickCamera; g_Configuration.EnableSubtitles = enableSubtitles; - // Set legacy variables + // Set legacy variables. SetVolumeMusic(musicVolume); SetVolumeFX(sfxVolume); - RegCloseKey(rootKey); - DefaultConflict(); return true; diff --git a/TombEngine/Specific/configuration.h b/TombEngine/Specific/configuration.h index d9f521088..f7bb89acd 100644 --- a/TombEngine/Specific/configuration.h +++ b/TombEngine/Specific/configuration.h @@ -3,66 +3,77 @@ #include "Specific/Input/Input.h" #include "Renderer/Renderer11Enums.h" +using namespace TEN::Input; using namespace TEN::Math; -#define REGKEY_ROOT "Software\\TombEngine\\TombEngine" +// Directories +constexpr auto REGKEY_ROOT = "Software\\TombEngine\\1.1.0"; +constexpr auto REGKEY_GRAPHICS = "Graphics"; +constexpr auto REGKEY_SOUND = "Sound"; +constexpr auto REGKEY_GAMEPLAY = "Gameplay"; +constexpr auto REGKEY_INPUT = "Input"; -#define REGKEY_SCREEN_WIDTH "ScreenWidth" -#define REGKEY_SCREEN_HEIGHT "ScreenHeight" -#define REGKEY_WINDOWED "Windowed" -#define REGKEY_SHADOWS "Shadows" -#define REGKEY_SHADOW_MAP "ShadowMap" -#define REGKEY_SHADOW_BLOBS "ShadowBlobs" -#define REGKEY_CAUSTICS "Caustics" -#define REGKEY_ANTIALIASING "Antialiasing" +// Graphics keys +constexpr auto REGKEY_SCREEN_WIDTH = "ScreenWidth"; +constexpr auto REGKEY_SCREEN_HEIGHT = "ScreenHeight"; +constexpr auto REGKEY_ENABLE_WINDOWED_MODE = "EnableWindowedMode"; +constexpr auto REGKEY_SHADOWS = "ShadowsMode"; +constexpr auto REGKEY_SHADOW_MAP_SIZE = "ShadowMapSize"; +constexpr auto REGKEY_SHADOW_BLOBS_MAX = "ShadowBlobsMax"; +constexpr auto REGKEY_ENABLE_CAUSTICS = "EnableCaustics"; +constexpr auto REGKEY_ANTIALIASING_MODE = "AntialiasingMode"; -#define REGKEY_SOUND_DEVICE "SoundDevice" -#define REGKEY_ENABLE_SOUND "EnableSound" -#define REGKEY_SOUND_SPECIAL_FX "EnableReverb" -#define REGKEY_SFX_VOLUME "SfxVolume" -#define REGKEY_MUSIC_VOLUME "MusicVolume" +// Sound keys +constexpr auto REGKEY_SOUND_DEVICE = "SoundDevice"; +constexpr auto REGKEY_ENABLE_SOUND = "EnableSound"; +constexpr auto REGKEY_ENABLE_REVERB = "EnableReverb"; +constexpr auto REGKEY_MUSIC_VOLUME = "MusicVolume"; +constexpr auto REGKEY_SFX_VOLUME = "SfxVolume"; -#define REGKEY_ENABLE_RUMBLE "EnableRumble" -#define REGKEY_ENABLE_THUMBSTICK_CAMERA "EnableThumbstickCamera" -#define REGKEY_ENABLE_SUBTITLES "EnableSubtitles" - -#define REGKEY_TARGET_HIGHLIGHTER "EnableTargetHighlighter" -#define REGKEY_AUTOTARGET "AutoTarget" +// Gameplay keys +constexpr auto REGKEY_ENABLE_SUBTITLES = "EnableSubtitles"; +constexpr auto REGKEY_ENABLE_AUTO_TARGETING = "EnableAutoTargeting"; +constexpr auto REGKEY_ENABLE_TARGET_HIGHLIGHTER = "EnableTargetHighlighter"; +constexpr auto REGKEY_ENABLE_RUMBLE = "EnableRumble"; +constexpr auto REGKEY_ENABLE_THUMBSTICK_CAMERA = "EnableThumbstickCamera"; struct GameConfiguration { - int Width; - int Height; - bool Windowed; + // Graphics + int ScreenWidth = 0; + int ScreenHeight = 0; + bool EnableWindowedMode = false; + ShadowMode ShadowType = ShadowMode::None; + int ShadowMapSize = 1024; + int ShadowBlobsMax = 16; + bool EnableCaustics = false; + AntialiasingMode AntialiasingMode = AntialiasingMode::None; - bool EnableSound; - bool EnableReverb; - int SoundDevice; - int MusicVolume; - int SfxVolume; + // Sound + int SoundDevice = 0; + bool EnableSound = false; + bool EnableReverb = false; + int MusicVolume = 0; + int SfxVolume = 0; - bool EnableCaustics; - AntialiasingMode Antialiasing; - ShadowMode ShadowType; - int ShadowMapSize = 1024; - int ShadowMaxBlobs = 16; + // Gaeplay + bool EnableSubtitles = false; + bool EnableAutoTargeting = false; + bool EnableTargetHighlighter = false; + bool EnableRumble = false; + bool EnableThumbstickCamera = false; - bool EnableSubtitles = false; - bool EnableAutoTargeting = false; - bool EnableTargetHighlighter = false; - bool EnableRumble = false; - bool EnableThumbstickCameraControl = false; + // Input + std::vector Bindings = {}; - short KeyboardLayout[TEN::Input::KEY_COUNT]; - - std::vector SupportedScreenResolutions; - std::string AdapterName; + std::vector SupportedScreenResolutions = {}; + std::string AdapterName = {}; }; void LoadResolutionsInCombobox(HWND handle); void LoadSoundDevicesInCombobox(HWND handle); BOOL CALLBACK DialogProc(HWND handle, UINT msg, WPARAM wParam, LPARAM lParam); -int SetupDialog(); +int SetupDialog(); void InitDefaultConfiguration(); bool LoadConfiguration(); bool SaveConfiguration(); @@ -74,4 +85,4 @@ LONG SetDWORDRegKey(HKEY hKey, LPCSTR strValueName, DWORD nValue); LONG SetBoolRegKey(HKEY hKey, LPCSTR strValueName, bool bValue); LONG SetStringRegKey(HKEY hKey, LPCSTR strValueName, char* strValue); -extern GameConfiguration g_Configuration; \ No newline at end of file +extern GameConfiguration g_Configuration; diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 25cfd2f0d..66ca478b1 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -203,8 +203,8 @@ void LoadItems() void LoadObjects() { - std::memset(Objects, 0, sizeof(ObjectInfo) * ID_NUMBER_OBJECTS); - std::memset(StaticObjects, 0, sizeof(STATIC_INFO) * MAX_STATICS); + Objects.Initialize(); + std::memset(StaticObjects, 0, sizeof(StaticInfo) * MAX_STATICS); int numMeshes = ReadInt32(); TENLog("Num meshes: " + std::to_string(numMeshes), LogLevel::Info); @@ -262,7 +262,7 @@ void LoadObjects() poly.textureCoordinates.resize(count); poly.normals.resize(count); poly.tangents.resize(count); - poly.bitangents.resize(count); + poly.binormals.resize(count); for (int n = 0; n < count; n++) poly.indices[n] = ReadInt32(); @@ -273,7 +273,7 @@ void LoadObjects() for (int n = 0; n < count; n++) poly.tangents[n] = ReadVector3(); for (int n = 0; n < count; n++) - poly.bitangents[n] = ReadVector3(); + poly.binormals[n] = ReadVector3(); bucket.polygons.push_back(poly); @@ -660,7 +660,7 @@ void ReadRooms() poly.textureCoordinates.resize(count); poly.normals.resize(count); poly.tangents.resize(count); - poly.bitangents.resize(count); + poly.binormals.resize(count); for (int n = 0; n < count; n++) poly.indices[n] = ReadInt32(); @@ -671,7 +671,7 @@ void ReadRooms() for (int n = 0; n < count; n++) poly.tangents[n] = ReadVector3(); for (int n = 0; n < count; n++) - poly.bitangents[n] = ReadVector3(); + poly.binormals[n] = ReadVector3(); bucket.polygons.push_back(poly); @@ -1288,6 +1288,7 @@ bool LoadLevelFile(int levelIndex) { TENLog("Loading level file...", LogLevel::Info); + BackupLara(); CleanUp(); FreeLevel(); @@ -1413,8 +1414,8 @@ void BuildOutsideRoomsTable() { auto* room = &g_Level.Rooms[i]; - int rx = (room->x / SECTOR(1)); - int rz = (room->z / SECTOR(1)); + int rx = (room->x / BLOCK(1)); + int rz = (room->z / BLOCK(1)); for (int x = 0; x < OUTSIDE_SIZE; x++) { diff --git a/TombEngine/Specific/newtypes.h b/TombEngine/Specific/newtypes.h index 23bc8406e..6881ae985 100644 --- a/TombEngine/Specific/newtypes.h +++ b/TombEngine/Specific/newtypes.h @@ -1,32 +1,32 @@ -#pragma once -#include "framework.h" -#include "Renderer/Renderer11Enums.h" - -struct ROOM_VECTOR -{ - int roomNumber; - int yNumber; -}; - -struct POLYGON -{ - int shape; - int animatedSequence; - int animatedFrame; - float shineStrength; - std::vector indices; - std::vector textureCoordinates; - std::vector normals; - std::vector tangents; - std::vector bitangents; -}; - -struct BUCKET -{ - int texture; - BLEND_MODES blendMode; - bool animated; - int numQuads; - int numTriangles; - std::vector polygons; -}; +#pragma once +#include "framework.h" +#include "Renderer/Renderer11Enums.h" + +struct ROOM_VECTOR +{ + int roomNumber; + int yNumber; +}; + +struct POLYGON +{ + int shape; + int animatedSequence; + int animatedFrame; + float shineStrength; + std::vector indices; + std::vector textureCoordinates; + std::vector normals; + std::vector tangents; + std::vector binormals; +}; + +struct BUCKET +{ + int texture; + BLEND_MODES blendMode; + bool animated; + int numQuads; + int numTriangles; + std::vector polygons; +}; diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_itemdata_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_itemdata_generated.h index 2de5e5a85..15e52fd49 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_itemdata_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_itemdata_generated.h @@ -9,7 +9,7 @@ namespace TEN { namespace Save { -struct Position; +struct Pose; struct CreatureTarget; struct CreatureTargetBuilder; @@ -103,6 +103,8 @@ struct ShortArray; struct ShortArrayBuilder; struct ShortArrayT; +struct EulerAngles; + struct Vector2; struct Vector3; @@ -507,7 +509,7 @@ struct ItemDataUnion { bool VerifyItemData(flatbuffers::Verifier &verifier, const void *obj, ItemData type); bool VerifyItemDataVector(flatbuffers::Verifier &verifier, const flatbuffers::Vector> *values, const flatbuffers::Vector *types); -FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Position FLATBUFFERS_FINAL_CLASS { +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Pose FLATBUFFERS_FINAL_CLASS { private: int32_t x_pos_; int32_t y_pos_; @@ -518,7 +520,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Position FLATBUFFERS_FINAL_CLASS { public: struct Traits; - Position() + Pose() : x_pos_(0), y_pos_(0), z_pos_(0), @@ -526,7 +528,7 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Position FLATBUFFERS_FINAL_CLASS { y_rot_(0), z_rot_(0) { } - Position(int32_t _x_pos, int32_t _y_pos, int32_t _z_pos, int32_t _x_rot, int32_t _y_rot, int32_t _z_rot) + Pose(int32_t _x_pos, int32_t _y_pos, int32_t _z_pos, int32_t _x_rot, int32_t _y_rot, int32_t _z_rot) : x_pos_(flatbuffers::EndianScalar(_x_pos)), y_pos_(flatbuffers::EndianScalar(_y_pos)), z_pos_(flatbuffers::EndianScalar(_z_pos)), @@ -553,10 +555,44 @@ FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Position FLATBUFFERS_FINAL_CLASS { return flatbuffers::EndianScalar(z_rot_); } }; -FLATBUFFERS_STRUCT_END(Position, 24); +FLATBUFFERS_STRUCT_END(Pose, 24); -struct Position::Traits { - using type = Position; +struct Pose::Traits { + using type = Pose; +}; + +FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(2) EulerAngles FLATBUFFERS_FINAL_CLASS { + private: + int16_t x_; + int16_t y_; + int16_t z_; + + public: + struct Traits; + EulerAngles() + : x_(0), + y_(0), + z_(0) { + } + EulerAngles(int16_t _x, int16_t _y, int16_t _z) + : x_(flatbuffers::EndianScalar(_x)), + y_(flatbuffers::EndianScalar(_y)), + z_(flatbuffers::EndianScalar(_z)) { + } + int16_t x() const { + return flatbuffers::EndianScalar(x_); + } + int16_t y() const { + return flatbuffers::EndianScalar(y_); + } + int16_t z() const { + return flatbuffers::EndianScalar(z_); + } +}; +FLATBUFFERS_STRUCT_END(EulerAngles, 6); + +struct EulerAngles::Traits { + using type = EulerAngles; }; FLATBUFFERS_MANUALLY_ALIGNED_STRUCT(4) Vector2 FLATBUFFERS_FINAL_CLASS { @@ -668,7 +704,7 @@ struct CreatureTargetT : public flatbuffers::NativeTable { int32_t box_number = 0; int32_t flags = 0; int32_t trigger_flags = 0; - std::unique_ptr position{}; + std::unique_ptr position{}; }; struct CreatureTarget FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { @@ -698,8 +734,8 @@ struct CreatureTarget FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t trigger_flags() const { return GetField(VT_TRIGGER_FLAGS, 0); } - const TEN::Save::Position *position() const { - return GetStruct(VT_POSITION); + const TEN::Save::Pose *position() const { + return GetStruct(VT_POSITION); } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && @@ -708,7 +744,7 @@ struct CreatureTarget FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_BOX_NUMBER) && VerifyField(verifier, VT_FLAGS) && VerifyField(verifier, VT_TRIGGER_FLAGS) && - VerifyField(verifier, VT_POSITION) && + VerifyField(verifier, VT_POSITION) && verifier.EndTable(); } CreatureTargetT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -735,7 +771,7 @@ struct CreatureTargetBuilder { void add_trigger_flags(int32_t trigger_flags) { fbb_.AddElement(CreatureTarget::VT_TRIGGER_FLAGS, trigger_flags, 0); } - void add_position(const TEN::Save::Position *position) { + void add_position(const TEN::Save::Pose *position) { fbb_.AddStruct(CreatureTarget::VT_POSITION, position); } explicit CreatureTargetBuilder(flatbuffers::FlatBufferBuilder &_fbb) @@ -756,7 +792,7 @@ inline flatbuffers::Offset CreateCreatureTarget( int32_t box_number = 0, int32_t flags = 0, int32_t trigger_flags = 0, - const TEN::Save::Position *position = 0) { + const TEN::Save::Pose *position = 0) { CreatureTargetBuilder builder_(_fbb); builder_.add_position(position); builder_.add_trigger_flags(trigger_flags); @@ -1566,7 +1602,7 @@ struct KayakT : public flatbuffers::NativeTable { int32_t right_vertical_velocity = 0; int32_t left_right_count = 0; int32_t water_height = 0; - std::unique_ptr old_pos{}; + std::unique_ptr old_pos{}; bool turn = false; bool forward = false; bool true_water = false; @@ -1612,8 +1648,8 @@ struct Kayak FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t water_height() const { return GetField(VT_WATER_HEIGHT, 0); } - const TEN::Save::Position *old_pos() const { - return GetStruct(VT_OLD_POS); + const TEN::Save::Pose *old_pos() const { + return GetStruct(VT_OLD_POS); } bool turn() const { return GetField(VT_TURN, 0) != 0; @@ -1636,7 +1672,7 @@ struct Kayak FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_RIGHT_VERTICAL_VELOCITY) && VerifyField(verifier, VT_LEFT_RIGHT_COUNT) && VerifyField(verifier, VT_WATER_HEIGHT) && - VerifyField(verifier, VT_OLD_POS) && + VerifyField(verifier, VT_OLD_POS) && VerifyField(verifier, VT_TURN) && VerifyField(verifier, VT_FORWARD) && VerifyField(verifier, VT_TRUE_WATER) && @@ -1673,7 +1709,7 @@ struct KayakBuilder { void add_water_height(int32_t water_height) { fbb_.AddElement(Kayak::VT_WATER_HEIGHT, water_height, 0); } - void add_old_pos(const TEN::Save::Position *old_pos) { + void add_old_pos(const TEN::Save::Pose *old_pos) { fbb_.AddStruct(Kayak::VT_OLD_POS, old_pos); } void add_turn(bool turn) { @@ -1708,7 +1744,7 @@ inline flatbuffers::Offset CreateKayak( int32_t right_vertical_velocity = 0, int32_t left_right_count = 0, int32_t water_height = 0, - const TEN::Save::Position *old_pos = 0, + const TEN::Save::Pose *old_pos = 0, bool turn = false, bool forward = false, bool true_water = false, @@ -2702,7 +2738,7 @@ inline void CreatureTarget::UnPackTo(CreatureTargetT *_o, const flatbuffers::res { auto _e = box_number(); _o->box_number = _e; } { auto _e = flags(); _o->flags = _e; } { auto _e = trigger_flags(); _o->trigger_flags = _e; } - { auto _e = position(); if (_e) _o->position = std::unique_ptr(new TEN::Save::Position(*_e)); } + { auto _e = position(); if (_e) _o->position = std::unique_ptr(new TEN::Save::Pose(*_e)); } } inline flatbuffers::Offset CreatureTarget::Pack(flatbuffers::FlatBufferBuilder &_fbb, const CreatureTargetT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -3006,7 +3042,7 @@ inline void Kayak::UnPackTo(KayakT *_o, const flatbuffers::resolver_function_t * { auto _e = right_vertical_velocity(); _o->right_vertical_velocity = _e; } { auto _e = left_right_count(); _o->left_right_count = _e; } { auto _e = water_height(); _o->water_height = _e; } - { auto _e = old_pos(); if (_e) _o->old_pos = std::unique_ptr(new TEN::Save::Position(*_e)); } + { auto _e = old_pos(); if (_e) _o->old_pos = std::unique_ptr(new TEN::Save::Pose(*_e)); } { auto _e = turn(); _o->turn = _e; } { auto _e = forward(); _o->forward = _e; } { auto _e = true_water(); _o->true_water = _e; } diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index 0ab087cea..2834eba08 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h @@ -89,6 +89,10 @@ struct PlayerStatusData; struct PlayerStatusDataBuilder; struct PlayerStatusDataT; +struct PlayerContextData; +struct PlayerContextDataBuilder; +struct PlayerContextDataT; + struct Lara; struct LaraBuilder; struct LaraT; @@ -113,6 +117,10 @@ struct ParticleInfo; struct ParticleInfoBuilder; struct ParticleInfoT; +struct Soundtrack; +struct SoundtrackBuilder; +struct SoundtrackT; + struct SwarmObjectInfo; struct SwarmObjectInfoBuilder; struct SwarmObjectInfoT; @@ -621,7 +629,7 @@ struct ItemT : public flatbuffers::NativeTable { int32_t carried_item = 0; int32_t after_death = 0; std::vector item_flags{}; - std::unique_ptr pose{}; + std::unique_ptr pose{}; int32_t next_item = 0; int32_t next_item_active = 0; bool active = false; @@ -762,8 +770,8 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const flatbuffers::Vector *item_flags() const { return GetPointer *>(VT_ITEM_FLAGS); } - const TEN::Save::Position *pose() const { - return GetStruct(VT_POSE); + const TEN::Save::Pose *pose() const { + return GetStruct(VT_POSE); } int32_t next_item() const { return GetField(VT_NEXT_ITEM, 0); @@ -923,7 +931,7 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_AFTER_DEATH) && VerifyOffset(verifier, VT_ITEM_FLAGS) && verifier.VerifyVector(item_flags()) && - VerifyField(verifier, VT_POSE) && + VerifyField(verifier, VT_POSE) && VerifyField(verifier, VT_NEXT_ITEM) && VerifyField(verifier, VT_NEXT_ITEM_ACTIVE) && VerifyField(verifier, VT_ACTIVE) && @@ -1118,7 +1126,7 @@ struct ItemBuilder { void add_item_flags(flatbuffers::Offset> item_flags) { fbb_.AddOffset(Item::VT_ITEM_FLAGS, item_flags); } - void add_pose(const TEN::Save::Position *pose) { + void add_pose(const TEN::Save::Pose *pose) { fbb_.AddStruct(Item::VT_POSE, pose); } void add_next_item(int32_t next_item) { @@ -1222,7 +1230,7 @@ inline flatbuffers::Offset CreateItem( int32_t carried_item = 0, int32_t after_death = 0, flatbuffers::Offset> item_flags = 0, - const TEN::Save::Position *pose = 0, + const TEN::Save::Pose *pose = 0, int32_t next_item = 0, int32_t next_item_active = 0, bool active = false, @@ -1323,7 +1331,7 @@ inline flatbuffers::Offset CreateItemDirect( int32_t carried_item = 0, int32_t after_death = 0, const std::vector *item_flags = nullptr, - const TEN::Save::Position *pose = 0, + const TEN::Save::Pose *pose = 0, int32_t next_item = 0, int32_t next_item_active = 0, bool active = false, @@ -1406,7 +1414,7 @@ flatbuffers::Offset CreateItem(flatbuffers::FlatBufferBuilder &_fbb, const struct FXInfoT : public flatbuffers::NativeTable { typedef FXInfo TableType; - std::unique_ptr pose{}; + std::unique_ptr pose{}; int32_t room_number = 0; int32_t object_number = 0; int32_t next_fx = 0; @@ -1438,8 +1446,8 @@ struct FXInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_FLAG1 = 24, VT_FLAG2 = 26 }; - const TEN::Save::Position *pose() const { - return GetStruct(VT_POSE); + const TEN::Save::Pose *pose() const { + return GetStruct(VT_POSE); } int32_t room_number() const { return GetField(VT_ROOM_NUMBER, 0); @@ -1476,7 +1484,7 @@ struct FXInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyField(verifier, VT_POSE) && + VerifyField(verifier, VT_POSE) && VerifyField(verifier, VT_ROOM_NUMBER) && VerifyField(verifier, VT_OBJECT_NUMBER) && VerifyField(verifier, VT_NEXT_FX) && @@ -1499,7 +1507,7 @@ struct FXInfoBuilder { typedef FXInfo Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_pose(const TEN::Save::Position *pose) { + void add_pose(const TEN::Save::Pose *pose) { fbb_.AddStruct(FXInfo::VT_POSE, pose); } void add_room_number(int32_t room_number) { @@ -1548,7 +1556,7 @@ struct FXInfoBuilder { inline flatbuffers::Offset CreateFXInfo( flatbuffers::FlatBufferBuilder &_fbb, - const TEN::Save::Position *pose = 0, + const TEN::Save::Pose *pose = 0, int32_t room_number = 0, int32_t object_number = 0, int32_t next_fx = 0, @@ -1974,7 +1982,7 @@ struct ArmInfoT : public flatbuffers::NativeTable { int32_t frame_number = 0; int32_t frame_base = 0; bool locked = false; - std::unique_ptr rotation{}; + std::unique_ptr rotation{}; int32_t gun_flash = 0; int32_t gun_smoke = 0; }; @@ -2004,8 +2012,8 @@ struct ArmInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { bool locked() const { return GetField(VT_LOCKED, 0) != 0; } - const TEN::Save::Vector3 *rotation() const { - return GetStruct(VT_ROTATION); + const TEN::Save::EulerAngles *rotation() const { + return GetStruct(VT_ROTATION); } int32_t gun_flash() const { return GetField(VT_GUN_FLASH, 0); @@ -2019,7 +2027,7 @@ struct ArmInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_FRAME_NUMBER) && VerifyField(verifier, VT_FRAME_BASE) && VerifyField(verifier, VT_LOCKED) && - VerifyField(verifier, VT_ROTATION) && + VerifyField(verifier, VT_ROTATION) && VerifyField(verifier, VT_GUN_FLASH) && VerifyField(verifier, VT_GUN_SMOKE) && verifier.EndTable(); @@ -2045,7 +2053,7 @@ struct ArmInfoBuilder { void add_locked(bool locked) { fbb_.AddElement(ArmInfo::VT_LOCKED, static_cast(locked), 0); } - void add_rotation(const TEN::Save::Vector3 *rotation) { + void add_rotation(const TEN::Save::EulerAngles *rotation) { fbb_.AddStruct(ArmInfo::VT_ROTATION, rotation); } void add_gun_flash(int32_t gun_flash) { @@ -2071,7 +2079,7 @@ inline flatbuffers::Offset CreateArmInfo( int32_t frame_number = 0, int32_t frame_base = 0, bool locked = false, - const TEN::Save::Vector3 *rotation = 0, + const TEN::Save::EulerAngles *rotation = 0, int32_t gun_flash = 0, int32_t gun_smoke = 0) { ArmInfoBuilder builder_(_fbb); @@ -3342,7 +3350,6 @@ struct LaraControlDataT : public flatbuffers::NativeTable { typedef LaraControlData TableType; int32_t move_angle = 0; int32_t turn_rate = 0; - int32_t calculated_jump_velocity = 0; int32_t jump_direction = 0; int32_t hand_status = 0; int32_t water_status = 0; @@ -3369,24 +3376,23 @@ struct LaraControlData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { VT_MOVE_ANGLE = 4, VT_TURN_RATE = 6, - VT_CALCULATED_JUMP_VELOCITY = 8, - VT_JUMP_DIRECTION = 10, - VT_HAND_STATUS = 12, - VT_WATER_STATUS = 14, - VT_COUNT = 16, - VT_CAN_LOOK = 18, - VT_IS_MOVING = 20, - VT_KEEP_LOW = 22, - VT_IS_LOW = 24, - VT_CAN_CLIMB_LADDER = 26, - VT_IS_CLIMBING_LADDER = 28, - VT_CAN_MONKEY_SWING = 30, - VT_RUN_JUMP_QUEUED = 32, - VT_LOCKED = 34, - VT_WEAPON = 36, - VT_ROPE = 38, - VT_TIGHTROPE = 40, - VT_SUBSUIT = 42 + VT_JUMP_DIRECTION = 8, + VT_HAND_STATUS = 10, + VT_WATER_STATUS = 12, + VT_COUNT = 14, + VT_CAN_LOOK = 16, + VT_IS_MOVING = 18, + VT_KEEP_LOW = 20, + VT_IS_LOW = 22, + VT_CAN_CLIMB_LADDER = 24, + VT_IS_CLIMBING_LADDER = 26, + VT_CAN_MONKEY_SWING = 28, + VT_RUN_JUMP_QUEUED = 30, + VT_LOCKED = 32, + VT_WEAPON = 34, + VT_ROPE = 36, + VT_TIGHTROPE = 38, + VT_SUBSUIT = 40 }; int32_t move_angle() const { return GetField(VT_MOVE_ANGLE, 0); @@ -3394,9 +3400,6 @@ struct LaraControlData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t turn_rate() const { return GetField(VT_TURN_RATE, 0); } - int32_t calculated_jump_velocity() const { - return GetField(VT_CALCULATED_JUMP_VELOCITY, 0); - } int32_t jump_direction() const { return GetField(VT_JUMP_DIRECTION, 0); } @@ -3452,7 +3455,6 @@ struct LaraControlData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { return VerifyTableStart(verifier) && VerifyField(verifier, VT_MOVE_ANGLE) && VerifyField(verifier, VT_TURN_RATE) && - VerifyField(verifier, VT_CALCULATED_JUMP_VELOCITY) && VerifyField(verifier, VT_JUMP_DIRECTION) && VerifyField(verifier, VT_HAND_STATUS) && VerifyField(verifier, VT_WATER_STATUS) && @@ -3492,9 +3494,6 @@ struct LaraControlDataBuilder { void add_turn_rate(int32_t turn_rate) { fbb_.AddElement(LaraControlData::VT_TURN_RATE, turn_rate, 0); } - void add_calculated_jump_velocity(int32_t calculated_jump_velocity) { - fbb_.AddElement(LaraControlData::VT_CALCULATED_JUMP_VELOCITY, calculated_jump_velocity, 0); - } void add_jump_direction(int32_t jump_direction) { fbb_.AddElement(LaraControlData::VT_JUMP_DIRECTION, jump_direction, 0); } @@ -3561,7 +3560,6 @@ inline flatbuffers::Offset CreateLaraControlData( flatbuffers::FlatBufferBuilder &_fbb, int32_t move_angle = 0, int32_t turn_rate = 0, - int32_t calculated_jump_velocity = 0, int32_t jump_direction = 0, int32_t hand_status = 0, int32_t water_status = 0, @@ -3588,7 +3586,6 @@ inline flatbuffers::Offset CreateLaraControlData( builder_.add_water_status(water_status); builder_.add_hand_status(hand_status); builder_.add_jump_direction(jump_direction); - builder_.add_calculated_jump_velocity(calculated_jump_velocity); builder_.add_turn_rate(turn_rate); builder_.add_move_angle(move_angle); builder_.add_locked(locked); @@ -3784,111 +3781,51 @@ struct PlayerStatusData::Traits { flatbuffers::Offset CreatePlayerStatusData(flatbuffers::FlatBufferBuilder &_fbb, const PlayerStatusDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); -struct LaraT : public flatbuffers::NativeTable { - typedef Lara TableType; - std::unique_ptr effect{}; - std::unique_ptr status{}; - int32_t item_number = 0; - std::unique_ptr control{}; - std::unique_ptr inventory{}; - std::vector> weapons{}; - std::unique_ptr flare{}; - std::unique_ptr torch{}; - std::unique_ptr extra_head_rot{}; - std::unique_ptr extra_torso_rot{}; +struct PlayerContextDataT : public flatbuffers::NativeTable { + typedef PlayerContextData TableType; + int32_t calc_jump_velocity = 0; + int32_t interacted_item_number = 0; + std::unique_ptr next_corner_pose{}; + int32_t projected_floor_height = 0; + std::unique_ptr target_orient{}; + int32_t vehicle_item_number = 0; int32_t water_current_active = 0; std::unique_ptr water_current_pull{}; - std::unique_ptr left_arm{}; - std::unique_ptr right_arm{}; - std::vector target_arm_angles{}; - int32_t target_entity_number = 0; - int32_t vehicle = 0; - int32_t extra_anim = 0; - int32_t hit_frame = 0; - int32_t hit_direction = 0; - int32_t projected_floor_height = 0; - int32_t target_facing_angle = 0; int32_t water_surface_dist = 0; - int32_t interacted_item = 0; - std::unique_ptr next_corner_pose{}; - int32_t burn_type = 0; - uint32_t burn_count = 0; - bool burn = false; - int32_t burn_blue = 0; - bool burn_smoke = false; - int32_t location = 0; - int32_t highest_location = 0; - int32_t location_pad = 0; }; -struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { - typedef LaraT NativeTableType; - typedef LaraBuilder Builder; +struct PlayerContextData FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef PlayerContextDataT NativeTableType; + typedef PlayerContextDataBuilder Builder; struct Traits; enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { - VT_EFFECT = 4, - VT_STATUS = 6, - VT_ITEM_NUMBER = 8, - VT_CONTROL = 10, - VT_INVENTORY = 12, - VT_WEAPONS = 14, - VT_FLARE = 16, - VT_TORCH = 18, - VT_EXTRA_HEAD_ROT = 20, - VT_EXTRA_TORSO_ROT = 22, - VT_WATER_CURRENT_ACTIVE = 24, - VT_WATER_CURRENT_PULL = 26, - VT_LEFT_ARM = 28, - VT_RIGHT_ARM = 30, - VT_TARGET_ARM_ANGLES = 32, - VT_TARGET_ENTITY_NUMBER = 34, - VT_VEHICLE = 36, - VT_EXTRA_ANIM = 38, - VT_HIT_FRAME = 40, - VT_HIT_DIRECTION = 42, - VT_PROJECTED_FLOOR_HEIGHT = 44, - VT_TARGET_FACING_ANGLE = 46, - VT_WATER_SURFACE_DIST = 48, - VT_INTERACTED_ITEM = 50, - VT_NEXT_CORNER_POSE = 52, - VT_BURN_TYPE = 54, - VT_BURN_COUNT = 56, - VT_BURN = 58, - VT_BURN_BLUE = 60, - VT_BURN_SMOKE = 62, - VT_LOCATION = 64, - VT_HIGHEST_LOCATION = 66, - VT_LOCATION_PAD = 68 + VT_CALC_JUMP_VELOCITY = 4, + VT_INTERACTED_ITEM_NUMBER = 6, + VT_NEXT_CORNER_POSE = 8, + VT_PROJECTED_FLOOR_HEIGHT = 10, + VT_TARGET_ORIENT = 12, + VT_VEHICLE_ITEM_NUMBER = 14, + VT_WATER_CURRENT_ACTIVE = 16, + VT_WATER_CURRENT_PULL = 18, + VT_WATER_SURFACE_DIST = 20 }; - const TEN::Save::PlayerEffectData *effect() const { - return GetPointer(VT_EFFECT); + int32_t calc_jump_velocity() const { + return GetField(VT_CALC_JUMP_VELOCITY, 0); } - const TEN::Save::PlayerStatusData *status() const { - return GetPointer(VT_STATUS); + int32_t interacted_item_number() const { + return GetField(VT_INTERACTED_ITEM_NUMBER, 0); } - int32_t item_number() const { - return GetField(VT_ITEM_NUMBER, 0); + const TEN::Save::Pose *next_corner_pose() const { + return GetStruct(VT_NEXT_CORNER_POSE); } - const TEN::Save::LaraControlData *control() const { - return GetPointer(VT_CONTROL); + int32_t projected_floor_height() const { + return GetField(VT_PROJECTED_FLOOR_HEIGHT, 0); } - const TEN::Save::LaraInventoryData *inventory() const { - return GetPointer(VT_INVENTORY); + const TEN::Save::EulerAngles *target_orient() const { + return GetStruct(VT_TARGET_ORIENT); } - const flatbuffers::Vector> *weapons() const { - return GetPointer> *>(VT_WEAPONS); - } - const TEN::Save::FlareData *flare() const { - return GetPointer(VT_FLARE); - } - const TEN::Save::TorchData *torch() const { - return GetPointer(VT_TORCH); - } - const TEN::Save::Vector3 *extra_head_rot() const { - return GetStruct(VT_EXTRA_HEAD_ROT); - } - const TEN::Save::Vector3 *extra_torso_rot() const { - return GetStruct(VT_EXTRA_TORSO_ROT); + int32_t vehicle_item_number() const { + return GetField(VT_VEHICLE_ITEM_NUMBER, 0); } int32_t water_current_active() const { return GetField(VT_WATER_CURRENT_ACTIVE, 0); @@ -3896,115 +3833,243 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const TEN::Save::Vector3 *water_current_pull() const { return GetStruct(VT_WATER_CURRENT_PULL); } - const TEN::Save::ArmInfo *left_arm() const { - return GetPointer(VT_LEFT_ARM); + int32_t water_surface_dist() const { + return GetField(VT_WATER_SURFACE_DIST, 0); } - const TEN::Save::ArmInfo *right_arm() const { - return GetPointer(VT_RIGHT_ARM); + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_CALC_JUMP_VELOCITY) && + VerifyField(verifier, VT_INTERACTED_ITEM_NUMBER) && + VerifyField(verifier, VT_NEXT_CORNER_POSE) && + VerifyField(verifier, VT_PROJECTED_FLOOR_HEIGHT) && + VerifyField(verifier, VT_TARGET_ORIENT) && + VerifyField(verifier, VT_VEHICLE_ITEM_NUMBER) && + VerifyField(verifier, VT_WATER_CURRENT_ACTIVE) && + VerifyField(verifier, VT_WATER_CURRENT_PULL) && + VerifyField(verifier, VT_WATER_SURFACE_DIST) && + verifier.EndTable(); } - const flatbuffers::Vector *target_arm_angles() const { - return GetPointer *>(VT_TARGET_ARM_ANGLES); + PlayerContextDataT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(PlayerContextDataT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const PlayerContextDataT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct PlayerContextDataBuilder { + typedef PlayerContextData Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_calc_jump_velocity(int32_t calc_jump_velocity) { + fbb_.AddElement(PlayerContextData::VT_CALC_JUMP_VELOCITY, calc_jump_velocity, 0); } - int32_t target_entity_number() const { - return GetField(VT_TARGET_ENTITY_NUMBER, 0); + void add_interacted_item_number(int32_t interacted_item_number) { + fbb_.AddElement(PlayerContextData::VT_INTERACTED_ITEM_NUMBER, interacted_item_number, 0); } - int32_t vehicle() const { - return GetField(VT_VEHICLE, 0); + void add_next_corner_pose(const TEN::Save::Pose *next_corner_pose) { + fbb_.AddStruct(PlayerContextData::VT_NEXT_CORNER_POSE, next_corner_pose); + } + void add_projected_floor_height(int32_t projected_floor_height) { + fbb_.AddElement(PlayerContextData::VT_PROJECTED_FLOOR_HEIGHT, projected_floor_height, 0); + } + void add_target_orient(const TEN::Save::EulerAngles *target_orient) { + fbb_.AddStruct(PlayerContextData::VT_TARGET_ORIENT, target_orient); + } + void add_vehicle_item_number(int32_t vehicle_item_number) { + fbb_.AddElement(PlayerContextData::VT_VEHICLE_ITEM_NUMBER, vehicle_item_number, 0); + } + void add_water_current_active(int32_t water_current_active) { + fbb_.AddElement(PlayerContextData::VT_WATER_CURRENT_ACTIVE, water_current_active, 0); + } + void add_water_current_pull(const TEN::Save::Vector3 *water_current_pull) { + fbb_.AddStruct(PlayerContextData::VT_WATER_CURRENT_PULL, water_current_pull); + } + void add_water_surface_dist(int32_t water_surface_dist) { + fbb_.AddElement(PlayerContextData::VT_WATER_SURFACE_DIST, water_surface_dist, 0); + } + explicit PlayerContextDataBuilder(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 CreatePlayerContextData( + flatbuffers::FlatBufferBuilder &_fbb, + int32_t calc_jump_velocity = 0, + int32_t interacted_item_number = 0, + const TEN::Save::Pose *next_corner_pose = 0, + int32_t projected_floor_height = 0, + const TEN::Save::EulerAngles *target_orient = 0, + int32_t vehicle_item_number = 0, + int32_t water_current_active = 0, + const TEN::Save::Vector3 *water_current_pull = 0, + int32_t water_surface_dist = 0) { + PlayerContextDataBuilder builder_(_fbb); + builder_.add_water_surface_dist(water_surface_dist); + builder_.add_water_current_pull(water_current_pull); + builder_.add_water_current_active(water_current_active); + builder_.add_vehicle_item_number(vehicle_item_number); + builder_.add_target_orient(target_orient); + builder_.add_projected_floor_height(projected_floor_height); + builder_.add_next_corner_pose(next_corner_pose); + builder_.add_interacted_item_number(interacted_item_number); + builder_.add_calc_jump_velocity(calc_jump_velocity); + return builder_.Finish(); +} + +struct PlayerContextData::Traits { + using type = PlayerContextData; + static auto constexpr Create = CreatePlayerContextData; +}; + +flatbuffers::Offset CreatePlayerContextData(flatbuffers::FlatBufferBuilder &_fbb, const PlayerContextDataT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + +struct LaraT : public flatbuffers::NativeTable { + typedef Lara TableType; + std::unique_ptr context{}; + std::unique_ptr control{}; + std::unique_ptr effect{}; + int32_t extra_anim = 0; + std::unique_ptr extra_head_rot{}; + std::unique_ptr extra_torso_rot{}; + std::unique_ptr flare{}; + int32_t highest_location = 0; + int32_t hit_direction = 0; + int32_t hit_frame = 0; + std::unique_ptr inventory{}; + std::unique_ptr left_arm{}; + int32_t location = 0; + int32_t location_pad = 0; + std::unique_ptr right_arm{}; + std::unique_ptr status{}; + std::unique_ptr target_arm_orient{}; + int32_t target_entity_number = 0; + std::unique_ptr torch{}; + std::vector> weapons{}; +}; + +struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef LaraT NativeTableType; + typedef LaraBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_CONTEXT = 4, + VT_CONTROL = 6, + VT_EFFECT = 8, + VT_EXTRA_ANIM = 10, + VT_EXTRA_HEAD_ROT = 12, + VT_EXTRA_TORSO_ROT = 14, + VT_FLARE = 16, + VT_HIGHEST_LOCATION = 18, + VT_HIT_DIRECTION = 20, + VT_HIT_FRAME = 22, + VT_INVENTORY = 24, + VT_LEFT_ARM = 26, + VT_LOCATION = 28, + VT_LOCATION_PAD = 30, + VT_RIGHT_ARM = 32, + VT_STATUS = 34, + VT_TARGET_ARM_ORIENT = 36, + VT_TARGET_ENTITY_NUMBER = 38, + VT_TORCH = 40, + VT_WEAPONS = 42 + }; + const TEN::Save::PlayerContextData *context() const { + return GetPointer(VT_CONTEXT); + } + const TEN::Save::LaraControlData *control() const { + return GetPointer(VT_CONTROL); + } + const TEN::Save::PlayerEffectData *effect() const { + return GetPointer(VT_EFFECT); } int32_t extra_anim() const { return GetField(VT_EXTRA_ANIM, 0); } - int32_t hit_frame() const { - return GetField(VT_HIT_FRAME, 0); + const TEN::Save::EulerAngles *extra_head_rot() const { + return GetStruct(VT_EXTRA_HEAD_ROT); } - int32_t hit_direction() const { - return GetField(VT_HIT_DIRECTION, 0); + const TEN::Save::EulerAngles *extra_torso_rot() const { + return GetStruct(VT_EXTRA_TORSO_ROT); } - int32_t projected_floor_height() const { - return GetField(VT_PROJECTED_FLOOR_HEIGHT, 0); - } - int32_t target_facing_angle() const { - return GetField(VT_TARGET_FACING_ANGLE, 0); - } - int32_t water_surface_dist() const { - return GetField(VT_WATER_SURFACE_DIST, 0); - } - int32_t interacted_item() const { - return GetField(VT_INTERACTED_ITEM, 0); - } - const TEN::Save::Position *next_corner_pose() const { - return GetStruct(VT_NEXT_CORNER_POSE); - } - int32_t burn_type() const { - return GetField(VT_BURN_TYPE, 0); - } - uint32_t burn_count() const { - return GetField(VT_BURN_COUNT, 0); - } - bool burn() const { - return GetField(VT_BURN, 0) != 0; - } - int32_t burn_blue() const { - return GetField(VT_BURN_BLUE, 0); - } - bool burn_smoke() const { - return GetField(VT_BURN_SMOKE, 0) != 0; - } - int32_t location() const { - return GetField(VT_LOCATION, 0); + const TEN::Save::FlareData *flare() const { + return GetPointer(VT_FLARE); } int32_t highest_location() const { return GetField(VT_HIGHEST_LOCATION, 0); } + int32_t hit_direction() const { + return GetField(VT_HIT_DIRECTION, 0); + } + int32_t hit_frame() const { + return GetField(VT_HIT_FRAME, 0); + } + const TEN::Save::LaraInventoryData *inventory() const { + return GetPointer(VT_INVENTORY); + } + const TEN::Save::ArmInfo *left_arm() const { + return GetPointer(VT_LEFT_ARM); + } + int32_t location() const { + return GetField(VT_LOCATION, 0); + } int32_t location_pad() const { return GetField(VT_LOCATION_PAD, 0); } + const TEN::Save::ArmInfo *right_arm() const { + return GetPointer(VT_RIGHT_ARM); + } + const TEN::Save::PlayerStatusData *status() const { + return GetPointer(VT_STATUS); + } + const TEN::Save::EulerAngles *target_arm_orient() const { + return GetStruct(VT_TARGET_ARM_ORIENT); + } + int32_t target_entity_number() const { + return GetField(VT_TARGET_ENTITY_NUMBER, 0); + } + const TEN::Save::TorchData *torch() const { + return GetPointer(VT_TORCH); + } + const flatbuffers::Vector> *weapons() const { + return GetPointer> *>(VT_WEAPONS); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && - VerifyOffset(verifier, VT_EFFECT) && - verifier.VerifyTable(effect()) && - VerifyOffset(verifier, VT_STATUS) && - verifier.VerifyTable(status()) && - VerifyField(verifier, VT_ITEM_NUMBER) && + VerifyOffset(verifier, VT_CONTEXT) && + verifier.VerifyTable(context()) && VerifyOffset(verifier, VT_CONTROL) && verifier.VerifyTable(control()) && + VerifyOffset(verifier, VT_EFFECT) && + verifier.VerifyTable(effect()) && + VerifyField(verifier, VT_EXTRA_ANIM) && + VerifyField(verifier, VT_EXTRA_HEAD_ROT) && + VerifyField(verifier, VT_EXTRA_TORSO_ROT) && + VerifyOffset(verifier, VT_FLARE) && + verifier.VerifyTable(flare()) && + VerifyField(verifier, VT_HIGHEST_LOCATION) && + VerifyField(verifier, VT_HIT_DIRECTION) && + VerifyField(verifier, VT_HIT_FRAME) && VerifyOffset(verifier, VT_INVENTORY) && verifier.VerifyTable(inventory()) && + VerifyOffset(verifier, VT_LEFT_ARM) && + verifier.VerifyTable(left_arm()) && + VerifyField(verifier, VT_LOCATION) && + VerifyField(verifier, VT_LOCATION_PAD) && + VerifyOffset(verifier, VT_RIGHT_ARM) && + verifier.VerifyTable(right_arm()) && + VerifyOffset(verifier, VT_STATUS) && + verifier.VerifyTable(status()) && + VerifyField(verifier, VT_TARGET_ARM_ORIENT) && + VerifyField(verifier, VT_TARGET_ENTITY_NUMBER) && + VerifyOffset(verifier, VT_TORCH) && + verifier.VerifyTable(torch()) && VerifyOffset(verifier, VT_WEAPONS) && verifier.VerifyVector(weapons()) && verifier.VerifyVectorOfTables(weapons()) && - VerifyOffset(verifier, VT_FLARE) && - verifier.VerifyTable(flare()) && - VerifyOffset(verifier, VT_TORCH) && - verifier.VerifyTable(torch()) && - VerifyField(verifier, VT_EXTRA_HEAD_ROT) && - VerifyField(verifier, VT_EXTRA_TORSO_ROT) && - VerifyField(verifier, VT_WATER_CURRENT_ACTIVE) && - VerifyField(verifier, VT_WATER_CURRENT_PULL) && - VerifyOffset(verifier, VT_LEFT_ARM) && - verifier.VerifyTable(left_arm()) && - VerifyOffset(verifier, VT_RIGHT_ARM) && - verifier.VerifyTable(right_arm()) && - VerifyOffset(verifier, VT_TARGET_ARM_ANGLES) && - verifier.VerifyVector(target_arm_angles()) && - VerifyField(verifier, VT_TARGET_ENTITY_NUMBER) && - VerifyField(verifier, VT_VEHICLE) && - VerifyField(verifier, VT_EXTRA_ANIM) && - VerifyField(verifier, VT_HIT_FRAME) && - VerifyField(verifier, VT_HIT_DIRECTION) && - VerifyField(verifier, VT_PROJECTED_FLOOR_HEIGHT) && - VerifyField(verifier, VT_TARGET_FACING_ANGLE) && - VerifyField(verifier, VT_WATER_SURFACE_DIST) && - VerifyField(verifier, VT_INTERACTED_ITEM) && - VerifyField(verifier, VT_NEXT_CORNER_POSE) && - VerifyField(verifier, VT_BURN_TYPE) && - VerifyField(verifier, VT_BURN_COUNT) && - VerifyField(verifier, VT_BURN) && - VerifyField(verifier, VT_BURN_BLUE) && - VerifyField(verifier, VT_BURN_SMOKE) && - VerifyField(verifier, VT_LOCATION) && - VerifyField(verifier, VT_HIGHEST_LOCATION) && - VerifyField(verifier, VT_LOCATION_PAD) && verifier.EndTable(); } LaraT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -4016,105 +4081,66 @@ struct LaraBuilder { typedef Lara Table; flatbuffers::FlatBufferBuilder &fbb_; flatbuffers::uoffset_t start_; - void add_effect(flatbuffers::Offset effect) { - fbb_.AddOffset(Lara::VT_EFFECT, effect); - } - void add_status(flatbuffers::Offset status) { - fbb_.AddOffset(Lara::VT_STATUS, status); - } - void add_item_number(int32_t item_number) { - fbb_.AddElement(Lara::VT_ITEM_NUMBER, item_number, 0); + void add_context(flatbuffers::Offset context) { + fbb_.AddOffset(Lara::VT_CONTEXT, context); } void add_control(flatbuffers::Offset control) { fbb_.AddOffset(Lara::VT_CONTROL, control); } - void add_inventory(flatbuffers::Offset inventory) { - fbb_.AddOffset(Lara::VT_INVENTORY, inventory); - } - void add_weapons(flatbuffers::Offset>> weapons) { - fbb_.AddOffset(Lara::VT_WEAPONS, weapons); - } - void add_flare(flatbuffers::Offset flare) { - fbb_.AddOffset(Lara::VT_FLARE, flare); - } - void add_torch(flatbuffers::Offset torch) { - fbb_.AddOffset(Lara::VT_TORCH, torch); - } - void add_extra_head_rot(const TEN::Save::Vector3 *extra_head_rot) { - fbb_.AddStruct(Lara::VT_EXTRA_HEAD_ROT, extra_head_rot); - } - void add_extra_torso_rot(const TEN::Save::Vector3 *extra_torso_rot) { - fbb_.AddStruct(Lara::VT_EXTRA_TORSO_ROT, extra_torso_rot); - } - void add_water_current_active(int32_t water_current_active) { - fbb_.AddElement(Lara::VT_WATER_CURRENT_ACTIVE, water_current_active, 0); - } - void add_water_current_pull(const TEN::Save::Vector3 *water_current_pull) { - fbb_.AddStruct(Lara::VT_WATER_CURRENT_PULL, water_current_pull); - } - void add_left_arm(flatbuffers::Offset left_arm) { - fbb_.AddOffset(Lara::VT_LEFT_ARM, left_arm); - } - void add_right_arm(flatbuffers::Offset right_arm) { - fbb_.AddOffset(Lara::VT_RIGHT_ARM, right_arm); - } - void add_target_arm_angles(flatbuffers::Offset> target_arm_angles) { - fbb_.AddOffset(Lara::VT_TARGET_ARM_ANGLES, target_arm_angles); - } - void add_target_entity_number(int32_t target_entity_number) { - fbb_.AddElement(Lara::VT_TARGET_ENTITY_NUMBER, target_entity_number, 0); - } - void add_vehicle(int32_t vehicle) { - fbb_.AddElement(Lara::VT_VEHICLE, vehicle, 0); + void add_effect(flatbuffers::Offset effect) { + fbb_.AddOffset(Lara::VT_EFFECT, effect); } void add_extra_anim(int32_t extra_anim) { fbb_.AddElement(Lara::VT_EXTRA_ANIM, extra_anim, 0); } - void add_hit_frame(int32_t hit_frame) { - fbb_.AddElement(Lara::VT_HIT_FRAME, hit_frame, 0); + void add_extra_head_rot(const TEN::Save::EulerAngles *extra_head_rot) { + fbb_.AddStruct(Lara::VT_EXTRA_HEAD_ROT, extra_head_rot); } - void add_hit_direction(int32_t hit_direction) { - fbb_.AddElement(Lara::VT_HIT_DIRECTION, hit_direction, 0); + void add_extra_torso_rot(const TEN::Save::EulerAngles *extra_torso_rot) { + fbb_.AddStruct(Lara::VT_EXTRA_TORSO_ROT, extra_torso_rot); } - void add_projected_floor_height(int32_t projected_floor_height) { - fbb_.AddElement(Lara::VT_PROJECTED_FLOOR_HEIGHT, projected_floor_height, 0); - } - void add_target_facing_angle(int32_t target_facing_angle) { - fbb_.AddElement(Lara::VT_TARGET_FACING_ANGLE, target_facing_angle, 0); - } - void add_water_surface_dist(int32_t water_surface_dist) { - fbb_.AddElement(Lara::VT_WATER_SURFACE_DIST, water_surface_dist, 0); - } - void add_interacted_item(int32_t interacted_item) { - fbb_.AddElement(Lara::VT_INTERACTED_ITEM, interacted_item, 0); - } - void add_next_corner_pose(const TEN::Save::Position *next_corner_pose) { - fbb_.AddStruct(Lara::VT_NEXT_CORNER_POSE, next_corner_pose); - } - void add_burn_type(int32_t burn_type) { - fbb_.AddElement(Lara::VT_BURN_TYPE, burn_type, 0); - } - void add_burn_count(uint32_t burn_count) { - fbb_.AddElement(Lara::VT_BURN_COUNT, burn_count, 0); - } - void add_burn(bool burn) { - fbb_.AddElement(Lara::VT_BURN, static_cast(burn), 0); - } - void add_burn_blue(int32_t burn_blue) { - fbb_.AddElement(Lara::VT_BURN_BLUE, burn_blue, 0); - } - void add_burn_smoke(bool burn_smoke) { - fbb_.AddElement(Lara::VT_BURN_SMOKE, static_cast(burn_smoke), 0); - } - void add_location(int32_t location) { - fbb_.AddElement(Lara::VT_LOCATION, location, 0); + void add_flare(flatbuffers::Offset flare) { + fbb_.AddOffset(Lara::VT_FLARE, flare); } void add_highest_location(int32_t highest_location) { fbb_.AddElement(Lara::VT_HIGHEST_LOCATION, highest_location, 0); } + void add_hit_direction(int32_t hit_direction) { + fbb_.AddElement(Lara::VT_HIT_DIRECTION, hit_direction, 0); + } + void add_hit_frame(int32_t hit_frame) { + fbb_.AddElement(Lara::VT_HIT_FRAME, hit_frame, 0); + } + void add_inventory(flatbuffers::Offset inventory) { + fbb_.AddOffset(Lara::VT_INVENTORY, inventory); + } + void add_left_arm(flatbuffers::Offset left_arm) { + fbb_.AddOffset(Lara::VT_LEFT_ARM, left_arm); + } + void add_location(int32_t location) { + fbb_.AddElement(Lara::VT_LOCATION, location, 0); + } void add_location_pad(int32_t location_pad) { fbb_.AddElement(Lara::VT_LOCATION_PAD, location_pad, 0); } + void add_right_arm(flatbuffers::Offset right_arm) { + fbb_.AddOffset(Lara::VT_RIGHT_ARM, right_arm); + } + void add_status(flatbuffers::Offset status) { + fbb_.AddOffset(Lara::VT_STATUS, status); + } + void add_target_arm_orient(const TEN::Save::EulerAngles *target_arm_orient) { + fbb_.AddStruct(Lara::VT_TARGET_ARM_ORIENT, target_arm_orient); + } + void add_target_entity_number(int32_t target_entity_number) { + fbb_.AddElement(Lara::VT_TARGET_ENTITY_NUMBER, target_entity_number, 0); + } + void add_torch(flatbuffers::Offset torch) { + fbb_.AddOffset(Lara::VT_TORCH, torch); + } + void add_weapons(flatbuffers::Offset>> weapons) { + fbb_.AddOffset(Lara::VT_WEAPONS, weapons); + } explicit LaraBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -4128,73 +4154,47 @@ struct LaraBuilder { inline flatbuffers::Offset CreateLara( flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset effect = 0, - flatbuffers::Offset status = 0, - int32_t item_number = 0, + flatbuffers::Offset context = 0, flatbuffers::Offset control = 0, - flatbuffers::Offset inventory = 0, - flatbuffers::Offset>> weapons = 0, - flatbuffers::Offset flare = 0, - flatbuffers::Offset torch = 0, - const TEN::Save::Vector3 *extra_head_rot = 0, - const TEN::Save::Vector3 *extra_torso_rot = 0, - int32_t water_current_active = 0, - const TEN::Save::Vector3 *water_current_pull = 0, - flatbuffers::Offset left_arm = 0, - flatbuffers::Offset right_arm = 0, - flatbuffers::Offset> target_arm_angles = 0, - int32_t target_entity_number = 0, - int32_t vehicle = 0, + flatbuffers::Offset effect = 0, int32_t extra_anim = 0, - int32_t hit_frame = 0, - int32_t hit_direction = 0, - int32_t projected_floor_height = 0, - int32_t target_facing_angle = 0, - int32_t water_surface_dist = 0, - int32_t interacted_item = 0, - const TEN::Save::Position *next_corner_pose = 0, - int32_t burn_type = 0, - uint32_t burn_count = 0, - bool burn = false, - int32_t burn_blue = 0, - bool burn_smoke = false, - int32_t location = 0, + const TEN::Save::EulerAngles *extra_head_rot = 0, + const TEN::Save::EulerAngles *extra_torso_rot = 0, + flatbuffers::Offset flare = 0, int32_t highest_location = 0, - int32_t location_pad = 0) { + int32_t hit_direction = 0, + int32_t hit_frame = 0, + flatbuffers::Offset inventory = 0, + flatbuffers::Offset left_arm = 0, + int32_t location = 0, + int32_t location_pad = 0, + flatbuffers::Offset right_arm = 0, + flatbuffers::Offset status = 0, + const TEN::Save::EulerAngles *target_arm_orient = 0, + int32_t target_entity_number = 0, + flatbuffers::Offset torch = 0, + flatbuffers::Offset>> weapons = 0) { LaraBuilder builder_(_fbb); - builder_.add_location_pad(location_pad); - builder_.add_highest_location(highest_location); - builder_.add_location(location); - builder_.add_burn_blue(burn_blue); - builder_.add_burn_count(burn_count); - builder_.add_burn_type(burn_type); - builder_.add_next_corner_pose(next_corner_pose); - builder_.add_interacted_item(interacted_item); - builder_.add_water_surface_dist(water_surface_dist); - builder_.add_target_facing_angle(target_facing_angle); - builder_.add_projected_floor_height(projected_floor_height); - builder_.add_hit_direction(hit_direction); - builder_.add_hit_frame(hit_frame); - builder_.add_extra_anim(extra_anim); - builder_.add_vehicle(vehicle); + builder_.add_weapons(weapons); + builder_.add_torch(torch); builder_.add_target_entity_number(target_entity_number); - builder_.add_target_arm_angles(target_arm_angles); + builder_.add_target_arm_orient(target_arm_orient); + builder_.add_status(status); builder_.add_right_arm(right_arm); + builder_.add_location_pad(location_pad); + builder_.add_location(location); builder_.add_left_arm(left_arm); - builder_.add_water_current_pull(water_current_pull); - builder_.add_water_current_active(water_current_active); + builder_.add_inventory(inventory); + builder_.add_hit_frame(hit_frame); + builder_.add_hit_direction(hit_direction); + builder_.add_highest_location(highest_location); + builder_.add_flare(flare); builder_.add_extra_torso_rot(extra_torso_rot); builder_.add_extra_head_rot(extra_head_rot); - builder_.add_torch(torch); - builder_.add_flare(flare); - builder_.add_weapons(weapons); - builder_.add_inventory(inventory); - builder_.add_control(control); - builder_.add_item_number(item_number); - builder_.add_status(status); + builder_.add_extra_anim(extra_anim); builder_.add_effect(effect); - builder_.add_burn_smoke(burn_smoke); - builder_.add_burn(burn); + builder_.add_control(control); + builder_.add_context(context); return builder_.Finish(); } @@ -4205,76 +4205,49 @@ struct Lara::Traits { inline flatbuffers::Offset CreateLaraDirect( flatbuffers::FlatBufferBuilder &_fbb, - flatbuffers::Offset effect = 0, - flatbuffers::Offset status = 0, - int32_t item_number = 0, + flatbuffers::Offset context = 0, flatbuffers::Offset control = 0, - flatbuffers::Offset inventory = 0, - const std::vector> *weapons = nullptr, - flatbuffers::Offset flare = 0, - flatbuffers::Offset torch = 0, - const TEN::Save::Vector3 *extra_head_rot = 0, - const TEN::Save::Vector3 *extra_torso_rot = 0, - int32_t water_current_active = 0, - const TEN::Save::Vector3 *water_current_pull = 0, - flatbuffers::Offset left_arm = 0, - flatbuffers::Offset right_arm = 0, - const std::vector *target_arm_angles = nullptr, - int32_t target_entity_number = 0, - int32_t vehicle = 0, + flatbuffers::Offset effect = 0, int32_t extra_anim = 0, - int32_t hit_frame = 0, - int32_t hit_direction = 0, - int32_t projected_floor_height = 0, - int32_t target_facing_angle = 0, - int32_t water_surface_dist = 0, - int32_t interacted_item = 0, - const TEN::Save::Position *next_corner_pose = 0, - int32_t burn_type = 0, - uint32_t burn_count = 0, - bool burn = false, - int32_t burn_blue = 0, - bool burn_smoke = false, - int32_t location = 0, + const TEN::Save::EulerAngles *extra_head_rot = 0, + const TEN::Save::EulerAngles *extra_torso_rot = 0, + flatbuffers::Offset flare = 0, int32_t highest_location = 0, - int32_t location_pad = 0) { + int32_t hit_direction = 0, + int32_t hit_frame = 0, + flatbuffers::Offset inventory = 0, + flatbuffers::Offset left_arm = 0, + int32_t location = 0, + int32_t location_pad = 0, + flatbuffers::Offset right_arm = 0, + flatbuffers::Offset status = 0, + const TEN::Save::EulerAngles *target_arm_orient = 0, + int32_t target_entity_number = 0, + flatbuffers::Offset torch = 0, + const std::vector> *weapons = nullptr) { auto weapons__ = weapons ? _fbb.CreateVector>(*weapons) : 0; - auto target_arm_angles__ = target_arm_angles ? _fbb.CreateVector(*target_arm_angles) : 0; return TEN::Save::CreateLara( _fbb, - effect, - status, - item_number, + context, control, - inventory, - weapons__, - flare, - torch, + effect, + extra_anim, extra_head_rot, extra_torso_rot, - water_current_active, - water_current_pull, - left_arm, - right_arm, - target_arm_angles__, - target_entity_number, - vehicle, - extra_anim, - hit_frame, - hit_direction, - projected_floor_height, - target_facing_angle, - water_surface_dist, - interacted_item, - next_corner_pose, - burn_type, - burn_count, - burn, - burn_blue, - burn_smoke, - location, + flare, highest_location, - location_pad); + hit_direction, + hit_frame, + inventory, + left_arm, + location, + location_pad, + right_arm, + status, + target_arm_orient, + target_entity_number, + torch, + weapons__); } flatbuffers::Offset CreateLara(flatbuffers::FlatBufferBuilder &_fbb, const LaraT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); @@ -4457,7 +4430,7 @@ struct StaticMeshInfoT : public flatbuffers::NativeTable { typedef StaticMeshInfo TableType; int32_t number = 0; int32_t room_number = 0; - std::unique_ptr pose{}; + std::unique_ptr pose{}; float scale = 0.0f; std::unique_ptr color{}; int32_t hit_points = 0; @@ -4483,8 +4456,8 @@ struct StaticMeshInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int32_t room_number() const { return GetField(VT_ROOM_NUMBER, 0); } - const TEN::Save::Position *pose() const { - return GetStruct(VT_POSE); + const TEN::Save::Pose *pose() const { + return GetStruct(VT_POSE); } float scale() const { return GetField(VT_SCALE, 0.0f); @@ -4502,7 +4475,7 @@ struct StaticMeshInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { return VerifyTableStart(verifier) && VerifyField(verifier, VT_NUMBER) && VerifyField(verifier, VT_ROOM_NUMBER) && - VerifyField(verifier, VT_POSE) && + VerifyField(verifier, VT_POSE) && VerifyField(verifier, VT_SCALE) && VerifyField(verifier, VT_COLOR) && VerifyField(verifier, VT_HIT_POINTS) && @@ -4524,7 +4497,7 @@ struct StaticMeshInfoBuilder { void add_room_number(int32_t room_number) { fbb_.AddElement(StaticMeshInfo::VT_ROOM_NUMBER, room_number, 0); } - void add_pose(const TEN::Save::Position *pose) { + void add_pose(const TEN::Save::Pose *pose) { fbb_.AddStruct(StaticMeshInfo::VT_POSE, pose); } void add_scale(float scale) { @@ -4554,7 +4527,7 @@ inline flatbuffers::Offset CreateStaticMeshInfo( flatbuffers::FlatBufferBuilder &_fbb, int32_t number = 0, int32_t room_number = 0, - const TEN::Save::Position *pose = 0, + const TEN::Save::Pose *pose = 0, float scale = 0.0f, const TEN::Save::Vector4 *color = 0, int32_t hit_points = 0, @@ -5031,10 +5004,91 @@ struct ParticleInfo::Traits { flatbuffers::Offset CreateParticleInfo(flatbuffers::FlatBufferBuilder &_fbb, const ParticleInfoT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct SoundtrackT : public flatbuffers::NativeTable { + typedef Soundtrack TableType; + std::string name{}; + uint64_t position = 0; +}; + +struct Soundtrack FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef SoundtrackT NativeTableType; + typedef SoundtrackBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_NAME = 4, + VT_POSITION = 6 + }; + const flatbuffers::String *name() const { + return GetPointer(VT_NAME); + } + uint64_t position() const { + return GetField(VT_POSITION, 0); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_NAME) && + verifier.VerifyString(name()) && + VerifyField(verifier, VT_POSITION) && + verifier.EndTable(); + } + SoundtrackT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(SoundtrackT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const SoundtrackT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct SoundtrackBuilder { + typedef Soundtrack Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_name(flatbuffers::Offset name) { + fbb_.AddOffset(Soundtrack::VT_NAME, name); + } + void add_position(uint64_t position) { + fbb_.AddElement(Soundtrack::VT_POSITION, position, 0); + } + explicit SoundtrackBuilder(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 CreateSoundtrack( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset name = 0, + uint64_t position = 0) { + SoundtrackBuilder builder_(_fbb); + builder_.add_position(position); + builder_.add_name(name); + return builder_.Finish(); +} + +struct Soundtrack::Traits { + using type = Soundtrack; + static auto constexpr Create = CreateSoundtrack; +}; + +inline flatbuffers::Offset CreateSoundtrackDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *name = nullptr, + uint64_t position = 0) { + auto name__ = name ? _fbb.CreateString(name) : 0; + return TEN::Save::CreateSoundtrack( + _fbb, + name__, + position); +} + +flatbuffers::Offset CreateSoundtrack(flatbuffers::FlatBufferBuilder &_fbb, const SoundtrackT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct SwarmObjectInfoT : public flatbuffers::NativeTable { typedef SwarmObjectInfo TableType; bool on = false; - std::unique_ptr pose{}; + std::unique_ptr pose{}; int32_t room_number = 0; int32_t flags = 0; }; @@ -5052,8 +5106,8 @@ struct SwarmObjectInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { bool on() const { return GetField(VT_ON, 0) != 0; } - const TEN::Save::Position *pose() const { - return GetStruct(VT_POSE); + const TEN::Save::Pose *pose() const { + return GetStruct(VT_POSE); } int32_t room_number() const { return GetField(VT_ROOM_NUMBER, 0); @@ -5064,7 +5118,7 @@ struct SwarmObjectInfo FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_ON) && - VerifyField(verifier, VT_POSE) && + VerifyField(verifier, VT_POSE) && VerifyField(verifier, VT_ROOM_NUMBER) && VerifyField(verifier, VT_FLAGS) && verifier.EndTable(); @@ -5081,7 +5135,7 @@ struct SwarmObjectInfoBuilder { void add_on(bool on) { fbb_.AddElement(SwarmObjectInfo::VT_ON, static_cast(on), 0); } - void add_pose(const TEN::Save::Position *pose) { + void add_pose(const TEN::Save::Pose *pose) { fbb_.AddStruct(SwarmObjectInfo::VT_POSE, pose); } void add_room_number(int32_t room_number) { @@ -5104,7 +5158,7 @@ struct SwarmObjectInfoBuilder { inline flatbuffers::Offset CreateSwarmObjectInfo( flatbuffers::FlatBufferBuilder &_fbb, bool on = false, - const TEN::Save::Position *pose = 0, + const TEN::Save::Pose *pose = 0, int32_t room_number = 0, int32_t flags = 0) { SwarmObjectInfoBuilder builder_(_fbb); @@ -6770,13 +6824,9 @@ struct SaveGameT : public flatbuffers::NativeTable { int32_t flip_timer = 0; int32_t flip_status = 0; int16_t current_fov = 0; + int32_t last_inv_item = 0; std::vector action_queue{}; - std::string ambient_track{}; - uint64_t ambient_position = 0; - std::string oneshot_track{}; - uint64_t oneshot_position = 0; - std::string voice_track{}; - uint64_t voice_position = 0; + std::vector> soundtracks{}; std::vector cd_flags{}; std::unique_ptr rope{}; std::unique_ptr pendulum{}; @@ -6828,30 +6878,26 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_FLIP_TIMER = 52, VT_FLIP_STATUS = 54, VT_CURRENT_FOV = 56, - VT_ACTION_QUEUE = 58, - VT_AMBIENT_TRACK = 60, - VT_AMBIENT_POSITION = 62, - VT_ONESHOT_TRACK = 64, - VT_ONESHOT_POSITION = 66, - VT_VOICE_TRACK = 68, - VT_VOICE_POSITION = 70, - VT_CD_FLAGS = 72, - VT_ROPE = 74, - VT_PENDULUM = 76, - VT_ALTERNATE_PENDULUM = 78, - VT_VOLUMES = 80, - VT_CALL_COUNTERS = 82, - VT_SCRIPT_VARS = 84, - VT_CALLBACKS_PRE_START = 86, - VT_CALLBACKS_POST_START = 88, - VT_CALLBACKS_PRE_END = 90, - VT_CALLBACKS_POST_END = 92, - VT_CALLBACKS_PRE_SAVE = 94, - VT_CALLBACKS_POST_SAVE = 96, - VT_CALLBACKS_PRE_LOAD = 98, - VT_CALLBACKS_POST_LOAD = 100, - VT_CALLBACKS_PRE_CONTROL = 102, - VT_CALLBACKS_POST_CONTROL = 104 + VT_LAST_INV_ITEM = 58, + VT_ACTION_QUEUE = 60, + VT_SOUNDTRACKS = 62, + VT_CD_FLAGS = 64, + VT_ROPE = 66, + VT_PENDULUM = 68, + VT_ALTERNATE_PENDULUM = 70, + VT_VOLUMES = 72, + VT_CALL_COUNTERS = 74, + VT_SCRIPT_VARS = 76, + VT_CALLBACKS_PRE_START = 78, + VT_CALLBACKS_POST_START = 80, + VT_CALLBACKS_PRE_END = 82, + VT_CALLBACKS_POST_END = 84, + VT_CALLBACKS_PRE_SAVE = 86, + VT_CALLBACKS_POST_SAVE = 88, + VT_CALLBACKS_PRE_LOAD = 90, + VT_CALLBACKS_POST_LOAD = 92, + VT_CALLBACKS_PRE_CONTROL = 94, + VT_CALLBACKS_POST_CONTROL = 96 }; const TEN::Save::SaveGameHeader *header() const { return GetPointer(VT_HEADER); @@ -6934,26 +6980,14 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { int16_t current_fov() const { return GetField(VT_CURRENT_FOV, 0); } + int32_t last_inv_item() const { + return GetField(VT_LAST_INV_ITEM, 0); + } const flatbuffers::Vector *action_queue() const { return GetPointer *>(VT_ACTION_QUEUE); } - const flatbuffers::String *ambient_track() const { - return GetPointer(VT_AMBIENT_TRACK); - } - uint64_t ambient_position() const { - return GetField(VT_AMBIENT_POSITION, 0); - } - const flatbuffers::String *oneshot_track() const { - return GetPointer(VT_ONESHOT_TRACK); - } - uint64_t oneshot_position() const { - return GetField(VT_ONESHOT_POSITION, 0); - } - const flatbuffers::String *voice_track() const { - return GetPointer(VT_VOICE_TRACK); - } - uint64_t voice_position() const { - return GetField(VT_VOICE_POSITION, 0); + const flatbuffers::Vector> *soundtracks() const { + return GetPointer> *>(VT_SOUNDTRACKS); } const flatbuffers::Vector *cd_flags() const { return GetPointer *>(VT_CD_FLAGS); @@ -7066,17 +7100,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VerifyField(verifier, VT_FLIP_TIMER) && VerifyField(verifier, VT_FLIP_STATUS) && VerifyField(verifier, VT_CURRENT_FOV) && + VerifyField(verifier, VT_LAST_INV_ITEM) && VerifyOffset(verifier, VT_ACTION_QUEUE) && verifier.VerifyVector(action_queue()) && - VerifyOffset(verifier, VT_AMBIENT_TRACK) && - verifier.VerifyString(ambient_track()) && - VerifyField(verifier, VT_AMBIENT_POSITION) && - VerifyOffset(verifier, VT_ONESHOT_TRACK) && - verifier.VerifyString(oneshot_track()) && - VerifyField(verifier, VT_ONESHOT_POSITION) && - VerifyOffset(verifier, VT_VOICE_TRACK) && - verifier.VerifyString(voice_track()) && - VerifyField(verifier, VT_VOICE_POSITION) && + VerifyOffset(verifier, VT_SOUNDTRACKS) && + verifier.VerifyVector(soundtracks()) && + verifier.VerifyVectorOfTables(soundtracks()) && VerifyOffset(verifier, VT_CD_FLAGS) && verifier.VerifyVector(cd_flags()) && VerifyOffset(verifier, VT_ROPE) && @@ -7215,26 +7244,14 @@ struct SaveGameBuilder { void add_current_fov(int16_t current_fov) { fbb_.AddElement(SaveGame::VT_CURRENT_FOV, current_fov, 0); } + void add_last_inv_item(int32_t last_inv_item) { + fbb_.AddElement(SaveGame::VT_LAST_INV_ITEM, last_inv_item, 0); + } void add_action_queue(flatbuffers::Offset> action_queue) { fbb_.AddOffset(SaveGame::VT_ACTION_QUEUE, action_queue); } - void add_ambient_track(flatbuffers::Offset ambient_track) { - fbb_.AddOffset(SaveGame::VT_AMBIENT_TRACK, ambient_track); - } - void add_ambient_position(uint64_t ambient_position) { - fbb_.AddElement(SaveGame::VT_AMBIENT_POSITION, ambient_position, 0); - } - void add_oneshot_track(flatbuffers::Offset oneshot_track) { - fbb_.AddOffset(SaveGame::VT_ONESHOT_TRACK, oneshot_track); - } - void add_oneshot_position(uint64_t oneshot_position) { - fbb_.AddElement(SaveGame::VT_ONESHOT_POSITION, oneshot_position, 0); - } - void add_voice_track(flatbuffers::Offset voice_track) { - fbb_.AddOffset(SaveGame::VT_VOICE_TRACK, voice_track); - } - void add_voice_position(uint64_t voice_position) { - fbb_.AddElement(SaveGame::VT_VOICE_POSITION, voice_position, 0); + void add_soundtracks(flatbuffers::Offset>> soundtracks) { + fbb_.AddOffset(SaveGame::VT_SOUNDTRACKS, soundtracks); } void add_cd_flags(flatbuffers::Offset> cd_flags) { fbb_.AddOffset(SaveGame::VT_CD_FLAGS, cd_flags); @@ -7327,13 +7344,9 @@ inline flatbuffers::Offset CreateSaveGame( int32_t flip_timer = 0, int32_t flip_status = 0, int16_t current_fov = 0, + int32_t last_inv_item = 0, flatbuffers::Offset> action_queue = 0, - flatbuffers::Offset ambient_track = 0, - uint64_t ambient_position = 0, - flatbuffers::Offset oneshot_track = 0, - uint64_t oneshot_position = 0, - flatbuffers::Offset voice_track = 0, - uint64_t voice_position = 0, + flatbuffers::Offset>> soundtracks = 0, flatbuffers::Offset> cd_flags = 0, flatbuffers::Offset rope = 0, flatbuffers::Offset pendulum = 0, @@ -7352,9 +7365,6 @@ inline flatbuffers::Offset CreateSaveGame( flatbuffers::Offset>> callbacks_pre_control = 0, flatbuffers::Offset>> callbacks_post_control = 0) { SaveGameBuilder builder_(_fbb); - builder_.add_voice_position(voice_position); - builder_.add_oneshot_position(oneshot_position); - builder_.add_ambient_position(ambient_position); builder_.add_callbacks_post_control(callbacks_post_control); builder_.add_callbacks_pre_control(callbacks_pre_control); builder_.add_callbacks_post_load(callbacks_post_load); @@ -7372,10 +7382,9 @@ inline flatbuffers::Offset CreateSaveGame( builder_.add_pendulum(pendulum); builder_.add_rope(rope); builder_.add_cd_flags(cd_flags); - builder_.add_voice_track(voice_track); - builder_.add_oneshot_track(oneshot_track); - builder_.add_ambient_track(ambient_track); + builder_.add_soundtracks(soundtracks); builder_.add_action_queue(action_queue); + builder_.add_last_inv_item(last_inv_item); builder_.add_flip_status(flip_status); builder_.add_flip_timer(flip_timer); builder_.add_flip_effect(flip_effect); @@ -7440,13 +7449,9 @@ inline flatbuffers::Offset CreateSaveGameDirect( int32_t flip_timer = 0, int32_t flip_status = 0, int16_t current_fov = 0, + int32_t last_inv_item = 0, const std::vector *action_queue = nullptr, - const char *ambient_track = nullptr, - uint64_t ambient_position = 0, - const char *oneshot_track = nullptr, - uint64_t oneshot_position = 0, - const char *voice_track = nullptr, - uint64_t voice_position = 0, + const std::vector> *soundtracks = nullptr, const std::vector *cd_flags = nullptr, flatbuffers::Offset rope = 0, flatbuffers::Offset pendulum = 0, @@ -7480,9 +7485,7 @@ inline flatbuffers::Offset CreateSaveGameDirect( auto flip_maps__ = flip_maps ? _fbb.CreateVector(*flip_maps) : 0; auto flip_stats__ = flip_stats ? _fbb.CreateVector(*flip_stats) : 0; auto action_queue__ = action_queue ? _fbb.CreateVector(*action_queue) : 0; - auto ambient_track__ = ambient_track ? _fbb.CreateString(ambient_track) : 0; - auto oneshot_track__ = oneshot_track ? _fbb.CreateString(oneshot_track) : 0; - auto voice_track__ = voice_track ? _fbb.CreateString(voice_track) : 0; + auto soundtracks__ = soundtracks ? _fbb.CreateVector>(*soundtracks) : 0; auto cd_flags__ = cd_flags ? _fbb.CreateVector(*cd_flags) : 0; auto volumes__ = volumes ? _fbb.CreateVector>(*volumes) : 0; auto call_counters__ = call_counters ? _fbb.CreateVector>(*call_counters) : 0; @@ -7525,13 +7528,9 @@ inline flatbuffers::Offset CreateSaveGameDirect( flip_timer, flip_status, current_fov, + last_inv_item, action_queue__, - ambient_track__, - ambient_position, - oneshot_track__, - oneshot_position, - voice_track__, - voice_position, + soundtracks__, cd_flags__, rope, pendulum, @@ -7619,7 +7618,7 @@ inline void Item::UnPackTo(ItemT *_o, const flatbuffers::resolver_function_t *_r { auto _e = carried_item(); _o->carried_item = _e; } { auto _e = after_death(); _o->after_death = _e; } { auto _e = item_flags(); if (_e) { _o->item_flags.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->item_flags[_i] = _e->Get(_i); } } } - { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Position(*_e)); } + { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Pose(*_e)); } { auto _e = next_item(); _o->next_item = _e; } { auto _e = next_item_active(); _o->next_item_active = _e; } { auto _e = active(); _o->active = _e; } @@ -7755,7 +7754,7 @@ inline FXInfoT *FXInfo::UnPack(const flatbuffers::resolver_function_t *_resolver inline void FXInfo::UnPackTo(FXInfoT *_o, const flatbuffers::resolver_function_t *_resolver) const { (void)_o; (void)_resolver; - { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Position(*_e)); } + { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Pose(*_e)); } { auto _e = room_number(); _o->room_number = _e; } { auto _e = object_number(); _o->object_number = _e; } { auto _e = next_fx(); _o->next_fx = _e; } @@ -7958,7 +7957,7 @@ inline void ArmInfo::UnPackTo(ArmInfoT *_o, const flatbuffers::resolver_function { auto _e = frame_number(); _o->frame_number = _e; } { auto _e = frame_base(); _o->frame_base = _e; } { auto _e = locked(); _o->locked = _e; } - { auto _e = rotation(); if (_e) _o->rotation = std::unique_ptr(new TEN::Save::Vector3(*_e)); } + { auto _e = rotation(); if (_e) _o->rotation = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } { auto _e = gun_flash(); _o->gun_flash = _e; } { auto _e = gun_smoke(); _o->gun_smoke = _e; } } @@ -8397,7 +8396,6 @@ inline void LaraControlData::UnPackTo(LaraControlDataT *_o, const flatbuffers::r (void)_resolver; { auto _e = move_angle(); _o->move_angle = _e; } { auto _e = turn_rate(); _o->turn_rate = _e; } - { auto _e = calculated_jump_velocity(); _o->calculated_jump_velocity = _e; } { auto _e = jump_direction(); _o->jump_direction = _e; } { auto _e = hand_status(); _o->hand_status = _e; } { auto _e = water_status(); _o->water_status = _e; } @@ -8427,7 +8425,6 @@ inline flatbuffers::Offset CreateLaraControlData(flatbuffers::F struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LaraControlDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; auto _move_angle = _o->move_angle; auto _turn_rate = _o->turn_rate; - auto _calculated_jump_velocity = _o->calculated_jump_velocity; auto _jump_direction = _o->jump_direction; auto _hand_status = _o->hand_status; auto _water_status = _o->water_status; @@ -8449,7 +8446,6 @@ inline flatbuffers::Offset CreateLaraControlData(flatbuffers::F _fbb, _move_angle, _turn_rate, - _calculated_jump_velocity, _jump_direction, _hand_status, _water_status, @@ -8533,6 +8529,56 @@ inline flatbuffers::Offset CreatePlayerStatusData(flatbuffers: _stamina); } +inline PlayerContextDataT *PlayerContextData::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::make_unique(); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void PlayerContextData::UnPackTo(PlayerContextDataT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = calc_jump_velocity(); _o->calc_jump_velocity = _e; } + { auto _e = interacted_item_number(); _o->interacted_item_number = _e; } + { auto _e = next_corner_pose(); if (_e) _o->next_corner_pose = std::unique_ptr(new TEN::Save::Pose(*_e)); } + { auto _e = projected_floor_height(); _o->projected_floor_height = _e; } + { auto _e = target_orient(); if (_e) _o->target_orient = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } + { auto _e = vehicle_item_number(); _o->vehicle_item_number = _e; } + { auto _e = water_current_active(); _o->water_current_active = _e; } + { auto _e = water_current_pull(); if (_e) _o->water_current_pull = std::unique_ptr(new TEN::Save::Vector3(*_e)); } + { auto _e = water_surface_dist(); _o->water_surface_dist = _e; } +} + +inline flatbuffers::Offset PlayerContextData::Pack(flatbuffers::FlatBufferBuilder &_fbb, const PlayerContextDataT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatePlayerContextData(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatePlayerContextData(flatbuffers::FlatBufferBuilder &_fbb, const PlayerContextDataT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const PlayerContextDataT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _calc_jump_velocity = _o->calc_jump_velocity; + auto _interacted_item_number = _o->interacted_item_number; + auto _next_corner_pose = _o->next_corner_pose ? _o->next_corner_pose.get() : 0; + auto _projected_floor_height = _o->projected_floor_height; + auto _target_orient = _o->target_orient ? _o->target_orient.get() : 0; + auto _vehicle_item_number = _o->vehicle_item_number; + auto _water_current_active = _o->water_current_active; + auto _water_current_pull = _o->water_current_pull ? _o->water_current_pull.get() : 0; + auto _water_surface_dist = _o->water_surface_dist; + return TEN::Save::CreatePlayerContextData( + _fbb, + _calc_jump_velocity, + _interacted_item_number, + _next_corner_pose, + _projected_floor_height, + _target_orient, + _vehicle_item_number, + _water_current_active, + _water_current_pull, + _water_surface_dist); +} + inline LaraT *Lara::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = std::make_unique(); UnPackTo(_o.get(), _resolver); @@ -8542,39 +8588,26 @@ inline LaraT *Lara::UnPack(const flatbuffers::resolver_function_t *_resolver) co inline void Lara::UnPackTo(LaraT *_o, const flatbuffers::resolver_function_t *_resolver) const { (void)_o; (void)_resolver; - { auto _e = effect(); if (_e) _o->effect = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = status(); if (_e) _o->status = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = item_number(); _o->item_number = _e; } + { auto _e = context(); if (_e) _o->context = std::unique_ptr(_e->UnPack(_resolver)); } { auto _e = control(); if (_e) _o->control = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = inventory(); if (_e) _o->inventory = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } - { auto _e = flare(); if (_e) _o->flare = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = torch(); if (_e) _o->torch = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = extra_head_rot(); if (_e) _o->extra_head_rot = std::unique_ptr(new TEN::Save::Vector3(*_e)); } - { auto _e = extra_torso_rot(); if (_e) _o->extra_torso_rot = std::unique_ptr(new TEN::Save::Vector3(*_e)); } - { auto _e = water_current_active(); _o->water_current_active = _e; } - { auto _e = water_current_pull(); if (_e) _o->water_current_pull = std::unique_ptr(new TEN::Save::Vector3(*_e)); } - { auto _e = left_arm(); if (_e) _o->left_arm = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = right_arm(); if (_e) _o->right_arm = std::unique_ptr(_e->UnPack(_resolver)); } - { auto _e = target_arm_angles(); if (_e) { _o->target_arm_angles.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->target_arm_angles[_i] = _e->Get(_i); } } } - { auto _e = target_entity_number(); _o->target_entity_number = _e; } - { auto _e = vehicle(); _o->vehicle = _e; } + { auto _e = effect(); if (_e) _o->effect = std::unique_ptr(_e->UnPack(_resolver)); } { auto _e = extra_anim(); _o->extra_anim = _e; } - { auto _e = hit_frame(); _o->hit_frame = _e; } - { auto _e = hit_direction(); _o->hit_direction = _e; } - { auto _e = projected_floor_height(); _o->projected_floor_height = _e; } - { auto _e = target_facing_angle(); _o->target_facing_angle = _e; } - { auto _e = water_surface_dist(); _o->water_surface_dist = _e; } - { auto _e = interacted_item(); _o->interacted_item = _e; } - { auto _e = next_corner_pose(); if (_e) _o->next_corner_pose = std::unique_ptr(new TEN::Save::Position(*_e)); } - { auto _e = burn_type(); _o->burn_type = _e; } - { auto _e = burn_count(); _o->burn_count = _e; } - { auto _e = burn(); _o->burn = _e; } - { auto _e = burn_blue(); _o->burn_blue = _e; } - { auto _e = burn_smoke(); _o->burn_smoke = _e; } - { auto _e = location(); _o->location = _e; } + { auto _e = extra_head_rot(); if (_e) _o->extra_head_rot = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } + { auto _e = extra_torso_rot(); if (_e) _o->extra_torso_rot = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } + { auto _e = flare(); if (_e) _o->flare = std::unique_ptr(_e->UnPack(_resolver)); } { auto _e = highest_location(); _o->highest_location = _e; } + { auto _e = hit_direction(); _o->hit_direction = _e; } + { auto _e = hit_frame(); _o->hit_frame = _e; } + { auto _e = inventory(); if (_e) _o->inventory = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = left_arm(); if (_e) _o->left_arm = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = location(); _o->location = _e; } { auto _e = location_pad(); _o->location_pad = _e; } + { auto _e = right_arm(); if (_e) _o->right_arm = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = status(); if (_e) _o->status = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = target_arm_orient(); if (_e) _o->target_arm_orient = std::unique_ptr(new TEN::Save::EulerAngles(*_e)); } + { auto _e = target_entity_number(); _o->target_entity_number = _e; } + { auto _e = torch(); if (_e) _o->torch = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = weapons(); if (_e) { _o->weapons.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->weapons[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } } inline flatbuffers::Offset Lara::Pack(flatbuffers::FlatBufferBuilder &_fbb, const LaraT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -8585,74 +8618,48 @@ inline flatbuffers::Offset CreateLara(flatbuffers::FlatBufferBuilder &_fbb (void)_rehasher; (void)_o; struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const LaraT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; - auto _effect = _o->effect ? CreatePlayerEffectData(_fbb, _o->effect.get(), _rehasher) : 0; - auto _status = _o->status ? CreatePlayerStatusData(_fbb, _o->status.get(), _rehasher) : 0; - auto _item_number = _o->item_number; + auto _context = _o->context ? CreatePlayerContextData(_fbb, _o->context.get(), _rehasher) : 0; auto _control = _o->control ? CreateLaraControlData(_fbb, _o->control.get(), _rehasher) : 0; - auto _inventory = _o->inventory ? CreateLaraInventoryData(_fbb, _o->inventory.get(), _rehasher) : 0; - auto _weapons = _fbb.CreateVector> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateCarriedWeaponInfo(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ); - auto _flare = _o->flare ? CreateFlareData(_fbb, _o->flare.get(), _rehasher) : 0; - auto _torch = _o->torch ? CreateTorchData(_fbb, _o->torch.get(), _rehasher) : 0; + auto _effect = _o->effect ? CreatePlayerEffectData(_fbb, _o->effect.get(), _rehasher) : 0; + auto _extra_anim = _o->extra_anim; auto _extra_head_rot = _o->extra_head_rot ? _o->extra_head_rot.get() : 0; auto _extra_torso_rot = _o->extra_torso_rot ? _o->extra_torso_rot.get() : 0; - auto _water_current_active = _o->water_current_active; - auto _water_current_pull = _o->water_current_pull ? _o->water_current_pull.get() : 0; - auto _left_arm = _o->left_arm ? CreateArmInfo(_fbb, _o->left_arm.get(), _rehasher) : 0; - auto _right_arm = _o->right_arm ? CreateArmInfo(_fbb, _o->right_arm.get(), _rehasher) : 0; - auto _target_arm_angles = _fbb.CreateVector(_o->target_arm_angles); - auto _target_entity_number = _o->target_entity_number; - auto _vehicle = _o->vehicle; - auto _extra_anim = _o->extra_anim; - auto _hit_frame = _o->hit_frame; - auto _hit_direction = _o->hit_direction; - auto _projected_floor_height = _o->projected_floor_height; - auto _target_facing_angle = _o->target_facing_angle; - auto _water_surface_dist = _o->water_surface_dist; - auto _interacted_item = _o->interacted_item; - auto _next_corner_pose = _o->next_corner_pose ? _o->next_corner_pose.get() : 0; - auto _burn_type = _o->burn_type; - auto _burn_count = _o->burn_count; - auto _burn = _o->burn; - auto _burn_blue = _o->burn_blue; - auto _burn_smoke = _o->burn_smoke; - auto _location = _o->location; + auto _flare = _o->flare ? CreateFlareData(_fbb, _o->flare.get(), _rehasher) : 0; auto _highest_location = _o->highest_location; + auto _hit_direction = _o->hit_direction; + auto _hit_frame = _o->hit_frame; + auto _inventory = _o->inventory ? CreateLaraInventoryData(_fbb, _o->inventory.get(), _rehasher) : 0; + auto _left_arm = _o->left_arm ? CreateArmInfo(_fbb, _o->left_arm.get(), _rehasher) : 0; + auto _location = _o->location; auto _location_pad = _o->location_pad; + auto _right_arm = _o->right_arm ? CreateArmInfo(_fbb, _o->right_arm.get(), _rehasher) : 0; + auto _status = _o->status ? CreatePlayerStatusData(_fbb, _o->status.get(), _rehasher) : 0; + auto _target_arm_orient = _o->target_arm_orient ? _o->target_arm_orient.get() : 0; + auto _target_entity_number = _o->target_entity_number; + auto _torch = _o->torch ? CreateTorchData(_fbb, _o->torch.get(), _rehasher) : 0; + auto _weapons = _fbb.CreateVector> (_o->weapons.size(), [](size_t i, _VectorArgs *__va) { return CreateCarriedWeaponInfo(*__va->__fbb, __va->__o->weapons[i].get(), __va->__rehasher); }, &_va ); return TEN::Save::CreateLara( _fbb, - _effect, - _status, - _item_number, + _context, _control, - _inventory, - _weapons, - _flare, - _torch, + _effect, + _extra_anim, _extra_head_rot, _extra_torso_rot, - _water_current_active, - _water_current_pull, - _left_arm, - _right_arm, - _target_arm_angles, - _target_entity_number, - _vehicle, - _extra_anim, - _hit_frame, - _hit_direction, - _projected_floor_height, - _target_facing_angle, - _water_surface_dist, - _interacted_item, - _next_corner_pose, - _burn_type, - _burn_count, - _burn, - _burn_blue, - _burn_smoke, - _location, + _flare, _highest_location, - _location_pad); + _hit_direction, + _hit_frame, + _inventory, + _left_arm, + _location, + _location_pad, + _right_arm, + _status, + _target_arm_orient, + _target_entity_number, + _torch, + _weapons); } inline FixedCameraT *FixedCamera::UnPack(const flatbuffers::resolver_function_t *_resolver) const { @@ -8744,7 +8751,7 @@ inline void StaticMeshInfo::UnPackTo(StaticMeshInfoT *_o, const flatbuffers::res (void)_resolver; { auto _e = number(); _o->number = _e; } { auto _e = room_number(); _o->room_number = _e; } - { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Position(*_e)); } + { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Pose(*_e)); } { auto _e = scale(); _o->scale = _e; } { auto _e = color(); if (_e) _o->color = std::unique_ptr(new TEN::Save::Vector4(*_e)); } { auto _e = hit_points(); _o->hit_points = _e; } @@ -8911,6 +8918,35 @@ inline flatbuffers::Offset CreateParticleInfo(flatbuffers::FlatBuf _node_number); } +inline SoundtrackT *Soundtrack::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::make_unique(); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void Soundtrack::UnPackTo(SoundtrackT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = name(); if (_e) _o->name = _e->str(); } + { auto _e = position(); _o->position = _e; } +} + +inline flatbuffers::Offset Soundtrack::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SoundtrackT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreateSoundtrack(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreateSoundtrack(flatbuffers::FlatBufferBuilder &_fbb, const SoundtrackT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const SoundtrackT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _name = _o->name.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->name); + auto _position = _o->position; + return TEN::Save::CreateSoundtrack( + _fbb, + _name, + _position); +} + inline SwarmObjectInfoT *SwarmObjectInfo::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = std::make_unique(); UnPackTo(_o.get(), _resolver); @@ -8921,7 +8957,7 @@ inline void SwarmObjectInfo::UnPackTo(SwarmObjectInfoT *_o, const flatbuffers::r (void)_o; (void)_resolver; { auto _e = on(); _o->on = _e; } - { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Position(*_e)); } + { auto _e = pose(); if (_e) _o->pose = std::unique_ptr(new TEN::Save::Pose(*_e)); } { auto _e = room_number(); _o->room_number = _e; } { auto _e = flags(); _o->flags = _e; } } @@ -9555,13 +9591,9 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi { auto _e = flip_timer(); _o->flip_timer = _e; } { auto _e = flip_status(); _o->flip_status = _e; } { auto _e = current_fov(); _o->current_fov = _e; } + { auto _e = last_inv_item(); _o->last_inv_item = _e; } { auto _e = action_queue(); if (_e) { _o->action_queue.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->action_queue[_i] = _e->Get(_i); } } } - { auto _e = ambient_track(); if (_e) _o->ambient_track = _e->str(); } - { auto _e = ambient_position(); _o->ambient_position = _e; } - { auto _e = oneshot_track(); if (_e) _o->oneshot_track = _e->str(); } - { auto _e = oneshot_position(); _o->oneshot_position = _e; } - { auto _e = voice_track(); if (_e) _o->voice_track = _e->str(); } - { auto _e = voice_position(); _o->voice_position = _e; } + { auto _e = soundtracks(); if (_e) { _o->soundtracks.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->soundtracks[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = cd_flags(); if (_e) { _o->cd_flags.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->cd_flags[_i] = _e->Get(_i); } } } { auto _e = rope(); if (_e) _o->rope = std::unique_ptr(_e->UnPack(_resolver)); } { auto _e = pendulum(); if (_e) _o->pendulum = std::unique_ptr(_e->UnPack(_resolver)); } @@ -9616,13 +9648,9 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild auto _flip_timer = _o->flip_timer; auto _flip_status = _o->flip_status; auto _current_fov = _o->current_fov; + auto _last_inv_item = _o->last_inv_item; auto _action_queue = _fbb.CreateVector(_o->action_queue); - auto _ambient_track = _o->ambient_track.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->ambient_track); - auto _ambient_position = _o->ambient_position; - auto _oneshot_track = _o->oneshot_track.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->oneshot_track); - auto _oneshot_position = _o->oneshot_position; - auto _voice_track = _o->voice_track.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->voice_track); - auto _voice_position = _o->voice_position; + auto _soundtracks = _fbb.CreateVector> (_o->soundtracks.size(), [](size_t i, _VectorArgs *__va) { return CreateSoundtrack(*__va->__fbb, __va->__o->soundtracks[i].get(), __va->__rehasher); }, &_va ); auto _cd_flags = _fbb.CreateVector(_o->cd_flags); auto _rope = _o->rope ? CreateRope(_fbb, _o->rope.get(), _rehasher) : 0; auto _pendulum = _o->pendulum ? CreatePendulum(_fbb, _o->pendulum.get(), _rehasher) : 0; @@ -9669,13 +9697,9 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild _flip_timer, _flip_status, _current_fov, + _last_inv_item, _action_queue, - _ambient_track, - _ambient_position, - _oneshot_track, - _oneshot_position, - _voice_track, - _voice_position, + _soundtracks, _cd_flags, _rope, _pendulum, diff --git a/TombEngine/Specific/savegame/schema/ten_itemdata.fbs b/TombEngine/Specific/savegame/schema/ten_itemdata.fbs index 6ce62ae10..4f409d5c2 100644 --- a/TombEngine/Specific/savegame/schema/ten_itemdata.fbs +++ b/TombEngine/Specific/savegame/schema/ten_itemdata.fbs @@ -1,6 +1,6 @@ namespace TEN.Save; -struct Position { +struct Pose { x_pos: int32; y_pos: int32; z_pos: int32; @@ -15,7 +15,7 @@ table CreatureTarget { box_number: int32; flags: int32; trigger_flags: int32; - position: Position; + position: Pose; } table Creature { @@ -93,7 +93,7 @@ table Kayak { right_vertical_velocity: int32; left_right_count: int32; water_height: int32; - old_pos: Position; + old_pos: Pose; turn: bool; forward: bool; true_water: bool; @@ -177,7 +177,13 @@ table Float { } table ShortArray { - arr: [short]; + arr: [short]; +} + +struct EulerAngles { + x: short; + y: short; + z: short; } struct Vector2 { @@ -211,7 +217,7 @@ union ItemData { ulong, double,*/ Int, - Short, + Short, Float, ShortArray, ItemNumber, diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs index 82f9d3bae..0eb8632d8 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -37,7 +37,7 @@ table Item { carried_item: int32; after_death: int32; item_flags: [int32]; - pose: Position; + pose: Pose; next_item: int32; next_item_active: int32; active: bool; @@ -65,7 +65,7 @@ table Item { } table FXInfo { - pose : Position; + pose : Pose; room_number: int32; object_number: int32; next_fx: int32; @@ -112,7 +112,7 @@ table ArmInfo { frame_number: int32; frame_base: int32; locked: bool; - rotation: Vector3; + rotation: EulerAngles; gun_flash: int32; gun_smoke: int32; } @@ -222,7 +222,6 @@ table SubsuitControlData { table LaraControlData { move_angle: int32; turn_rate: int32; - calculated_jump_velocity: int32; jump_direction: int32; hand_status: int32; water_status: int32; @@ -254,40 +253,39 @@ table PlayerStatusData { stamina: int32; } -table Lara { - effect: PlayerEffectData; - status: PlayerStatusData; - item_number: int32; - control: LaraControlData; - inventory: LaraInventoryData; - weapons: [CarriedWeaponInfo]; - flare: FlareData; - torch: TorchData; - extra_head_rot: Vector3; - extra_torso_rot: Vector3; +table PlayerContextData { + calc_jump_velocity: int32; + interacted_item_number: int32; + next_corner_pose: Pose; + projected_floor_height: int32; + target_orient: EulerAngles; + vehicle_item_number: int32; water_current_active: int32; water_current_pull: Vector3; - left_arm: ArmInfo; - right_arm: ArmInfo; - target_arm_angles: [int32]; - target_entity_number: int32; - vehicle: int32; - extra_anim: int32; - hit_frame: int32; - hit_direction: int32; - projected_floor_height: int32; - target_facing_angle: int32; water_surface_dist: int32; - interacted_item: int32; - next_corner_pose: Position; - burn_type: int32; - burn_count: uint32; - burn: bool; - burn_blue: int32; - burn_smoke: bool; - location: int32; +} + +table Lara { + context: PlayerContextData; + control: LaraControlData; + effect: PlayerEffectData; + extra_anim: int32; + extra_head_rot: EulerAngles; + extra_torso_rot: EulerAngles; + flare: FlareData; highest_location: int32; + hit_direction: int32; + hit_frame: int32; + inventory: LaraInventoryData; + left_arm: ArmInfo; + location: int32; location_pad: int32; + right_arm: ArmInfo; + status: PlayerStatusData; + target_arm_orient: EulerAngles; + target_entity_number: int32; + torch: TorchData; + weapons: [CarriedWeaponInfo]; } table FixedCamera { @@ -305,7 +303,7 @@ table Sink { table StaticMeshInfo { number: int32; room_number: int32; - pose: Position; + pose: Pose; scale: float; color: Vector4; hit_points: int32; @@ -352,9 +350,14 @@ table ParticleInfo { node_number: int32; } +table Soundtrack { + name: string; + position: uint64; +} + table SwarmObjectInfo { on: bool; - pose: Position; + pose: Pose; room_number: int32; flags: int32; } @@ -510,13 +513,9 @@ table SaveGame { flip_timer: int32; flip_status: int32; current_fov: int16; + last_inv_item: int32; action_queue: [int32]; - ambient_track: string; - ambient_position: uint64; - oneshot_track: string; - oneshot_position: uint64; - voice_track: string; - voice_position: uint64; + soundtracks: [Soundtrack]; cd_flags: [int32]; rope: Rope; pendulum: Pendulum; diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index bee15b94d..215d7cc4b 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -205,7 +205,7 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { if ((signed int)(unsigned short)wParam > 0 && (signed int)(unsigned short)wParam <= 2) { - if (!g_Configuration.Windowed) + if (!g_Configuration.EnableWindowedMode) g_Renderer.ToggleFullScreen(true); if (!DebugMode && ThreadHandle > 0) @@ -220,7 +220,7 @@ LRESULT CALLBACK WinAppProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) } else { - if (!g_Configuration.Windowed) + if (!g_Configuration.EnableWindowedMode) ShowWindow(hWnd, SW_MINIMIZE); if (!DebugMode) @@ -388,8 +388,8 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine RECT Rect; Rect.left = 0; Rect.top = 0; - Rect.right = g_Configuration.Width; - Rect.bottom = g_Configuration.Height; + Rect.right = g_Configuration.ScreenWidth; + Rect.bottom = g_Configuration.ScreenHeight; AdjustWindowRect(&Rect, WS_CAPTION, false); // Make window handle. @@ -425,7 +425,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine CoInitializeEx(NULL, COINIT_MULTITHREADED); // Initialize the renderer - g_Renderer.Initialize(g_Configuration.Width, g_Configuration.Height, g_Configuration.Windowed, App.WindowHandle); + g_Renderer.Initialize(g_Configuration.ScreenWidth, g_Configuration.ScreenHeight, g_Configuration.EnableWindowedMode, App.WindowHandle); // Initialize audio Sound_Init(gameDir); @@ -498,5 +498,4 @@ void WinClose() ShutdownTENLog(); CoUninitialize(); - } \ No newline at end of file diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index d08fd0017..4f195aed6 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -323,11 +323,11 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" + - @@ -373,7 +373,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - @@ -570,6 +569,8 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" + + @@ -585,8 +586,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - - @@ -796,15 +795,15 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - + - + - - + + @@ -818,7 +817,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - @@ -1013,6 +1011,8 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" + + @@ -1028,8 +1028,6 @@ xcopy /Y "$(SolutionDir)Libs\zlib\x64\*.dll" "$(TargetDir)" - -