From f54ad0f865083485e91b71233481faed5c6d8633 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 12 Aug 2022 11:59:51 +0100 Subject: [PATCH 001/106] Improve error messages and properly shut down TENLog if we have to crash the game. --- TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp | 5 +++-- TombEngine/Specific/winmain.cpp | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index b1828248e..9dd54070a 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -244,8 +244,9 @@ bool FlowHandler::DoFlow() } catch (TENScriptException const& e) { - std::string msg = std::string{ "An unrecoverable error occurred in " } + __func__ + ": " + e.what(); + std::string msg = std::string{ "A Lua error occurred while running the title level; " } + __func__ + ": " + e.what(); TENLog(msg, LogLevel::Error, LogConfig::All); + ShutdownTENLog(); throw; } } @@ -277,7 +278,7 @@ bool FlowHandler::DoFlow() } catch (TENScriptException const& e) { - std::string msg = std::string{ "An unrecoverable error occurred in " } + __func__ + ": " + e.what(); + std::string msg = std::string{ "A Lua error occurred while running a level; " } + __func__ + ": " + e.what(); TENLog(msg, LogLevel::Error, LogConfig::All); status = GameStatus::ExitToTitle; } diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 41f1de856..5e3ff1d48 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -290,7 +290,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } catch (TENScriptException const& e) { - std::string msg = std::string{ "An unrecoverable error occurred in " } + __func__ + ": " + e.what(); + std::string msg = std::string{ "A Lua error occurred while setting up scripts; " } + __func__ + ": " + e.what(); TENLog(msg, LogLevel::Error, LogConfig::All); ShutdownTENLog(); return 0; From 47c7775ee18e88ddae6c8b80e1c742ef3acd2371 Mon Sep 17 00:00:00 2001 From: hispidence Date: Sun, 14 Aug 2022 18:17:07 +0100 Subject: [PATCH 002/106] Add EventSequence documentation --- .../5 lua utility modules/EventSequence.html | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 Documentation/doc/5 lua utility modules/EventSequence.html diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html new file mode 100644 index 000000000..be2753a3d --- /dev/null +++ b/Documentation/doc/5 lua utility modules/EventSequence.html @@ -0,0 +1,340 @@ + + + + + TombEngine 1.0.1 Lua API + + + + +
+ +
+ +
+
+
+ + +
+ + + + + + +
+ +

Lua utility module EventSequence

+

Event sequence - a chain of functions to call at specified times, modeled after TRNG's organizers.

+

+ +

Example usage:

+ +
+local EventSequence = require("EventSequence")
+
+-- These will be called by the sequence
+LevelFuncs.HealLara = function()
+    Lara:SetHP(Lara:GetHP()+10)
+end
+
+local nSpawned = 0
+LevelFuncs.SpawnBaddy = function(baddy, name, pos)
+    local myBaddy = TEN.Objects.Moveable(baddy, name..nSpawned, pos, nil, 0)
+    myBaddy:Enable()
+    nSpawned = nSpawned + 1
+end
+
+-- This function triggers the sequence
+LevelFuncs.TriggerSequence = function(obj)
+    local posSteve = TEN.Objects.GetMoveableByName("stevePosNullmesh"):GetPosition()
+    local posChris = TEN.Objects.GetMoveableByName("chrisPosNullmesh"):GetPosition()
+    local mySeq = EventSequence.Create("my_seq",
+        false, -- does not loop
+        {seconds = true, deciseconds = true}, -- timer format, see Timer for details
+        6, -- seconds until call the function specified in next arg
+        "HealLara", -- first function to call. If we don't need to pass any arguments, we can just give the func name as a string
+        2.1, -- seconds until the next function, after the previous one has been called
+        {"SpawnBaddy", TEN.Objects.ObjID.BADDY1, "steve", posSteve}, -- if we DO want to pass arguments to the function to be called, we give a table with the name of the function ("SpawnBaddy" in this case) followed by the args to pass to it
+        0.5,
+        {"SpawnBaddy", TEN.Objects.ObjID.SAS_CAIRO, "chris", posChris},
+        1,
+        "HealLara")
+
+    -- event sequences are inactive to begin with and so need to be started
+    mySeq:Start()
+end
+
+-- EventSequence runs on Timer, so this call is required
+LevelFuncs.OnControlPhase = function(dt)
+    Timer.UpdateAll(dt)
+end
+
+ +

+ + +

Functions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Create(name, loop, timerFormat[, ...])Create (but do not start) a new event sequence.
Get(name)Get an event sequence by its name.
mySequence:SetPaused(p)Pause or unpause the sequence.
mySequence:IsPaused()Get whether or not the sequence is paused
mySequence:Start()Begin or unpause a sequence.
mySequence:Stop()Stop the sequence.
mySequence:IsActive()Get whether or not the sequence is active
+ +
+
+ + +

Functions

+ +
+
+ + Create(name, loop, timerFormat[, ...]) +
+
+ Create (but do not start) a new event sequence. + + +

Parameters:

+
    +
  • name + string + A label to give the sequence; used to retrieve the timer later as well as internally by TEN. +
  • +
  • loop + bool + if true, the sequence will start again from its first timer once its final function has been called +
  • +
  • timerFormat + table or bool + same as in Timer. This is mainly for debugging. This will not work properly if another sequence or timer is showing a countdown. +
  • +
  • ... + a variable number of pairs of arguments - a time in seconds, followed by the function (must be defined in the LevelFuncs table) to call once the time has elapsed, followed by another duration in seconds, another function name, etc. You can specify a function either by its name as a string, or by a table with the function name as the first member, followed by its arguments (see above example). + (optional) +
  • +
+ +

Returns:

+
    + + The inactive sequence. +
+ + + + +
+
+ + Get(name) +
+
+ Get an event sequence by its name. + + +

Parameters:

+
    +
  • name + string + The label that was given to the sequence when it was created +
  • +
+ +

Returns:

+
    + + The sequence +
+ + + + +
+
+ + mySequence:SetPaused(p) +
+
+ Pause or unpause the sequence. If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused). + + +

Parameters:

+
    +
  • p + bool + if true, the sequence will be paused; if false, it will be unpaused +
  • +
+ + + + + +
+
+ + mySequence:IsPaused() +
+
+ Get whether or not the sequence is paused + + + +

Returns:

+
    + + true if the timer is paused, false if otherwise +
+ + + + +
+
+ + mySequence:Start() +
+
+ Begin or unpause a sequence. If showing the remaining time on-screen, its color will be set to white. + + + + + + + +
+
+ + mySequence:Stop() +
+
+ Stop the sequence. + + + + + + + +
+
+ + mySequence:IsActive() +
+
+ Get whether or not the sequence is active + + + +

Returns:

+
    + + true if the sequence is active, false if otherwise +
+ + + + +
+
+ + +
+
+
+generated by LDoc 1.4.6 +Last updated 2022-08-11 22:43:52 +
+
+ + From d9e0ecb79ed178291ef90df75c99afb4812fefd2 Mon Sep 17 00:00:00 2001 From: hispidence Date: Mon, 15 Aug 2022 17:43:19 +0100 Subject: [PATCH 003/106] Hopefully fix #627 --- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 2d7f28eaf..9057db93e 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -131,6 +131,8 @@ void LogicHandler::ResetScripts(bool clearGameVars) ResetGameTables(); m_handler.ResetGlobals(); + + m_handler.GetState()->collect_garbage(); } void LogicHandler::FreeLevelScripts() From 96d1af28a72b2d7886a05e0c86713e176dbac964 Mon Sep 17 00:00:00 2001 From: hispidence Date: Mon, 15 Aug 2022 18:31:15 +0100 Subject: [PATCH 004/106] Finish PlaySound documentation. --- Documentation/doc/1 modules/Misc.html | 61 +++++++++---------- .../Internal/TEN/Misc/Miscellanous.cpp | 8 +-- 2 files changed, 34 insertions(+), 35 deletions(-) diff --git a/Documentation/doc/1 modules/Misc.html b/Documentation/doc/1 modules/Misc.html index 86d155089..22ce29e8d 100644 --- a/Documentation/doc/1 modules/Misc.html +++ b/Documentation/doc/1 modules/Misc.html @@ -124,6 +124,10 @@ Set and play an ambient track + PlaySound(sound[, position]) + Play sound effect + + CalculateDistance(posA, posB) Calculate the distance between two positions. @@ -144,10 +148,6 @@ Vibrate gamepad, if possible. - PlaySound(sound, position) - Play sound effect - - KeyIsHeld(action) Check if particular action key is held @@ -355,6 +355,32 @@ eyes of the creatures would be. + +
+ + PlaySound(sound[, position]) +
+
+ Play sound effect + + +

Parameters:

+
    +
  • sound + int + ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window. +
  • +
  • position + Vec3 + The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional. + (optional) +
  • +
+ + + + +
@@ -514,33 +540,6 @@ To be used with - PlaySound(sound, position) -
-
- Play sound effect - - -

Parameters:

-
    -
  • sound - int - ID to play -
  • -
  • position - Vec3 - - - -
  • -
- - - - -
diff --git a/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp b/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp index a36abe198..d63c2d78b 100644 --- a/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp +++ b/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp @@ -120,6 +120,10 @@ namespace Misc PlaySoundTrack(trackName, SoundTrackType::BGM); } + /// Play sound effect + //@function PlaySound + //@tparam int sound ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window. + ////@tparam[opt] Vec3 position The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional. static void PlaySoundEffect(int id, sol::optional p) { SoundEffect(id, p.has_value() ? &PHD_3DPOS(p.value().x, p.value().y, p.value().z) : nullptr, SoundEnvironment::Always); @@ -222,10 +226,6 @@ namespace Misc table_misc.set_function(ScriptReserved_PlayAudioTrack, &PlayAudioTrack); - /// Play sound effect - //@function PlaySound - //@tparam int sound ID to play - //@tparam Vec3 position table_misc.set_function(ScriptReserved_PlaySound, &PlaySoundEffect); /// Check if particular action key is held From e9329f9c1368c3029a94921a8f9e8ec67576bce2 Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 16 Aug 2022 20:55:43 +1000 Subject: [PATCH 005/106] Convert some probabilities; tr5_larson.cpp cleanup --- .../Objects/TR3/Entity/tr3_flamethrower.cpp | 15 +- TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 27 +- TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 26 +- .../Objects/TR3/Entity/tr3_mp_stick.cpp | 14 +- TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 2 +- .../Objects/TR3/Entity/tr3_tribesman.cpp | 5 +- .../Objects/TR5/Entity/tr5_autoguns.cpp | 24 +- TombEngine/Objects/TR5/Entity/tr5_chef.cpp | 11 +- .../Objects/TR5/Entity/tr5_doberman.cpp | 44 +-- .../Objects/TR5/Entity/tr5_gladiator.cpp | 20 +- TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 30 +- TombEngine/Objects/TR5/Entity/tr5_hydra.cpp | 28 +- .../Objects/TR5/Entity/tr5_lagoon_witch.cpp | 1 + TombEngine/Objects/TR5/Entity/tr5_larson.cpp | 272 +++++++++--------- 14 files changed, 269 insertions(+), 250 deletions(-) diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index cdda7e9c1..5af828ce5 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -14,8 +14,11 @@ #include "Game/people.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; + namespace TEN::Entities::TR3 { const auto FlamethrowerOffset = Vector3Int(0, 340, 0); @@ -57,9 +60,7 @@ namespace TEN::Entities::TR3 TriggerPilotFlame(itemNumber, 9); } else - { TriggerDynamicLight(pos.x, pos.y, pos.z, (random & 3) + 10, 31 - ((random / 16) & 3), 24 - ((random / 64) & 3), random & 7); - } if (item->HitPoints <= 0) { @@ -154,7 +155,7 @@ namespace TEN::Entities::TR3 { head = AIGuard(creature); - if (!(GetRandomControl() & 0xFF)) + if (TestProbability(0.008f)) item->Animation.TargetState = 4; break; @@ -170,9 +171,9 @@ namespace TEN::Entities::TR3 else item->Animation.TargetState = 2; } - else if (creature->Mood == MoodType::Bored && AI.ahead && !(GetRandomControl() & 0xFF)) + else if (creature->Mood == MoodType::Bored && AI.ahead && TestProbability(0.008f)) item->Animation.TargetState = 4; - else if (creature->Mood == MoodType::Attack || !(GetRandomControl() & 0xFF)) + else if (creature->Mood == MoodType::Attack || TestProbability(0.008f)) item->Animation.TargetState = 2; break; @@ -184,7 +185,7 @@ namespace TEN::Entities::TR3 { head = AIGuard(creature); - if (!(GetRandomControl() & 0xFF)) + if (TestProbability(0.008f)) item->Animation.TargetState = 1; break; @@ -193,7 +194,7 @@ namespace TEN::Entities::TR3 AI.distance < pow(SECTOR(4), 2) && (realEnemy != LaraItem || creature->HurtByLara) || creature->Mood != MoodType::Bored || - !(GetRandomControl() & 0xFF))) + TestProbability(0.008f))) { item->Animation.TargetState = 1; } diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index d01d4a5fb..806106f26 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -10,21 +10,22 @@ #include "Game/Lara/lara.h" #include "Game/misc.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR3 { - const vector MonkeyAttackJoints = { 10, 13 }; const auto MonkeyBite = BiteInfo(Vector3(10.0f, 10.0f, 11.0f), 13); + const vector MonkeyAttackJoints = { 10, 13 }; void InitialiseMonkey(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 2; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = 6; @@ -154,9 +155,9 @@ namespace TEN::Entities::TR3 if (item->AIBits & GUARD) { torsoY = AIGuard(creature); - if (!(GetRandomControl() & 0xF)) + if (TestProbability(0.06f)) { - if (GetRandomControl() & 0x1) + if (TestProbability(0.5f)) item->Animation.TargetState = 8; else item->Animation.TargetState = 7; @@ -173,11 +174,11 @@ namespace TEN::Entities::TR3 { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; - else if (!(GetRandomControl() & 0xF)) + else if (TestProbability(0.06f)) item->Animation.TargetState = 2; - else if (!(GetRandomControl() & 0xF)) + else if (TestProbability(0.06f)) { - if (GetRandomControl() & 0x1) + if (TestProbability(0.5f)) item->Animation.TargetState = 8; else item->Animation.TargetState = 7; @@ -210,9 +211,9 @@ namespace TEN::Entities::TR3 { torsoY = AIGuard(creature); - if (!(GetRandomControl() & 15)) + if (TestProbability(0.06f)) { - if (GetRandomControl() & 1) + if (TestProbability(0.5f)) item->Animation.TargetState = 10; else item->Animation.TargetState = 6; @@ -233,11 +234,11 @@ namespace TEN::Entities::TR3 { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; - else if (!(GetRandomControl() & 15)) + else if (TestProbability(0.06f)) item->Animation.TargetState = 2; - else if (!(GetRandomControl() & 15)) + else if (TestProbability(0.06f)) { - if (GetRandomControl() & 1) + if (TestProbability(0.5f)) item->Animation.TargetState = 10; else item->Animation.TargetState = 6; @@ -361,7 +362,7 @@ namespace TEN::Entities::TR3 item->Animation.TargetState = 4; else if (creature->Mood == MoodType::Bored) { - if (GetRandomControl() < 256) + if (TestProbability(0.008f)) item->Animation.TargetState = 6; } else if (AI.bite && AI.distance < pow(682, 2)) diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index 2526236f9..a46c432c2 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -14,8 +14,11 @@ #include "Game/people.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; + namespace TEN::Entities::TR3 { const auto MPGunBite = BiteInfo(Vector3(0.0f, 160.0f, 40.0f), 13); @@ -76,8 +79,8 @@ namespace TEN::Entities::TR3 if (item->BoxNumber != NO_BOX && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED)) { - DoLotsOfBlood(item->Pose.Position.x, item->Pose.Position.y - (GetRandomControl() & 255) - 32, item->Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() * 2, item->RoomNumber, 3); DoDamage(item, 20); + DoLotsOfBlood(item->Pose.Position.x, item->Pose.Position.y - (GetRandomControl() & 255) - 32, item->Pose.Position.z, (GetRandomControl() & 127) + 128, GetRandomControl() * 2, item->RoomNumber, 3); } AI_INFO AI; @@ -91,7 +94,7 @@ namespace TEN::Entities::TR3 item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = 13; } - else if (!(GetRandomControl() & 3) && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 1) + else if (TestProbability(0.25f) && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 1) { CreatureAIInfo(item, &AI); @@ -220,10 +223,9 @@ namespace TEN::Entities::TR3 item->Animation.TargetState = MPGUN_STATE_RUN; else if (Targetable(item, &AI)) { - int random = GetRandomControl(); - if (random < 0x2000) + if (TestProbability(0.25f)) item->Animation.TargetState = MPGUN_STATE_SHOOT_1; - else if (random < 0x4000) + else if (TestProbability(0.5f)) item->Animation.TargetState = MPGUN_STATE_SHOOT_2; else item->Animation.TargetState = MPGUN_STATE_AIM_3; @@ -315,7 +317,7 @@ namespace TEN::Entities::TR3 if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) item->Animation.RequiredState = MPGUN_STATE_WAIT; } - else if (item->HitStatus && !(GetRandomControl() & 0x3) && cover) + else if (item->HitStatus && TestProbability(0.25f) && cover) { item->Animation.RequiredState = MPGUN_STATE_CROUCH; item->Animation.TargetState = MPGUN_STATE_WAIT; @@ -347,7 +349,7 @@ namespace TEN::Entities::TR3 if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) item->Animation.TargetState = MPGUN_STATE_WAIT; } - else if (item->HitStatus && !(GetRandomControl() & 0x3) && cover) + else if (item->HitStatus && TestProbability(0.25f) && cover) { item->Animation.RequiredState = MPGUN_STATE_CROUCH; item->Animation.TargetState = MPGUN_STATE_WAIT; @@ -369,7 +371,7 @@ namespace TEN::Entities::TR3 if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) item->Animation.TargetState = MPGUN_STATE_WAIT; } - else if (item->HitStatus && !(GetRandomControl() & 0x3) && cover) + else if (item->HitStatus && TestProbability(0.25f) && cover) { item->Animation.RequiredState = MPGUN_STATE_CROUCH; item->Animation.TargetState = MPGUN_STATE_WAIT; @@ -390,7 +392,7 @@ namespace TEN::Entities::TR3 if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) item->Animation.RequiredState = MPGUN_STATE_WALK; } - else if (item->HitStatus && !(GetRandomControl() & 0x3) && cover) + else if (item->HitStatus && TestProbability(0.25f) && cover) { item->Animation.RequiredState = MPGUN_STATE_CROUCH; item->Animation.TargetState = MPGUN_STATE_WAIT; @@ -431,7 +433,7 @@ namespace TEN::Entities::TR3 if (Targetable(item, &AI)) item->Animation.TargetState = MPGUN_STATE_CROUCH_AIM; - else if (item->HitStatus || !cover || (AI.ahead && !(GetRandomControl() & 0x1F))) + else if (item->HitStatus || !cover || (AI.ahead && TestProbability(0.03f))) item->Animation.TargetState = MPGUN_STATE_STAND; else item->Animation.TargetState = MPGUN_STATE_CROUCH_WALK; @@ -457,7 +459,7 @@ namespace TEN::Entities::TR3 if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32) || !(GetRandomControl() & 0x7)) + if (!ShotLara(item, &AI, MPGunBite, torsoY, 32) || TestProbability(0.125f)) item->Animation.TargetState = MPGUN_STATE_CROUCHED; } @@ -469,7 +471,7 @@ namespace TEN::Entities::TR3 if (AI.ahead) head = AI.angle; - if (Targetable(item, &AI) || item->HitStatus || !cover || (AI.ahead && !(GetRandomControl() & 0x1F))) + if (Targetable(item, &AI) || item->HitStatus || !cover || (AI.ahead && TestProbability(0.03f))) item->Animation.TargetState = MPGUN_STATE_CROUCHED; break; diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index 94676c6f2..3378fed0e 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -11,8 +11,10 @@ #include "Game/people.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR3 @@ -20,7 +22,7 @@ namespace TEN::Entities::TR3 const auto MPStickBite1 = BiteInfo(Vector3(247.0f, 10.0f, 11.0f), 13); const auto MPStickBite2 = BiteInfo(Vector3(0.0f, 0.0f, 100.0f), 6); const vector MPStickPunchAttackJoints = { 10, 13 }; - const vector MPStickKickAttackJoints = { 5, 6 }; + const vector MPStickKickAttackJoints = { 5, 6 }; enum MPStickState { @@ -184,7 +186,7 @@ namespace TEN::Entities::TR3 if (item->AIBits & GUARD) { head = AIGuard(creature); - if (!(GetRandomControl() & 0xFF)) + if (TestProbability(0.004f)) { if (item->Animation.ActiveState == MPSTICK_STATE_STOP) item->Animation.TargetState = MPSTICK_STATE_WAIT; @@ -240,7 +242,7 @@ namespace TEN::Entities::TR3 item->Animation.TargetState = MPSTICK_STATE_RUN; else if (creature->Mood == MoodType::Bored) { - if (GetRandomControl() < 0x100) + if (TestProbability(0.008f)) { item->Animation.RequiredState = MPSTICK_STATE_WAIT; item->Animation.TargetState = MPSTICK_STATE_STOP; @@ -458,8 +460,8 @@ namespace TEN::Entities::TR3 if (creature->Flags != 1 && item->TestBits(JointBitType::Touch, MPStickKickAttackJoints) && item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 8) { - CreatureEffect(item, MPStickBite2, DoBloodSplat); DoDamage(enemy, 150); + CreatureEffect(item, MPStickBite2, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; } @@ -473,10 +475,10 @@ namespace TEN::Entities::TR3 abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) { - creature->Flags = 1; - CreatureEffect(item, MPStickBite2, DoBloodSplat); DoDamage(enemy, 9); + CreatureEffect(item, MPStickBite2, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); + creature->Flags = 1; } } } diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index 9f1829f04..5a1864f7b 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -86,7 +86,7 @@ namespace TEN::Entities::TR3 } else { - if (creature->Enemy == nullptr || !(GetRandomControl() & 0x7F)) // TODO: Probability is 0.004f or 0.996f? + if (creature->Enemy == nullptr || TestProbability(0.008f)) { ItemInfo* nearestItem = nullptr; int minDistance = INT_MAX; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index 7eac71702..f8abb0681 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -280,6 +280,7 @@ namespace TEN::Entities::TR3 case TRIBESMAN_STATE_AXE_ATTACK_HIGH_START: creature->MaxTurn = ANGLE(4.0f); + if (AI.bite || AI.distance < pow(682, 2)) item->Animation.TargetState = TRIBESMAN_STATE_AXE_ATTACK_HIGH_CONTINUE; else @@ -452,7 +453,7 @@ namespace TEN::Entities::TR3 torsoX = 0; torsoY = 0; - if (!(GetRandomControl() & 0xFF)) + if (TestProbability(0.004f)) item->Animation.TargetState = TRIBESMAN_STATE_IDLE; break; @@ -493,7 +494,7 @@ namespace TEN::Entities::TR3 torsoX = 0; torsoY = 0; - if (!(GetRandomControl() & 0xFF)) + if (TestProbability(0.004f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp b/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp index b56f70de7..380cc0bfb 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp @@ -1,14 +1,18 @@ #include "framework.h" -#include "tr5_autoguns.h" -#include "Game/collision/sphere.h" -#include "Game/Lara/lara.h" +#include "Objects/TR5/Entity/tr5_autoguns.h" + #include "Game/animation.h" +#include "Game/collision/sphere.h" #include "Game/control/los.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" #include "Specific/level.h" #include "Sound/sound.h" -#include "Game/items.h" +#include "Specific/prng.h" + +using namespace TEN::Math::Random; namespace TEN::Entities::TR5 { @@ -64,10 +68,10 @@ namespace TEN::Entities::TR5 item->MeshBits = 1664; - GameVector pos1 = { 0, 0, -64 }; + auto pos1 = GameVector(0, 0, -64); GetJointAbsPosition(item, (Vector3Int*)&pos1, 8); - GameVector pos2 = { 0, 0, 0 }; + auto pos2 = GameVector(); GetLaraJointPosition((Vector3Int*)&pos2, 0); pos1.roomNumber = item->RoomNumber; @@ -95,7 +99,7 @@ namespace TEN::Entities::TR5 data[1] = item->ItemFlags[1]; data[2] += item->ItemFlags[2]; - if (abs(angle1) < 1024 && abs(angle2) < 1024 && los) + if (abs(angle1) < ANGLE(5.6f) && abs(angle2) < ANGLE(5.6f) && los) { SoundEffect(SFX_TR4_HK_FIRE, &item->Pose, SoundEnvironment::Land, 0.8f); @@ -105,10 +109,10 @@ namespace TEN::Entities::TR5 TriggerDynamicLight(pos1.x, pos1.y, pos1.z, 10, (GetRandomControl() & 0x1F) + 192, (GetRandomControl() & 0x1F) + 128, 0); - if (GetRandomControl() & 3) + if (TestProbability(0.75f)) { - auto pos2 = Vector3Int(); - GetLaraJointPosition((Vector3Int*)&pos2, GetRandomControl() % 15); + auto pos2 = Vector3Int::Zero; + GetLaraJointPosition(&pos2, GetRandomControl() % 15); DoBloodSplat(pos2.x, pos2.y, pos2.z, (GetRandomControl() & 3) + 3, 2 * GetRandomControl(), LaraItem->RoomNumber); DoDamage(LaraItem, 20); diff --git a/TombEngine/Objects/TR5/Entity/tr5_chef.cpp b/TombEngine/Objects/TR5/Entity/tr5_chef.cpp index d61157779..6e58f1cda 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_chef.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_chef.cpp @@ -1,16 +1,17 @@ #include "framework.h" -#include "tr5_chef.h" +#include "Objects/TR5/Entity/tr5_chef.h" + #include "Game/items.h" #include "Game/control/box.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" -#include "Game/people.h" -#include "Specific/setup.h" -#include "Specific/level.h" +#include "Game/itemdata/creature_info.h" #include "Game/Lara/lara.h" #include "Game/misc.h" +#include "Game/people.h" #include "Sound/sound.h" -#include "Game/itemdata/creature_info.h" +#include "Specific/level.h" +#include "Specific/setup.h" namespace TEN::Entities::TR5 { diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp index 9447b3418..7c386d4bd 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp @@ -1,14 +1,18 @@ #include "framework.h" -#include "tr5_doberman.h" +#include "Objects/TR5/Entity/tr5_doberman.h" + #include "Game/control/box.h" -#include "Game/effects/effects.h" -#include "Specific/setup.h" -#include "Specific/level.h" -#include "Game/Lara/lara.h" -#include "Game/itemdata/creature_info.h" #include "Game/control/control.h" +#include "Game/effects/effects.h" +#include "Game/itemdata/creature_info.h" #include "Game/items.h" +#include "Game/Lara/lara.h" #include "Game/misc.h" +#include "Specific/level.h" +#include "Specific/prng.h" +#include "Specific/setup.h" + +using namespace TEN::Math::Random; namespace TEN::Entities::TR5 { @@ -106,20 +110,21 @@ namespace TEN::Entities::TR5 item->Animation.TargetState = DOBERMAN_STATE_RUN_FORWARD; else { - int random = GetRandomControl(); - if (random < 768) + if (TestProbability(0.025f)) { item->Animation.RequiredState = DOBERMAN_STATE_STAND_LOW_BITE_ATTACK; item->Animation.TargetState = DOBERMAN_STATE_STOP; break; } - if (random < 1536) + + if (TestProbability(0.045f)) { item->Animation.RequiredState = DOBERMAN_STATE_SIT_IDLE; item->Animation.TargetState = DOBERMAN_STATE_STOP; break; } - if (random < 2816) + + if (TestProbability(0.085f)) { item->Animation.TargetState = DOBERMAN_STATE_STOP; break; @@ -146,6 +151,7 @@ namespace TEN::Entities::TR5 case DOBERMAN_STATE_STOP: creature->MaxTurn = 0; creature->Flags = 0; + if (creature->Mood != MoodType::Bored) { if (creature->Mood != MoodType::Escape && @@ -163,12 +169,11 @@ namespace TEN::Entities::TR5 item->Animation.TargetState = item->Animation.RequiredState; else { - int random = GetRandomControl(); - if (random >= 768) + if (TestProbability(0.975f)) { - if (random >= 1536) + if (TestProbability(0.95f)) { - if (random < 9728) + if (TestProbability(0.3f)) item->Animation.TargetState = DOBERMAN_STATE_WALK_FORWARD; } else @@ -178,22 +183,23 @@ namespace TEN::Entities::TR5 item->Animation.TargetState = DOBERMAN_STATE_STAND_LOW_BITE_ATTACK; } } + break; case DOBERMAN_STATE_STAND_LOW_BITE_ATTACK: - if (creature->Mood != MoodType::Bored || GetRandomControl() < 1280) + if (creature->Mood != MoodType::Bored || TestProbability(0.04f)) item->Animation.TargetState = DOBERMAN_STATE_STOP; break; case DOBERMAN_STATE_SIT_IDLE: - if (creature->Mood != MoodType::Bored || GetRandomControl() < 256) + if (creature->Mood != MoodType::Bored || TestProbability(0.008f)) item->Animation.TargetState = DOBERMAN_STATE_STOP; break; case DOBERMAN_STATE_STAND_IDLE: - if (creature->Mood != MoodType::Bored || GetRandomControl() < 512) + if (creature->Mood != MoodType::Bored || TestProbability(0.015f)) item->Animation.TargetState = DOBERMAN_STATE_STOP; break; @@ -201,8 +207,7 @@ namespace TEN::Entities::TR5 case DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK: creature->MaxTurn = ANGLE(0.5f); - if (creature->Flags != 1 && - AI.ahead && + if (creature->Flags != 1 && AI.ahead && item->TouchBits & 0x122000) { DoDamage(creature->Enemy, 30); @@ -244,6 +249,7 @@ namespace TEN::Entities::TR5 CreatureEffect(item, DobermanBite, DoBloodSplat); creature->Flags = 3; } + if (AI.distance < pow(341, 2)) item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index abe2c8b45..aae3085dd 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -24,8 +24,8 @@ namespace TEN::Entities::TR5 // TODO: Ranges. - const vector GladiatorAttackJoints = { 13, 14 }; const auto GladiatorBite = BiteInfo(Vector3::Zero, 16); + const vector GladiatorAttackJoints = { 13, 14 }; enum GladiatorState { @@ -156,7 +156,7 @@ namespace TEN::Entities::TR5 creature->Flags = 0; if (item->AIBits & GUARD || - !(GetRandomControl() & 0x1F) && + TestProbability(0.03f) && (AI.distance > pow(SECTOR(1), 2) || creature->Mood != MoodType::Attack)) { joint2 = AIGuard(creature); @@ -179,13 +179,12 @@ namespace TEN::Entities::TR5 else { if (creature->Mood == MoodType::Bored || - item->AIBits & FOLLOW && - (creature->ReachedGoal || - distance > pow(SECTOR(2), 2))) + (item->AIBits & FOLLOW && + (creature->ReachedGoal || distance > pow(SECTOR(2), 2)))) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; - else if (!(GetRandomControl() & 0x3F)) + else if (TestProbability(0.015f)) item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -194,7 +193,7 @@ namespace TEN::Entities::TR5 if (Lara.TargetEntity == item && unknown && distance < pow(SECTOR(1.5f), 2) && TestProbability(0.5f) && - (Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun || !(GetRandomControl() & 0xF)) && + (Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun || TestProbability(0.06f)) && item->MeshBits == -1) { item->Animation.TargetState = GLADIATOR_STATE_GUARD_START; @@ -242,7 +241,7 @@ namespace TEN::Entities::TR5 else if (!AI.ahead || AI.distance > pow(SECTOR(1.5f), 2)) item->Animation.TargetState = GLADIATOR_STATE_RUN_FORWARD; } - else if (!(GetRandomControl() & 0x3F)) + else if (TestProbability(0.015f)) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -308,8 +307,7 @@ namespace TEN::Entities::TR5 break; } } - else if (Lara.TargetEntity != item || - !(GetRandomControl() & 0x7F)) + else if (Lara.TargetEntity != item || TestProbability(0.008f)) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -343,7 +341,7 @@ namespace TEN::Entities::TR5 { auto* room = &g_Level.Rooms[item->RoomNumber]; - auto pos = Vector3Int(); + auto pos = Vector3Int::Zero; GetJointAbsPosition(item, &pos, 16); auto* floor = GetSector(room, pos.x - room->x, pos.z - room->z); diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp index 33f3b89f9..aa39aee12 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp @@ -1,19 +1,23 @@ #include "framework.h" -#include "tr5_guard.h" -#include "Game/items.h" +#include "Objects/TR5/Entity/tr5_guard.h" + +#include "Game/animation.h" #include "Game/collision/collide_room.h" #include "Game/control/box.h" -#include "Game/people.h" +#include "Game/control/los.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" -#include "Game/control/los.h" -#include "Specific/setup.h" -#include "Game/animation.h" -#include "Specific/level.h" +#include "Game/itemdata/creature_info.h" +#include "Game/items.h" #include "Game/Lara/lara.h" #include "Game/misc.h" +#include "Game/people.h" #include "Sound/sound.h" -#include "Game/itemdata/creature_info.h" +#include "Specific/level.h" +#include "Specific/prng.h" +#include "Specific/setup.h" + +using namespace TEN::Math::Random; namespace TEN::Entities::TR5 { @@ -354,7 +358,7 @@ namespace TEN::Entities::TR5 if (item->ObjectNumber == ID_SWAT_PLUS) { item->ItemFlags[0]++; - if (item->ItemFlags[0] > 60 && !(GetRandomControl() & 0xF)) + if (item->ItemFlags[0] > 60 && TestProbability(0.06f)) { SoundEffect(SFX_TR5_BIO_BREATHE_OUT, &item->Pose); item->ItemFlags[0] = 0; @@ -839,7 +843,7 @@ namespace TEN::Entities::TR5 case GUARD_STATE_USE_COMPUTER: if ((item->ObjectNumber != ID_SCIENTIST || item != Lara.TargetEntity) && - (GetRandomControl() & 0x7F || item->TriggerFlags >= 10 || item->TriggerFlags == 9)) + (TestProbability(0.992f) || item->TriggerFlags >= 10 || item->TriggerFlags == 9)) { if (item->AIBits & GUARD) { @@ -859,7 +863,7 @@ namespace TEN::Entities::TR5 break; case GUARD_STATE_SURRENDER: - if (item != Lara.TargetEntity && !(GetRandomControl() & 0x3F)) + if (item != Lara.TargetEntity && TestProbability(0.015f)) { if (item->TriggerFlags == 7 || item->TriggerFlags == 9) item->Animation.RequiredState = GUARD_STATE_USE_COMPUTER; @@ -1044,11 +1048,11 @@ namespace TEN::Entities::TR5 creature->Flags = 0; if (!TargetVisible(item, &AI) || item->HitStatus && - GetRandomControl() & 1) + TestProbability(0.5f)) { item->Animation.TargetState = SNIPER_STATE_COVER; } - else if (!(GetRandomControl() & 0x1F)) + else if (TestProbability(0.03f)) item->Animation.TargetState = SNIPER_STATE_FIRE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp index e04af88b4..94230274b 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp @@ -1,18 +1,21 @@ #include "framework.h" -#include "tr5_hydra.h" +#include "Objects/TR5/Entity/tr5_hydra.h" -#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Game/animation.h" #include "Game/collision/collide_room.h" #include "Game/control/box.h" #include "Game/effects/debris.h" #include "Game/effects/effects.h" -#include "Specific/setup.h" -#include "Game/animation.h" -#include "Specific/level.h" -#include "Game/Lara/lara.h" +#include "Game/itemdata/creature_info.h" +#include "Game/items.h" #include "Game/misc.h" #include "Sound/sound.h" -#include "Game/itemdata/creature_info.h" +#include "Specific/level.h" +#include "Specific/prng.h" +#include "Specific/setup.h" + +using namespace TEN::Math::Random; namespace TEN::Entities::TR5 { @@ -103,7 +106,7 @@ namespace TEN::Entities::TR5 spark->flags = SP_EXPDEF | SP_ROTATE | SP_DEF | SP_SCALE; spark->rotAng = GetRandomControl() & 0xFFF; - if (GetRandomControl() & 1) + if (TestProbability(0.5f)) spark->rotAdd = -32 - (GetRandomControl() & 0x1F); else spark->rotAdd = (GetRandomControl() & 0x1F) + 32; @@ -227,11 +230,11 @@ namespace TEN::Entities::TR5 else if (item->TriggerFlags == 2) tilt = ANGLE(2.8f); - if (AI.distance >= pow(CLICK(7), 2) && GetRandomControl() & 0x1F) + if (AI.distance >= pow(CLICK(7), 2) && TestProbability(0.97f)) { - if (AI.distance >= pow(SECTOR(2), 2) && GetRandomControl() & 0x1F) + if (AI.distance >= pow(SECTOR(2), 2) && TestProbability(0.97f)) { - if (!(GetRandomControl() & 0xF)) + if (TestProbability(0.06f)) item->Animation.TargetState = HYDRA_STATE_AIM; } else @@ -290,7 +293,8 @@ namespace TEN::Entities::TR5 if (Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun) damage *= 3; - if ((GetRandomControl() & 0xF) < damage && AI.distance < SQUARE(10240) && damage > 0) + if ((GetRandomControl() & 0xF) < damage && + AI.distance < SQUARE(SECTOR(10)) && damage > 0) { item->Animation.TargetState = 4; DoDamage(item, damage); diff --git a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp index 1cea7a9f8..149d45168 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp @@ -1,5 +1,6 @@ #include "framework.h" #include "tr5_lagoon_witch.h" + #include "Game/items.h" #include "Game/control/box.h" #include "Game/effects/effects.h" diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index 5b5f28a08..b45c443e6 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -1,41 +1,45 @@ #include "framework.h" -#include "tr5_larson.h" -#include "Game/items.h" -#include "Game/control/box.h" -#include "Game/effects/effects.h" -#include "Game/people.h" -#include "Game/Lara/lara.h" -#include "Specific/setup.h" -#include "Specific/level.h" -#include "Game/itemdata/creature_info.h" -#include "Game/control/control.h" +#include "Objects/TR5/Entity/tr5_larson.h" + #include "Game/animation.h" +#include "Game/control/box.h" +#include "Game/control/control.h" +#include "Game/effects/effects.h" +#include "Game/itemdata/creature_info.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" +#include "Game/misc.h" +#include "Game/people.h" +#include "Specific/level.h" +#include "Specific/prng.h" +#include "Specific/setup.h" + +using namespace TEN::Math::Random; namespace TEN::Entities::TR5 { -#define STATE_TR5_LARSON_STOP 1 -#define STATE_TR5_LARSON_WALK 2 -#define STATE_TR5_LARSON_RUN 3 -#define STATE_TR5_LARSON_AIM 4 -#define STATE_TR5_LARSON_DIE 5 -#define STATE_TR5_LARSON_IDLE 6 -#define STATE_TR5_LARSON_ATTACK 7 + #define STATE_TR5_LARSON_STOP 1 + #define STATE_TR5_LARSON_WALK 2 + #define STATE_TR5_LARSON_RUN 3 + #define STATE_TR5_LARSON_AIM 4 + #define STATE_TR5_LARSON_DIE 5 + #define STATE_TR5_LARSON_IDLE 6 + #define STATE_TR5_LARSON_ATTACK 7 -#define ANIMATION_TR5_PIERRE_DIE 12 -#define ANIMATION_TR5_LARSON_DIE 15 + #define ANIMATION_TR5_PIERRE_DIE 12 + #define ANIMATION_TR5_LARSON_DIE 15 -#define TR5_LARSON_MIN_HP 40 + #define TR5_LARSON_MIN_HP 40 - const auto LarsonGun = BiteInfo(Vector3(-55, 200, 5), 14); - const auto PierreGun1 = BiteInfo(Vector3(60, 200, 0), 11); - const auto PierreGun2 = BiteInfo(Vector3(-57, 200, 0), 14); + const auto LarsonGun = BiteInfo(Vector3(-55.0f, 200.0f, 5.0f), 14); + const auto PierreGun1 = BiteInfo(Vector3(60.0f, 200.0f, 0.0f), 11); + const auto PierreGun2 = BiteInfo(Vector3(-57.0f, 200.0f, 0.0f), 14); void InitialiseLarson(short itemNum) { - ItemInfo* item = &g_Level.Items[itemNum]; + auto* item = &g_Level.Items[itemNum]; ClearItem(itemNum); - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.TargetState = STATE_TR5_LARSON_STOP; @@ -47,22 +51,14 @@ namespace TEN::Entities::TR5 item->ItemFlags[3] = item->TriggerFlags; short rotY = item->Pose.Orientation.y; - if (rotY > ANGLE(22.5f) && rotY < 28672) - { + if (rotY > ANGLE(22.5f) && rotY < ANGLE(157.5f)) item->Pose.Position.x += STEPUP_HEIGHT; - } - else if (rotY < -ANGLE(22.5f) && rotY > -28672) - { + else if (rotY < ANGLE(-22.5f) && rotY > ANGLE(-157.5f)) item->Pose.Position.x -= STEPUP_HEIGHT; - } - else if (rotY < -20480 || rotY > 20480) - { + else if (rotY < ANGLE(-112.5f) || rotY > ANGLE(112.5f)) item->Pose.Position.z -= STEPUP_HEIGHT; - } - else if (rotY > -8192 || rotY < 8192) - { + else if (rotY > ANGLE(-45.0f) || rotY < ANGLE(45.0f)) item->Pose.Position.z += STEPUP_HEIGHT; - } } void LarsonControl(short itemNumber) @@ -77,7 +73,7 @@ namespace TEN::Entities::TR5 short joint2 = 0; auto* item = &g_Level.Items[itemNumber]; - CreatureInfo* creature = (CreatureInfo*)item->Data; + auto* creature = GetCreatureInfo(item); // In Streets of Rome when Larson HP are below 40 he runs way /*if (item->HitPoints <= TR5_LARSON_MIN_HP && !(item->flags & IFLAG_INVISIBLE)) @@ -113,6 +109,7 @@ namespace TEN::Entities::TR5 item->Collidable = false; item->Status = ITEM_ACTIVE; } + item->TriggerFlags = 0; } @@ -123,11 +120,11 @@ namespace TEN::Entities::TR5 else creature->Enemy = LaraItem; - AI_INFO info; - CreatureAIInfo(item, &info); + AI_INFO AI; + CreatureAIInfo(item, &AI); - if (info.ahead) - joint2 = info.angle; + if (AI.ahead) + joint2 = AI.angle; // FIXME: this should make Larson running away, but it's broken /*if (creature->flags) @@ -140,13 +137,13 @@ namespace TEN::Entities::TR5 creature->flags = 0; }*/ - GetCreatureMood(item, &info, true); - CreatureMood(item, &info, true); + GetCreatureMood(item, &AI, true); + CreatureMood(item, &AI, true); - if (info.distance < SQUARE(2048) - && LaraItem->Animation.Velocity.z > 20 - || item->HitStatus - || TargetVisible(item, &info) != 0) + if (AI.distance < SQUARE(SECTOR(2)) && + LaraItem->Animation.Velocity > 20 || + item->HitStatus || + TargetVisible(item, &AI) != 0) { item->Status &= ~ITEM_ACTIVE; creature->Alerted = true; @@ -157,40 +154,34 @@ namespace TEN::Entities::TR5 switch (item->Animation.ActiveState) { case STATE_TR5_LARSON_STOP: - joint0 = info.angle / 2; - joint2 = info.angle / 2; - if (info.ahead) - joint1 = info.xAngle; + joint0 = AI.angle / 2; + joint2 = AI.angle / 2; + + if (AI.ahead) + joint1 = AI.xAngle; if (item->Animation.RequiredState) - { item->Animation.TargetState = item->Animation.RequiredState; - } else if (item->AIBits & AMBUSH) - { item->Animation.TargetState = STATE_TR5_LARSON_RUN; - } - else if (Targetable(item, &info)) - { + else if (Targetable(item, &AI)) item->Animation.TargetState = STATE_TR5_LARSON_AIM; - } else { if (item->AIBits & GUARD || CurrentLevel == 2 || item->ItemFlags[3]) { - creature->MaxTurn = 0; item->Animation.TargetState = STATE_TR5_LARSON_STOP; - if (abs(info.angle) >= ANGLE(2)) + creature->MaxTurn = 0; + + if (abs(AI.angle) >= ANGLE(2.0f)) { - if (info.angle > 0) - item->Pose.Orientation.y += ANGLE(2); + if (AI.angle > 0) + item->Pose.Orientation.y += ANGLE(2.0f); else - item->Pose.Orientation.y -= ANGLE(2); + item->Pose.Orientation.y -= ANGLE(2.0f); } else - { - item->Pose.Orientation.y += info.angle; - } + item->Pose.Orientation.y += AI.angle; } else { @@ -202,69 +193,67 @@ namespace TEN::Entities::TR5 item->Animation.TargetState = STATE_TR5_LARSON_WALK; } else - { - item->Animation.TargetState = GetRandomControl() >= 96 ? 2 : 6; - } + item->Animation.TargetState = TestProbability(0.997f) ? 2 : 6; } } + break; case STATE_TR5_LARSON_WALK: - if (info.ahead) - joint2 = info.angle; + creature->MaxTurn = ANGLE(7.0f); - creature->MaxTurn = ANGLE(7); - if (creature->Mood == MoodType::Bored && GetRandomControl() < 96) + if (AI.ahead) + joint2 = AI.angle; + + if (creature->Mood == MoodType::Bored && TestProbability(0.003f)) { - item->Animation.RequiredState = STATE_TR5_LARSON_IDLE; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_IDLE; break; } if (creature->Mood == MoodType::Escape || item->AIBits & AMBUSH) { - item->Animation.RequiredState = STATE_TR5_LARSON_RUN; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_RUN; } - else if (Targetable(item, &info)) + else if (Targetable(item, &AI)) { + item->Animation.TargetState = STATE_TR5_LARSON_STOP; item->Animation.RequiredState = STATE_TR5_LARSON_AIM; - item->Animation.TargetState = STATE_TR5_LARSON_STOP; } - else if (!info.ahead || info.distance > SQUARE(3072)) + else if (!AI.ahead || AI.distance > SQUARE(SECTOR(3))) { - item->Animation.RequiredState = STATE_TR5_LARSON_RUN; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_RUN; } + break; case STATE_TR5_LARSON_RUN: - if (info.ahead) - joint2 = info.angle; - creature->MaxTurn = ANGLE(11); tilt = angle / 2; + creature->MaxTurn = ANGLE(11.0f); + + if (AI.ahead) + joint2 = AI.angle; if (creature->ReachedGoal) - { item->Animation.TargetState = STATE_TR5_LARSON_STOP; - } else if (item->AIBits & AMBUSH) - { item->Animation.TargetState = STATE_TR5_LARSON_RUN; - } - else if (creature->Mood != MoodType::Bored || GetRandomControl() >= 96) + else if (creature->Mood != MoodType::Bored || TestProbability(0.997f)) { - if (Targetable(item, &info)) + if (Targetable(item, &AI)) { - item->Animation.RequiredState = STATE_TR5_LARSON_AIM; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_AIM; } - else if (info.ahead) + else if (AI.ahead) { - if (info.distance <= SQUARE(3072)) + if (AI.distance <= SQUARE(SECTOR(3))) { - item->Animation.RequiredState = STATE_TR5_LARSON_WALK; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_WALK; } } } @@ -273,104 +262,108 @@ namespace TEN::Entities::TR5 item->Animation.RequiredState = STATE_TR5_LARSON_IDLE; item->Animation.TargetState = STATE_TR5_LARSON_STOP; } + break; case STATE_TR5_LARSON_AIM: - joint0 = info.angle / 2; - joint2 = info.angle / 2; - if (info.ahead) - joint1 = info.xAngle; + joint0 = AI.angle / 2; + joint2 = AI.angle / 2; creature->MaxTurn = 0; - if (abs(info.angle) >= ANGLE(2)) + + if (AI.ahead) + joint1 = AI.xAngle; + + if (abs(AI.angle) >= ANGLE(2.0f)) { - if (info.angle > 0) - item->Pose.Orientation.y += ANGLE(2); + if (AI.angle > 0) + item->Pose.Orientation.y += ANGLE(2.0f); else - item->Pose.Orientation.y -= ANGLE(2); + item->Pose.Orientation.y -= ANGLE(2.0f); } else - { - item->Pose.Orientation.y += info.angle; - } + item->Pose.Orientation.y += AI.angle; - if (Targetable(item, &info)) + if (Targetable(item, &AI)) item->Animation.TargetState = STATE_TR5_LARSON_ATTACK; else item->Animation.TargetState = STATE_TR5_LARSON_STOP; + break; case STATE_TR5_LARSON_IDLE: - joint0 = info.angle / 2; - joint2 = info.angle / 2; - if (info.ahead) - joint1 = info.xAngle; + joint0 = AI.angle / 2; + joint2 = AI.angle / 2; + + if (AI.ahead) + joint1 = AI.xAngle; if (creature->Mood != MoodType::Bored) - { item->Animation.TargetState = STATE_TR5_LARSON_STOP; - } else { - if (GetRandomControl() <= 96) + if (TestProbability(0.003f)) { - item->Animation.RequiredState = STATE_TR5_LARSON_WALK; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_WALK; } } + break; case STATE_TR5_LARSON_ATTACK: - joint0 = info.angle / 2; - joint2 = info.angle / 2; - if (info.ahead) - joint1 = info.xAngle; + joint0 = AI.angle / 2; + joint2 = AI.angle / 2; creature->MaxTurn = 0; - if (abs(info.angle) >= ANGLE(2)) + + if (AI.ahead) + joint1 = AI.xAngle; + + if (abs(AI.angle) >= ANGLE(2.0f)) { - if (info.angle > 0) - item->Pose.Orientation.y += ANGLE(2); + if (AI.angle > 0) + item->Pose.Orientation.y += ANGLE(2.0f); else - item->Pose.Orientation.y -= ANGLE(2); + item->Pose.Orientation.y -= ANGLE(2.0f); } else - { - item->Pose.Orientation.y += info.angle; - } + item->Pose.Orientation.y += AI.angle; + if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase) { if (item->ObjectNumber == ID_PIERRE) { - ShotLara(item, &info, PierreGun1, joint0, 20); - ShotLara(item, &info, PierreGun2, joint0, 20); + ShotLara(item, &AI, PierreGun1, joint0, 20); + ShotLara(item, &AI, PierreGun2, joint0, 20); } else - { - ShotLara(item, &info, LarsonGun, joint0, 20); - } + ShotLara(item, &AI, LarsonGun, joint0, 20); + creature->FiredWeapon = 2; } - if (creature->Mood == MoodType::Escape && GetRandomControl() > 0x2000) + + if (creature->Mood == MoodType::Escape && TestProbability(0.75f)) item->Animation.RequiredState = STATE_TR5_LARSON_STOP; + break; default: break; - } } else if (item->Animation.ActiveState == STATE_TR5_LARSON_DIE) { // When Larson dies, it activates trigger at start position - if (item->ObjectNumber == ID_LARSON - && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd) + if (item->ObjectNumber == ID_LARSON && + item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd) { short roomNumber = item->ItemFlags[2] & 0xFF; short floorHeight = item->ItemFlags[2] & 0xFF00; - ROOM_INFO* r = &g_Level.Rooms[roomNumber]; - int x = r->x + (creature->Tosspad / 256 & 0xFF) * SECTOR(1) + 512; - int y = r->minfloor + floorHeight; - int z = r->z + (creature->Tosspad & 0xFF) * SECTOR(1) + 512; + auto* room = &g_Level.Rooms[roomNumber]; + + int x = room->x + (creature->Tosspad / 256 & 0xFF) * SECTOR(1) + 512; + int y = room->minfloor + floorHeight; + int z = room->z + (creature->Tosspad & 0xFF) * SECTOR(1) + 512; TestTriggers(x, y, z, roomNumber, true); @@ -379,13 +372,14 @@ namespace TEN::Entities::TR5 } else { - // Die + // Death. if (item->ObjectNumber == ID_PIERRE) item->Animation.AnimNumber = Objects[ID_PIERRE].animIndex + ANIMATION_TR5_PIERRE_DIE; else item->Animation.AnimNumber = Objects[ID_LARSON].animIndex + ANIMATION_TR5_LARSON_DIE; - item->Animation.ActiveState = STATE_TR5_LARSON_DIE; + item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + item->Animation.ActiveState = STATE_TR5_LARSON_DIE; } CreatureTilt(item, tilt); From 30bd87164b633569ef1e502951b0e756bf4b0ed3 Mon Sep 17 00:00:00 2001 From: Sezz Date: Wed, 17 Aug 2022 16:43:07 +1000 Subject: [PATCH 006/106] Convert probabilities --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 8 ++++---- TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 18 ++++++++++-------- TombEngine/Objects/TR1/Entity/tr1_centaur.cpp | 14 ++++++++------ .../Objects/TR1/Entity/tr1_giant_mutant.cpp | 13 ++++++++----- TombEngine/Objects/TR1/Entity/tr1_natla.cpp | 8 ++++++-- .../Objects/TR1/Entity/tr1_winged_mutant.cpp | 12 +++++++----- TombEngine/Objects/TR1/Entity/tr1_wolf.cpp | 14 ++++++++------ 7 files changed, 51 insertions(+), 36 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 274645477..b4a66dcda 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -22,10 +22,10 @@ namespace TEN::Entities::TR1 constexpr auto APE_ATTACK_RANGE = SQUARE(SECTOR(0.42f)); constexpr auto APE_PANIC_RANGE = SQUARE(SECTOR(2)); - constexpr auto APE_JUMP_CHANCE = 0xA0; - constexpr auto APE_POUND_CHEST_CHANCE = APE_JUMP_CHANCE + 0xA0; - constexpr auto APE_POUND_GROUND_CHANCE = APE_POUND_CHEST_CHANCE + 0xA0; - constexpr auto APE_RUN_LEFT_CHANCE = APE_POUND_GROUND_CHANCE + 0xA0; + constexpr auto APE_JUMP_CHANCE = 0.005f; + constexpr auto APE_POUND_CHEST_CHANCE = 0.01f; + constexpr auto APE_POUND_GROUND_CHANCE = 0.015f; + constexpr auto APE_RUN_LEFT_CHANCE = 0.02f; constexpr auto SHIFT = 75; diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp index 0038f9e06..49cf01acb 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp @@ -9,8 +9,10 @@ #include "Game/Lara/lara.h" #include "Game/misc.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR1 @@ -24,10 +26,10 @@ namespace TEN::Entities::TR1 constexpr auto BEAR_REAR_RANGE = SECTOR(2); constexpr auto BEAR_REAR_SWIPE_ATTACK_RANGE = SECTOR(0.6f); constexpr auto BEAR_EAT_RANGE = CLICK(3); - - constexpr auto BEAR_ROAR_CHANCE = 0x50; - constexpr auto BEAR_REAR_CHANCE = 0x300; - constexpr auto BEAR_DROP_CHANCE = 0x600; + + constexpr auto BEAR_ROAR_CHANCE = 0.0025f; + constexpr auto BEAR_REAR_CHANCE = 0.025f; + constexpr auto BEAR_DROP_CHANCE = 0.045f; #define BEAR_WALK_TURN_RATE_MAX ANGLE(2.0f) #define BEAR_RUN_TURN_RATE_MAX ANGLE(5.0f) @@ -174,7 +176,7 @@ namespace TEN::Entities::TR1 if (creature->Mood == MoodType::Escape) item->Animation.RequiredState = BEAR_STATE_STROLL; } - else if (GetRandomControl() < BEAR_ROAR_CHANCE) + else if (TestProbability(BEAR_ROAR_CHANCE)) { item->Animation.RequiredState = BEAR_STATE_ROAR; item->Animation.TargetState = BEAR_STATE_IDLE; @@ -195,7 +197,7 @@ namespace TEN::Entities::TR1 else if (AI.ahead && !item->Animation.RequiredState) { if (AI.distance < pow(BEAR_REAR_RANGE, 2) && - GetRandomControl() < BEAR_REAR_CHANCE && + TestProbability(BEAR_REAR_CHANCE) && !creature->Flags) { item->Animation.RequiredState = BEAR_STATE_REAR; @@ -237,12 +239,12 @@ namespace TEN::Entities::TR1 item->Animation.TargetState = BEAR_STATE_REAR; item->Animation.RequiredState = BEAR_STATE_STROLL; } - else if (creature->Mood == MoodType::Bored || GetRandomControl() < BEAR_ROAR_CHANCE) + else if (creature->Mood == MoodType::Bored || TestProbability(BEAR_ROAR_CHANCE)) { item->Animation.RequiredState = BEAR_STATE_ROAR; item->Animation.TargetState = BEAR_STATE_REAR; } - else if (AI.distance > pow(BEAR_REAR_RANGE, 2) || GetRandomControl() < BEAR_DROP_CHANCE) + else if (AI.distance > pow(BEAR_REAR_RANGE, 2) || TestProbability(BEAR_DROP_CHANCE)) { item->Animation.RequiredState = BEAR_STATE_IDLE; item->Animation.TargetState = BEAR_STATE_REAR; diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp index 27f76ce0a..3f9029d35 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp @@ -15,15 +15,17 @@ #include "Game/people.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR1 { constexpr auto CENTAUR_REAR_DAMAGE = 200; constexpr auto CENTAUR_REAR_RANGE = SECTOR(1.5f); - constexpr auto CENTAUR_REAR_CHANCE = 0x60; + constexpr auto CENTAUR_REAR_CHANCE = 0.003f; constexpr auto CENTAUR_BOMB_VELOCITY = 20; #define CENTAUR_TURN_RATE_MAX ANGLE(4.0f) @@ -98,18 +100,18 @@ namespace TEN::Entities::TR1 case CENTAUR_STATE_RUN_FORWARD: if (AI.bite && AI.distance < pow(CENTAUR_REAR_RANGE, 2)) { - item->Animation.RequiredState = CENTAUR_STATE_WARNING; item->Animation.TargetState = CENTAUR_STATE_IDLE; + item->Animation.RequiredState = CENTAUR_STATE_WARNING; } else if (Targetable(item, &AI)) { + item->Animation.TargetState = CENTAUR_STATE_IDLE; item->Animation.RequiredState = CENTAUR_STATE_AIM; - item->Animation.TargetState = CENTAUR_STATE_IDLE; } - else if (GetRandomControl() < CENTAUR_REAR_CHANCE) + else if (TestProbability(CENTAUR_REAR_CHANCE)) { - item->Animation.RequiredState = CENTAUR_STATE_WARNING; item->Animation.TargetState = CENTAUR_STATE_IDLE; + item->Animation.RequiredState = CENTAUR_STATE_WARNING; } break; @@ -137,8 +139,8 @@ namespace TEN::Entities::TR1 if (!item->Animation.RequiredState && item->TestBits(JointBitType::Touch, CentaurAttackJoints)) { - CreatureEffect(item, CentaurRearBite, DoBloodSplat); DoDamage(creature->Enemy, CENTAUR_REAR_DAMAGE); + CreatureEffect(item, CentaurRearBite, DoBloodSplat); item->Animation.RequiredState = CENTAUR_STATE_IDLE; } diff --git a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp index 7061059ec..46709db1e 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp @@ -12,8 +12,10 @@ #include "Game/misc.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR1 @@ -24,16 +26,17 @@ namespace TEN::Entities::TR1 constexpr auto MUTANT_ATTACK_RANGE = SQUARE(SECTOR(2.5f)); constexpr auto MUTANT_CLOSE_RANGE = SQUARE(SECTOR(2.2f)); - constexpr auto MUTANT_ATTACK_1_CHANCE = 0x2AF8; - constexpr auto MUTANT_ATTACK_2_CHANCE = 0x55F0; + // TODO: Unused. + constexpr auto MUTANT_ATTACK_1_CHANCE = 0.33f; + constexpr auto MUTANT_ATTACK_2_CHANCE = 0.67f; #define MUTANT_NEED_TURN ANGLE(45.0f) #define MUTANT_TURN ANGLE(3.0f) #define LARA_GIANT_MUTANT_DEATH 6 // TODO: Not 13? Check this. - const vector MutantAttackJoints = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; - const vector MutantAttackLeftJoints = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; + const vector MutantAttackJoints = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; + const vector MutantAttackLeftJoint = { 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14 }; const vector MutantAttackRightJoints = { 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25 }; enum GiantMutantState @@ -122,7 +125,7 @@ namespace TEN::Entities::TR1 else item->Animation.TargetState = MUTANT_STATE_FORWARD; } - else if (GetRandomControl() < 0x4000) + else if (TestProbability(0.5f)) item->Animation.TargetState = MUTANT_STATE_ATTACK_1; else item->Animation.TargetState = MUTANT_STATE_ATTACK_2; diff --git a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp index 503b169d5..f18c25f1e 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp @@ -10,8 +10,11 @@ #include "Game/people.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/trmath.h" +using namespace TEN::Math::Random; + namespace TEN::Entities::TR1 { // TODO: Organise. @@ -20,9 +23,10 @@ namespace TEN::Entities::TR1 constexpr auto NATLA_DEATH_TIME = (FPS * 16); // 16 seconds. constexpr auto NATLA_FLYMODE = 0x8000; constexpr auto NATLA_TIMER = 0x7FFF; - constexpr auto NATLA_LAND_CHANCE = 0x100; constexpr auto NATLA_GUN_VELOCITY = 400; + constexpr auto NATLA_LAND_CHANCE = 0.008f; + #define NATLA_TURN_NEAR_DEATH_SPEED ANGLE(6.0f) #define NATLA_TURN_SPEED ANGLE(5.0f) #define NATLA_FLY_ANGLE_SPEED ANGLE(5.0f) @@ -183,7 +187,7 @@ namespace TEN::Entities::TR1 if (item->Animation.ActiveState == NATLA_STATE_FLY && (creature->Flags & NATLA_FLYMODE)) { - if (creature->Flags & NATLA_FLYMODE && shoot && GetRandomControl() < NATLA_LAND_CHANCE) + if (creature->Flags & NATLA_FLYMODE && shoot && TestProbability(NATLA_LAND_CHANCE)) creature->Flags -= NATLA_FLYMODE; if (!(creature->Flags & NATLA_FLYMODE)) diff --git a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp index 1e84f91f0..4684f4326 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp @@ -13,8 +13,10 @@ #include "Game/people.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/trmath.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR1 @@ -29,8 +31,8 @@ namespace TEN::Entities::TR1 constexpr auto WINGED_MUTANT_IDLE_JUMP_ATTACK_RANGE = SQUARE(SECTOR(2.5f)); constexpr auto WINGED_MUTANT_ATTACK_RANGE = SQUARE(SECTOR(3.75f)); - constexpr auto WINGED_MUTANT_POSE_CHANCE = 85; - constexpr auto WINGED_MUTANT_UNPOSE_CHANCE = 200; + constexpr auto WINGED_MUTANT_POSE_CHANCE = 0.0025f; + constexpr auto WINGED_MUTANT_UNPOSE_CHANCE = 0.006f; constexpr auto WINGED_MUTANT_FLY_VELOCITY = CLICK(1) / 8; constexpr auto WINGED_MUTANT_SHARD_VELOCITY = 250; @@ -337,7 +339,7 @@ namespace TEN::Entities::TR1 if (AI.distance < WINGED_MUTANT_WALK_RANGE) { if (AI.zoneNumber == AI.enemyZone || - GetRandomControl() < WINGED_MUTANT_UNPOSE_CHANCE) + TestProbability(WINGED_MUTANT_UNPOSE_CHANCE)) { item->Animation.TargetState = WMUTANT_STATE_WALK_FORWARD; } @@ -345,7 +347,7 @@ namespace TEN::Entities::TR1 else item->Animation.TargetState = WMUTANT_STATE_IDLE; } - else if (creature->Mood == MoodType::Bored && GetRandomControl() < WINGED_MUTANT_UNPOSE_CHANCE) + else if (creature->Mood == MoodType::Bored && TestProbability(WINGED_MUTANT_UNPOSE_CHANCE)) item->Animation.TargetState = WMUTANT_STATE_WALK_FORWARD; else if (creature->Mood == MoodType::Attack || creature->Mood == MoodType::Escape) @@ -363,7 +365,7 @@ namespace TEN::Entities::TR1 else if (creature->Mood == MoodType::Bored || (creature->Mood == MoodType::Stalk && AI.zoneNumber != AI.enemyZone)) { - if (GetRandomControl() < WINGED_MUTANT_POSE_CHANCE) + if (TestProbability(WINGED_MUTANT_POSE_CHANCE)) item->Animation.TargetState = WMUTANT_STATE_POSE; } else if (creature->Mood == MoodType::Stalk && diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp index 20ab213b8..a8a293eb8 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp @@ -9,8 +9,10 @@ #include "Game/Lara/lara.h" #include "Game/misc.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; using std::vector; namespace TEN::Entities::TR1 @@ -21,9 +23,9 @@ namespace TEN::Entities::TR1 constexpr auto WOLF_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); constexpr auto WOLF_STALK_RANGE = SQUARE(SECTOR(2)); - constexpr auto WOLF_WAKE_CHANCE = 0x20; - constexpr auto WOLF_SLEEP_CHANCE = 0x20; - constexpr auto WOLF_HOWL_CHANCE = 0x180; + constexpr auto WOLF_WAKE_CHANCE = 0.00095f; + constexpr auto WOLF_SLEEP_CHANCE = 0.00095f; + constexpr auto WOLF_HOWL_CHANCE = 0.012f; constexpr auto WOLF_SLEEP_FRAME = 96; @@ -110,7 +112,7 @@ namespace TEN::Entities::TR1 item->Animation.RequiredState = WOLF_STATE_CROUCH; item->Animation.TargetState = WOLF_STATE_IDLE; } - else if (GetRandomControl() < WOLF_WAKE_CHANCE) + else if (TestProbability(WOLF_WAKE_CHANCE)) { item->Animation.RequiredState = WOLF_STATE_WALK; item->Animation.TargetState = WOLF_STATE_IDLE; @@ -133,7 +135,7 @@ namespace TEN::Entities::TR1 item->Animation.TargetState = WOLF_STATE_STALK; item->Animation.RequiredState = WOLF_STATE_NONE; } - else if (GetRandomControl() < WOLF_SLEEP_CHANCE) + else if (TestProbability(WOLF_SLEEP_CHANCE)) { item->Animation.RequiredState = WOLF_STATE_SLEEP; item->Animation.TargetState = WOLF_STATE_IDLE; @@ -174,7 +176,7 @@ namespace TEN::Entities::TR1 item->Animation.TargetState = WOLF_STATE_RUN; } } - else if (GetRandomControl() < WOLF_HOWL_CHANCE) + else if (TestProbability(WOLF_HOWL_CHANCE)) { item->Animation.RequiredState = WOLF_STATE_HOWL; item->Animation.TargetState = WOLF_STATE_CROUCH; From 37a45e6d6007ba2525355626c3fbcbfe66ee4a17 Mon Sep 17 00:00:00 2001 From: Sezz Date: Wed, 17 Aug 2022 17:19:33 +1000 Subject: [PATCH 007/106] Finish probability conversion for TR1 ape --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 28 ++++++++++++----------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index b4a66dcda..23ddb3759 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -22,10 +22,14 @@ namespace TEN::Entities::TR1 constexpr auto APE_ATTACK_RANGE = SQUARE(SECTOR(0.42f)); constexpr auto APE_PANIC_RANGE = SQUARE(SECTOR(2)); - constexpr auto APE_JUMP_CHANCE = 0.005f; - constexpr auto APE_POUND_CHEST_CHANCE = 0.01f; - constexpr auto APE_POUND_GROUND_CHANCE = 0.015f; - constexpr auto APE_RUN_LEFT_CHANCE = 0.02f; + constexpr auto APE_IDLE_JUMP_CHANCE = 0.16f; + constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 0.32f; + constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 0.47f; + constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 0.63f; + constexpr auto APE_RUN_JUMP_CHANCE = 0.005f; + constexpr auto APE_RUN_POUND_CHEST_CHANCE = 0.01f; + constexpr auto APE_RUN_POUND_GROUND_CHANCE = 0.015f; + constexpr auto APE_RUN_RUN_LEFT_CHANCE = 0.02f; constexpr auto SHIFT = 75; @@ -207,14 +211,13 @@ namespace TEN::Entities::TR1 else if (!(creatureInfo->Flags & APE_FLAG_ATTACK) && AI.zoneNumber == AI.enemyZone && AI.ahead) { - random = (short)(GetRandomControl() / 32); - if (random < APE_JUMP_CHANCE) + if (TestProbability(APE_IDLE_JUMP_CHANCE)) item->Animation.TargetState = APE_STATE_JUMP; - else if (random < APE_POUND_CHEST_CHANCE) + else if (TestProbability(APE_IDLE_POUND_CHEST_CHANCE)) item->Animation.TargetState = APE_STATE_POUND_CHEST; - else if (random < APE_POUND_GROUND_CHANCE) + else if (TestProbability(APE_IDLE_POUND_GROUND_CHANCE)) item->Animation.TargetState = APE_STATE_POUND_GROUND; - else if (random < APE_RUN_LEFT_CHANCE) + else if (TestProbability(APE_IDLE_RUN_LEFT_CHANCE)) { item->Animation.TargetState = APE_STATE_RUN_LEFT; creatureInfo->MaxTurn = 0; @@ -246,18 +249,17 @@ namespace TEN::Entities::TR1 } else if (creatureInfo->Mood != MoodType::Escape) { - random = (short)GetRandomControl(); - if (random < APE_JUMP_CHANCE) + if (TestProbability(APE_RUN_JUMP_CHANCE)) { item->Animation.RequiredState = APE_STATE_JUMP; item->Animation.TargetState = APE_STATE_IDLE; } - else if (random < APE_POUND_CHEST_CHANCE) + else if (TestProbability(APE_RUN_POUND_CHEST_CHANCE)) { item->Animation.RequiredState = APE_STATE_POUND_CHEST; item->Animation.TargetState = APE_STATE_IDLE; } - else if (random < APE_POUND_GROUND_CHANCE) + else if (TestProbability(APE_RUN_POUND_GROUND_CHANCE)) { item->Animation.RequiredState = APE_STATE_POUND_GROUND; item->Animation.TargetState = APE_STATE_IDLE; From 673b61bf74e9e957527db1b08d17ab1abe8a68ba Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 18 Aug 2022 21:04:11 +1000 Subject: [PATCH 008/106] Demagic tr3_monkey.cpp; cleanup --- TombEngine/Game/control/box.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 359 ++++++++++-------- TombEngine/Objects/TR3/Entity/tr3_shiva.cpp | 22 +- .../Objects/TR4/Entity/tr4_von_croy.cpp | 18 +- TombEngine/Objects/TR5/Entity/tr5_larson.cpp | 2 +- 5 files changed, 226 insertions(+), 177 deletions(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 19085c70d..f11437934 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -1170,7 +1170,7 @@ int CreatureVault(short itemNumber, short angle, int vault, int shift) vault = 0; else if (item->Floor > y + CHECK_CLICK(7)) vault = -4; - // FIXME: edit assets adding climb down animations for Von Croy and baddys? + // FIXME: edit assets adding climb down animations for Von Croy and baddies? else if (item->Floor > y + CHECK_CLICK(5) && item->ObjectNumber != ID_VON_CROY && item->ObjectNumber != ID_BADDY1 && diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index 806106f26..63816c709 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -18,18 +18,80 @@ using std::vector; namespace TEN::Entities::TR3 { + // TODO: Work out damage constants. + constexpr auto MONKEY_SWIPE_ATTACK_PLAYER_DAMAGE = 40; + constexpr auto MONKEY_SWIPE_ATTACK_CREATURE_DAMAGE = 20; + + // TODO: Range constants. + const auto MonkeyBite = BiteInfo(Vector3(10.0f, 10.0f, 11.0f), 13); const vector MonkeyAttackJoints = { 10, 13 }; + enum MonkeyState + { + // No states 0-1. + MONKEY_STATE_WALK_FORWARD = 2, + MONKEY_STATE_IDLE = 3, + MONKEY_STATE_RUN_FORWARD = 4, + MONKEY_STATE_BITE_ATTACK = 5, // Check. + MONKEY_STATE_SIT = 6, + MONKEY_STATE_SIT_EAT = 7, + MONKEY_STATE_SIT_SCRATCH = 8, + MONKEY_STATE_RUN_FORWARD_ROLL = 9, + MONKEY_STATE_POUND_GROUND = 10, + MONKEY_STATE_DEATH = 11, + MONKEY_STATE_SWIPE_ATTACK = 12, + MONKEY_STATE_JUMP_ATTACK = 13, + MONKEY_STATE_HIGH_JUMP_ATTACK = 14, + MONKEY_STATE_VAULT_UP_1_BLOCK = 15, + MONKEY_STATE_VAULT_UP_0_POINT_3_BLOCKS = 16, + MONKEY_STATE_VAULT_UP_0_POINT_2_BLOCKS = 17, + MONKEY_STATE_VAULT_DOWN_1_BLOCK = 18, + MONKEY_STATE_VAULT_DOWN_0_POINT_3_BLOCKS = 19, + MONKEY_STATE_VAULT_DOWN_0_POINT_2_BLOCKS = 20 + }; + + enum MonkeyAnim + { + MONKEY_ANIM_WALK_FORWARD = 0, + MONKEY_ANIM_WALK_FORWARD_TO_SIT = 1, + MONKEY_ANIM_SIT = 2, + MONKEY_ANIM_SIT_TO_WALK_FORWARD = 3, + MONKEY_ANIM_SIT_EAT = 4, + MONKEY_ANIM_SIT_SCRATCH = 5, + MONKEY_ANIM_RUN_FORWARD = 6, + MONKEY_ANIM_RUN_FORWARD_ROLL = 7, + MONKEY_ANIM_IDLE_POUND_GROUND = 8, + MONKEY_ANIM_IDLE = 9, + MONKEY_ANIM_IDLE_TO_RUN_FORWARD = 10, + MONKEY_ANIM_WALK_FORWARD_TO_RUN_FORWARD = 11, + MONKEY_ANIM_RUN_FORWARD_TO_IDLE = 12, + MONKEY_ANIM_SIT_TO_IDLE = 13, + MONKEY_ANIM_DEATH = 14, + MONKEY_ANIM_RUN_FORWARD_TO_WALK_FORWARD = 15, + MONKEY_ANIM_IDLE_TO_SIT = 16, + MONKEY_ANIM_VAULT_UP_1_BLOCK = 17, + MONKEY_ANIM_VAULT_UP_0_POINT_3_BLOCKS = 18, + MONKEY_ANIM_VAULT_UP_0_POINT_2_BLOCKS = 19, + MONKEY_ANIM_VAULT_DOWN_1_BLOCK = 20, + MONKEY_ANIM_VAULT_DOWN_0_POINT_3_BLOCKS = 21, + MONKEY_ANIM_VAULT_DOWN_0_POINT_2_BLOCKS = 22, + MONKEY_ANIM_SWIPE_ATTACK = 23, + MONKEY_ANIM_JUMP_ATTACK = 24, + MONKEY_ANIM_BITE_ATTACK = 25, + MONKEY_ANIM_HIGH_JUMP_ATTACK_START = 26, + MONKEY_ANIM_HIGH_JUMP_ATTACK_CONTINUE = 27, + MONKEY_ANIM_HIGH_JUMP_ATTACK_END = 28, + MONKEY_ANIM_IDLE_TO_WALK_FORWARD = 29, + MONKEY_ANIM_WALK_FORWARD_TO_IDLE = 30 + }; + void InitialiseMonkey(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 2; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 6; - item->Animation.TargetState = 6; + SetAnimation(item, MONKEY_ANIM_SIT); } void MonkeyControl(short itemNumber) @@ -40,20 +102,17 @@ namespace TEN::Entities::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short headX = 0; - short headY = 0; - short torsoY = 0; short angle = 0; short tilt = 0; + auto extraHeadRot = Vector3Shrt::Zero; + auto extraTorsoRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { - if (item->Animation.ActiveState != 11) + if (item->Animation.ActiveState != MONKEY_STATE_DEATH) { + SetAnimation(item, MONKEY_ANIM_DEATH); item->MeshBits = ALL_JOINT_BITS; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 14; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 11; } } else @@ -64,12 +123,11 @@ namespace TEN::Entities::TR3 creature->Enemy = LaraItem; else { - int minDistance = 0x7FFFFFFF; creature->Enemy = nullptr; + int minDistance = INT_MAX; - for (int i = 0; i < ActiveCreatures.size(); i++) + for (auto& currentCreature : ActiveCreatures) { - auto* currentCreature = ActiveCreatures[i]; if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber) continue; @@ -110,11 +168,11 @@ namespace TEN::Entities::TR3 AI_INFO AI; CreatureAIInfo(item, &AI); - if (!creature->HurtByLara && creature->Enemy == LaraItem) + if (!creature->HurtByLara && creature->Enemy->IsLara()) creature->Enemy = nullptr; AI_INFO laraAI; - if (creature->Enemy == LaraItem) + if (creature->Enemy->IsLara()) { laraAI.angle = AI.angle; laraAI.distance = AI.distance; @@ -147,144 +205,147 @@ namespace TEN::Entities::TR3 switch (item->Animation.ActiveState) { - case 6: - creature->Flags = 0; + case MONKEY_STATE_SIT: creature->MaxTurn = 0; - torsoY = laraAI.angle; + creature->Flags = 0; + extraTorsoRot.y = laraAI.angle; if (item->AIBits & GUARD) { - torsoY = AIGuard(creature); + extraTorsoRot.y = AIGuard(creature); if (TestProbability(0.06f)) { if (TestProbability(0.5f)) - item->Animation.TargetState = 8; + item->Animation.TargetState = MONKEY_STATE_SIT_EAT; else - item->Animation.TargetState = 7; + item->Animation.TargetState = MONKEY_STATE_SIT_SCRATCH; } break; } - else if (item->AIBits & PATROL1) - item->Animation.TargetState = 2; + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; else if (creature->Mood == MoodType::Escape) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; else if (creature->Mood == MoodType::Bored) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; else if (TestProbability(0.06f)) - item->Animation.TargetState = 2; + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; else if (TestProbability(0.06f)) { if (TestProbability(0.5f)) - item->Animation.TargetState = 8; + item->Animation.TargetState = MONKEY_STATE_SIT_EAT; else - item->Animation.TargetState = 7; + item->Animation.TargetState = MONKEY_STATE_SIT_SCRATCH; } } - else if ((item->AIBits & FOLLOW) && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + else if ((item->AIBits & FOLLOW) && + (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; else if (AI.ahead) - item->Animation.TargetState = 6; + item->Animation.TargetState = MONKEY_STATE_SIT; else - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; } else if (AI.bite && AI.distance < pow(682, 2)) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; else if (AI.bite && AI.distance < pow(682, 2)) - item->Animation.TargetState = 2; + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; else - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; break; - case 3: + case MONKEY_STATE_IDLE: creature->MaxTurn = 0; creature->Flags = 0; - torsoY = laraAI.angle; + extraTorsoRot.y = laraAI.angle; if (item->AIBits & GUARD) { - torsoY = AIGuard(creature); + extraTorsoRot.y = AIGuard(creature); if (TestProbability(0.06f)) { if (TestProbability(0.5f)) - item->Animation.TargetState = 10; + item->Animation.TargetState = MONKEY_STATE_POUND_GROUND; else - item->Animation.TargetState = 6; + item->Animation.TargetState = MONKEY_STATE_SIT; } break; } else if (item->AIBits & PATROL1) - item->Animation.TargetState = 2; + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; else if (creature->Mood == MoodType::Escape) { if (Lara.TargetEntity != item && AI.ahead) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; else - item->Animation.TargetState = 4; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; } else if (creature->Mood == MoodType::Bored) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; else if (TestProbability(0.06f)) - item->Animation.TargetState = 2; + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; else if (TestProbability(0.06f)) { if (TestProbability(0.5f)) - item->Animation.TargetState = 10; + item->Animation.TargetState = MONKEY_STATE_POUND_GROUND; else - item->Animation.TargetState = 6; + item->Animation.TargetState = MONKEY_STATE_SIT; } } - else if (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + else if (item->AIBits & FOLLOW && + (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; else if (AI.ahead) - item->Animation.TargetState = 6; + item->Animation.TargetState = MONKEY_STATE_SIT; else - item->Animation.TargetState = 4; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; } else if (AI.bite && AI.distance < pow(341, 2)) { if (LaraItem->Pose.Position.y < item->Pose.Position.y) - item->Animation.TargetState = 13; + item->Animation.TargetState = MONKEY_STATE_JUMP_ATTACK; else - item->Animation.TargetState = 12; + item->Animation.TargetState = MONKEY_STATE_SWIPE_ATTACK; } else if (AI.bite && AI.distance < pow(682, 2)) - item->Animation.TargetState = 14; + item->Animation.TargetState = MONKEY_STATE_HIGH_JUMP_ATTACK; else if (AI.bite && AI.distance < pow(682, 2)) - item->Animation.TargetState = 2; - else if (AI.distance < pow(682, 2) && creature->Enemy != LaraItem && creature->Enemy != nullptr && - creature->Enemy->ObjectNumber != ID_AI_PATROL1 && creature->Enemy->ObjectNumber != ID_AI_PATROL2 && - abs(item->Pose.Position.y - creature->Enemy->Pose.Position.y) < 256) + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; + else if (AI.distance < pow(682, 2) && + !creature->Enemy->IsLara() && creature->Enemy != nullptr && + creature->Enemy->ObjectNumber != ID_AI_PATROL1 && + creature->Enemy->ObjectNumber != ID_AI_PATROL2 && + abs(item->Pose.Position.y - creature->Enemy->Pose.Position.y) < CLICK(1)) { - item->Animation.TargetState = 5; + item->Animation.TargetState = MONKEY_STATE_BITE_ATTACK; } else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) - item->Animation.TargetState = 9; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD_ROLL; else - item->Animation.TargetState = 4; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; break; - case 5: + case MONKEY_STATE_BITE_ATTACK: creature->ReachedGoal = true; if (creature->Enemy == nullptr) break; else if ((creature->Enemy->ObjectNumber == ID_SMALLMEDI_ITEM || creature->Enemy->ObjectNumber == ID_KEY_ITEM4) && - item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 12) + item->Animation.FrameNumber == (g_Level.Anims[item->Animation.AnimNumber].frameBase + 12)) { if (creature->Enemy->RoomNumber == NO_ROOM || creature->Enemy->Status == ITEM_INVISIBLE || @@ -299,9 +360,8 @@ namespace TEN::Entities::TR3 creature->Enemy->RoomNumber = NO_ROOM; creature->Enemy->CarriedItem = NO_ITEM; - for (int i = 0; i < ActiveCreatures.size(); i++) + for (auto& currentCreature : ActiveCreatures) { - auto* currentCreature = ActiveCreatures[i]; if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber) continue; @@ -319,15 +379,14 @@ namespace TEN::Entities::TR3 } } } - else if (creature->Enemy->ObjectNumber == ID_AI_AMBUSH && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 12) + else if (creature->Enemy->ObjectNumber == ID_AI_AMBUSH && + item->Animation.FrameNumber == (g_Level.Anims[item->Animation.AnimNumber].frameBase + 12)) { item->AIBits = 0; auto* carriedItem = &g_Level.Items[item->CarriedItem]; - carriedItem->Pose.Position.x = item->Pose.Position.x; - carriedItem->Pose.Position.y = item->Pose.Position.y; - carriedItem->Pose.Position.z = item->Pose.Position.z; + carriedItem->Pose.Position = item->Pose.Position; ItemNewRoom(item->CarriedItem, item->RoomNumber); item->CarriedItem = NO_ITEM; @@ -349,60 +408,106 @@ namespace TEN::Entities::TR3 break; - case 2: + case MONKEY_STATE_WALK_FORWARD: creature->MaxTurn = ANGLE(7.0f); - torsoY = laraAI.angle; + extraTorsoRot.y = laraAI.angle; if (item->AIBits & PATROL1) { - item->Animation.TargetState = 2; - torsoY = 0; + item->Animation.TargetState = MONKEY_STATE_WALK_FORWARD; + extraTorsoRot.y = 0; } else if (creature->Mood == MoodType::Escape) - item->Animation.TargetState = 4; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; else if (creature->Mood == MoodType::Bored) { if (TestProbability(0.008f)) - item->Animation.TargetState = 6; + item->Animation.TargetState = MONKEY_STATE_SIT; } else if (AI.bite && AI.distance < pow(682, 2)) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; break; - case 4: + case MONKEY_STATE_RUN_FORWARD: creature->MaxTurn = ANGLE(11.0f); tilt = angle / 2; if (AI.ahead) - torsoY = AI.angle; + extraTorsoRot.y = AI.angle; if (item->AIBits & GUARD) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; else if (creature->Mood == MoodType::Escape) { if (Lara.TargetEntity != item && AI.ahead) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; + break; } - else if ((item->AIBits & FOLLOW) && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) - item->Animation.TargetState = 3; + else if ((item->AIBits & FOLLOW) && + (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) + { + item->Animation.TargetState = MONKEY_STATE_IDLE; + } else if (creature->Mood == MoodType::Bored) - item->Animation.TargetState = 9; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD_ROLL; else if (AI.distance < pow(682, 2)) - item->Animation.TargetState = 3; + item->Animation.TargetState = MONKEY_STATE_IDLE; else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) - item->Animation.TargetState = 9; + item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD_ROLL; break; - case 12: + case MONKEY_STATE_SWIPE_ATTACK: creature->MaxTurn = 0; if (AI.ahead) { - headY = AI.angle; - headX = AI.xAngle; + extraHeadRot.x = AI.xAngle; + extraHeadRot.y = AI.angle; + } + + if (abs(AI.angle) < ANGLE(7.0f)) + item->Pose.Orientation.y += AI.angle; + else if (AI.angle < 0) + item->Pose.Orientation.y -= ANGLE(7.0f); + else + item->Pose.Orientation.y += ANGLE(7.0f); + + if (enemy->IsLara()) + { + if (!creature->Flags && item->TestBits(JointBitType::Touch, MonkeyAttackJoints)) + { + DoDamage(enemy, MONKEY_SWIPE_ATTACK_PLAYER_DAMAGE); + CreatureEffect(item, MonkeyBite, DoBloodSplat); + creature->Flags = 1; + } + } + else + { + if (!creature->Flags && enemy) + { + if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < CLICK(1) && + abs(enemy->Pose.Position.y - item->Pose.Position.y) <= CLICK(1) && + abs(enemy->Pose.Position.z - item->Pose.Position.z) < CLICK(1)) + { + DoDamage(enemy, MONKEY_SWIPE_ATTACK_CREATURE_DAMAGE); + CreatureEffect(item, MonkeyBite, DoBloodSplat); + creature->Flags = 1; + } + } + } + + break; + + case MONKEY_STATE_JUMP_ATTACK: + creature->MaxTurn = 0; + + if (AI.ahead) + { + extraHeadRot.x = AI.xAngle; + extraHeadRot.y = AI.angle; } if (abs(AI.angle) < ANGLE(7.0f)) @@ -423,7 +528,7 @@ namespace TEN::Entities::TR3 } else { - if (!creature->Flags && enemy) + if (!creature->Flags && enemy != nullptr) { if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < CLICK(1) && abs(enemy->Pose.Position.y - item->Pose.Position.y) <= CLICK(1) && @@ -438,55 +543,13 @@ namespace TEN::Entities::TR3 break; - case 13: + case MONKEY_STATE_HIGH_JUMP_ATTACK: creature->MaxTurn = 0; if (AI.ahead) { - headY = AI.angle; - headX = AI.xAngle; - } - - if (abs(AI.angle) < ANGLE(7.0f)) - item->Pose.Orientation.y += AI.angle; - else if (AI.angle < 0) - item->Pose.Orientation.y -= ANGLE(7.0f); - else - item->Pose.Orientation.y += ANGLE(7.0f); - - if (enemy->IsLara()) - { - if (!creature->Flags && item->TestBits(JointBitType::Touch, MonkeyAttackJoints)) - { - DoDamage(enemy, 40); - CreatureEffect(item, MonkeyBite, DoBloodSplat); - creature->Flags = 1; - } - } - else - { - if (!creature->Flags && enemy) - { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < CLICK(1) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= CLICK(1) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < CLICK(1)) - { - DoDamage(enemy, 20); - CreatureEffect(item, MonkeyBite, DoBloodSplat); - creature->Flags = 1; - } - } - } - - break; - - case 14: - creature->MaxTurn = 0; - - if (AI.ahead) - { - headX = AI.xAngle; - headY = AI.angle; + extraHeadRot.x = AI.xAngle; + extraHeadRot.y = AI.angle; } if (abs(AI.angle) < ANGLE(7.0f)) @@ -525,54 +588,42 @@ namespace TEN::Entities::TR3 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, headY); - CreatureJoint(item, 1, headX); - CreatureJoint(item, 2, torsoY); + CreatureJoint(item, 0, extraHeadRot.y); + CreatureJoint(item, 1, extraHeadRot.x); + CreatureJoint(item, 2, extraTorsoRot.y); - if (item->Animation.ActiveState < 15) + if (item->Animation.ActiveState < MONKEY_STATE_VAULT_UP_1_BLOCK) { - switch (CreatureVault(itemNumber, angle, 2, 128)) + switch (CreatureVault(itemNumber, angle, 2, CLICK(0.5f))) { case 2: + SetAnimation(item, MONKEY_ANIM_VAULT_UP_0_POINT_2_BLOCKS); creature->MaxTurn = 0; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 19; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 17; break; case 3: + SetAnimation(item, MONKEY_ANIM_VAULT_UP_0_POINT_3_BLOCKS); creature->MaxTurn = 0; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 18; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 16; break; case 4: + SetAnimation(item, MONKEY_ANIM_VAULT_UP_1_BLOCK); creature->MaxTurn = 0; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 17; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 15; break; case -2: + SetAnimation(item, MONKEY_ANIM_VAULT_DOWN_0_POINT_2_BLOCKS); creature->MaxTurn = 0; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 22; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 20; break; case -3: + SetAnimation(item, MONKEY_ANIM_VAULT_DOWN_0_POINT_3_BLOCKS); creature->MaxTurn = 0; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 21; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 19; break; case -4: + SetAnimation(item, MONKEY_ANIM_VAULT_DOWN_1_BLOCK); creature->MaxTurn = 0; - item->Animation.AnimNumber = Objects[ID_MONKEY].animIndex + 20; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 18; break; } } diff --git a/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp b/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp index 2d618700a..3a8eb3d89 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp @@ -29,10 +29,10 @@ namespace TEN::Entities::TR3 #define SHIVA_WALK_TURN_RATE_MAX ANGLE(4.0f) #define SHIVA_ATTACK_TURN_RATE_MAX ANGLE(4.0f) - const vector ShivaAttackLeftJoints = { 10, 13 }; - const vector ShivaAttackRightJoints = { 22, 25 }; const auto ShivaBiteLeft = BiteInfo(Vector3(0.0f, 0.0f, 920.0f), 13); const auto ShivaBiteRight = BiteInfo(Vector3(0.0f, 0.0f, 920.0f), 22); + const vector ShivaAttackLeftJoints = { 10, 13 }; + const vector ShivaAttackRightJoints = { 22, 25 }; enum ShivaState { @@ -81,7 +81,7 @@ namespace TEN::Entities::TR3 }; - static void TriggerShivaSmoke(long x, long y, long z, long uw) + void TriggerShivaSmoke(long x, long y, long z, long uw) { long dx = LaraItem->Pose.Position.x - x; long dz = LaraItem->Pose.Position.z - z; @@ -169,7 +169,7 @@ namespace TEN::Entities::TR3 sptr->dSize = size; } - static void ShivaDamage(ItemInfo* item, CreatureInfo* creature, int damage) + void ShivaDamage(ItemInfo* item, CreatureInfo* creature, int damage) { if (!(creature->Flags) && item->TestBits(JointBitType::Touch, ShivaAttackRightJoints)) { @@ -451,8 +451,8 @@ namespace TEN::Entities::TR3 case SHIVA_STATE_KILL: shiva->MaxTurn = 0; - extraHeadRot = Vector3Shrt(); - extraTorsoRot = Vector3Shrt(); + extraHeadRot = Vector3Shrt::Zero; + extraTorsoRot = Vector3Shrt::Zero; if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + SHIVA_ANIM_WALK_FORWARD_TO_GUARDED_LEFT_1 || item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + SHIVA_ANIM_WALK_BACK_RIGHT || @@ -466,7 +466,7 @@ namespace TEN::Entities::TR3 } } - // Dispatch kill animation + // Dispatch kill animation. if (laraAlive && LaraItem->HitPoints <= 0) { item->Animation.TargetState = SHIVA_STATE_KILL; @@ -474,15 +474,13 @@ namespace TEN::Entities::TR3 if (LaraItem->RoomNumber != item->RoomNumber) ItemNewRoom(Lara.ItemNumber, item->RoomNumber); - LaraItem->Pose.Position = item->Pose.Position; - LaraItem->Pose.Orientation = Vector3Shrt(0, item->Pose.Orientation.y, 0); - LaraItem->Animation.IsAirborne = false; - LaraItem->Animation.AnimNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex + LARA_ANIM_SHIVA_DEATH; LaraItem->Animation.FrameNumber = g_Level.Anims[LaraItem->Animation.AnimNumber].frameBase; LaraItem->Animation.ActiveState = LS_DEATH; LaraItem->Animation.TargetState = LS_DEATH; - + LaraItem->Animation.IsAirborne = false; + LaraItem->Pose.Position = item->Pose.Position; + LaraItem->Pose.Orientation = Vector3Shrt(0, item->Pose.Orientation.y, 0); LaraItem->HitPoints = NOT_TARGETABLE; Lara.Air = -1; Lara.Control.HandStatus = HandStatus::Special; diff --git a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp index a90133027..bccb3d500 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp @@ -770,10 +770,10 @@ namespace TEN::Entities::TR4 creature->MaxTurn = 0; ClampRotation(&item->Pose, AI.angle, ANGLE(6.0f)); - if ((enemy == NULL || enemy->Flags != NULL) || + if ((enemy == nullptr || enemy->Flags != 0) || item->Animation.FrameNumber <= g_Level.Anims[item->Animation.AnimNumber].frameBase + 21) { - if (creature->Flags == NULL && enemy != nullptr) + if (creature->Flags == 0 && enemy != nullptr) { if (item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 15 && item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 26) @@ -849,7 +849,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = VON_CROY_STATE_WALK; item->Animation.RequiredState = VON_CROY_STATE_RUN; - item->ItemFlags[2] = NULL; + item->ItemFlags[2] = 0; //if (sVar3 == -1) goto LAB_0041a991; if (!flags) { @@ -878,38 +878,38 @@ namespace TEN::Entities::TR4 CreatureJoint(item, 2, joint2); CreatureJoint(item, 3, joint3); - if ((item->Animation.ActiveState < VON_CROY_STATE_JUMP) && (item->Animation.ActiveState != VON_CROY_STATE_MONKEY)) + if (item->Animation.ActiveState < VON_CROY_STATE_JUMP && + item->Animation.ActiveState != VON_CROY_STATE_MONKEY) { switch (CreatureVault(itemNumber, angle, 2, 260)) { - case VON_CROY_STATE_WALK: + case 2: item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_2_BLOCKS; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = VON_CROY_STATE_CLIMB_2_BLOCKS; creature->MaxTurn = 0; break; - case VON_CROY_STATE_RUN: + case 3: item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_3_BLOCKS; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = VON_CROY_STATE_CLIMB_3_BLOCKS; creature->MaxTurn = 0; break; - case VON_CROY_STATE_START_MONKEY: + case 4: item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_4_BLOCKS; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = VON_CROY_STATE_CLIMB_4_BLOCKS; creature->MaxTurn = 0; break; - case VON_CROY_STATE_LOOK_BEFORE_JUMP: + case 7: item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_JUMP_TO_HANG; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = VON_CROY_STATE_GRAB_LADDER; creature->MaxTurn = 0; break; - // I am not sure what negative states are (probably the inverse of the above), I will leave them alone - Kubsy 18/06/2022 case -7: item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + VON_CROY_ANIM_CLIMB_DOWN_2_SECTORS; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index b45c443e6..99147a8c1 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -141,7 +141,7 @@ namespace TEN::Entities::TR5 CreatureMood(item, &AI, true); if (AI.distance < SQUARE(SECTOR(2)) && - LaraItem->Animation.Velocity > 20 || + LaraItem->Animation.Velocity.z > 20.0f || item->HitStatus || TargetVisible(item, &AI) != 0) { From 02a8d935caac79db4d3dfce505598e0718e8d34b Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 19 Aug 2022 00:05:52 +0100 Subject: [PATCH 009/106] Update docs --- Documentation/config.ld | 2 +- Documentation/doc/1 modules/Effects.html | 4 +-- Documentation/doc/1 modules/Flow.html | 4 +-- Documentation/doc/1 modules/Inventory.html | 4 +-- Documentation/doc/1 modules/Logic.html | 4 +-- Documentation/doc/1 modules/Misc.html | 4 +-- Documentation/doc/1 modules/Objects.html | 4 +-- Documentation/doc/1 modules/Strings.html | 4 +-- .../doc/2 classes/Flow.Animations.html | 4 +-- Documentation/doc/2 classes/Flow.Fog.html | 4 +-- .../doc/2 classes/Flow.InventoryItem.html | 4 +-- Documentation/doc/2 classes/Flow.Level.html | 29 ++----------------- Documentation/doc/2 classes/Flow.Mirror.html | 4 +-- .../doc/2 classes/Flow.Settings.html | 4 +-- .../doc/2 classes/Flow.SkyLayer.html | 4 +-- .../doc/2 classes/Objects.AIObject.html | 4 +-- .../doc/2 classes/Objects.Camera.html | 4 +-- .../doc/2 classes/Objects.Moveable.html | 4 +-- Documentation/doc/2 classes/Objects.Sink.html | 4 +-- .../doc/2 classes/Objects.SoundSource.html | 4 +-- .../doc/2 classes/Objects.Static.html | 4 +-- .../doc/2 classes/Strings.DisplayString.html | 4 +-- .../doc/3 primitive classes/Color.html | 4 +-- .../doc/3 primitive classes/Rotation.html | 4 +-- .../doc/3 primitive classes/Vec3.html | 4 +-- .../doc/4 enums/Effects.BlendID.html | 4 +-- Documentation/doc/4 enums/Flow.InvID.html | 4 +-- Documentation/doc/4 enums/Objects.ObjID.html | 4 +-- .../5 lua utility modules/EventSequence.html | 4 +-- .../doc/5 lua utility modules/Timer.html | 4 +-- .../doc/5 lua utility modules/Util.html | 4 +-- Documentation/doc/index.html | 6 ++-- .../Internal/TEN/Flow/Level/FlowLevel.cpp | 8 ----- .../Internal/TEN/Flow/Level/FlowLevel.h | 1 - 34 files changed, 65 insertions(+), 97 deletions(-) diff --git a/Documentation/config.ld b/Documentation/config.ld index 75fce7222..903bc8e9e 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.1" +local version = "1.0.2" 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 acb3a242b..96a620603 100644 --- a/Documentation/doc/1 modules/Effects.html +++ b/Documentation/doc/1 modules/Effects.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -511,7 +511,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index c80e697c8..058eb30e2 100644 --- a/Documentation/doc/1 modules/Flow.html +++ b/Documentation/doc/1 modules/Flow.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -353,7 +353,7 @@ Specify which translations in the strings table correspond to which languages.
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index 327be00e9..2b13b1af3 100644 --- a/Documentation/doc/1 modules/Inventory.html +++ b/Documentation/doc/1 modules/Inventory.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -204,7 +204,7 @@ Similar to GiveItem but repla
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index 4475152b2..75f3dbfed 100644 --- a/Documentation/doc/1 modules/Logic.html +++ b/Documentation/doc/1 modules/Logic.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -279,7 +279,7 @@ and provides the delta time (a float representing game time since last call) via
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/1 modules/Misc.html b/Documentation/doc/1 modules/Misc.html index 22ce29e8d..e49ef1a65 100644 --- a/Documentation/doc/1 modules/Misc.html +++ b/Documentation/doc/1 modules/Misc.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -632,7 +632,7 @@ To be used with
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/1 modules/Objects.html b/Documentation/doc/1 modules/Objects.html index 0aa9b0508..fbd3e71bd 100644 --- a/Documentation/doc/1 modules/Objects.html +++ b/Documentation/doc/1 modules/Objects.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -297,7 +297,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html index d07a6c74d..0bc83ae5d 100644 --- a/Documentation/doc/1 modules/Strings.html +++ b/Documentation/doc/1 modules/Strings.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -169,7 +169,7 @@ with a call to ShowString, or
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.Animations.html b/Documentation/doc/2 classes/Flow.Animations.html index 25b6ecaa5..956dc4fca 100644 --- a/Documentation/doc/2 classes/Flow.Animations.html +++ b/Documentation/doc/2 classes/Flow.Animations.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -100,7 +100,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.Fog.html b/Documentation/doc/2 classes/Flow.Fog.html index 1aeaeeaef..912f3ea19 100644 --- a/Documentation/doc/2 classes/Flow.Fog.html +++ b/Documentation/doc/2 classes/Flow.Fog.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -227,7 +227,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.InventoryItem.html b/Documentation/doc/2 classes/Flow.InventoryItem.html index 8a35205c0..b5e5dd9c2 100644 --- a/Documentation/doc/2 classes/Flow.InventoryItem.html +++ b/Documentation/doc/2 classes/Flow.InventoryItem.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -182,7 +182,7 @@ EXAMINE
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html index e43c230be..4e29132bb 100644 --- a/Documentation/doc/2 classes/Flow.Level.html +++ b/Documentation/doc/2 classes/Flow.Level.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -120,8 +120,7 @@ layer2 - (Flow.SkyLayer) Secondary sky layer - (not yet implemented) + (Flow.SkyLayer) Secondary sky layer fog @@ -132,10 +131,6 @@ (bool) Draw sky layer? - colAddHorizon - (bool) Enable smooth transition from horizon graphic to sky layer. - - storm (bool) Enable flickering lightning in the sky. @@ -282,7 +277,6 @@
(Flow.SkyLayer) Secondary sky layer - (not yet implemented) @@ -320,23 +314,6 @@ -
-
- - colAddHorizon -
-
- (bool) Enable smooth transition from horizon graphic to sky layer. - If set to false, there will be a black band between the two.

- -

(not yet implemented) - - - - - - -

@@ -519,7 +496,7 @@ Must be at least 4.

generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.Mirror.html b/Documentation/doc/2 classes/Flow.Mirror.html index 8847b143e..4f4f07877 100644 --- a/Documentation/doc/2 classes/Flow.Mirror.html +++ b/Documentation/doc/2 classes/Flow.Mirror.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -100,7 +100,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index 96ef22346..95edfc4f5 100644 --- a/Documentation/doc/2 classes/Flow.Settings.html +++ b/Documentation/doc/2 classes/Flow.Settings.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -143,7 +143,7 @@ an invalid argument.

generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Flow.SkyLayer.html b/Documentation/doc/2 classes/Flow.SkyLayer.html index 69b0dd699..7fea04f07 100644 --- a/Documentation/doc/2 classes/Flow.SkyLayer.html +++ b/Documentation/doc/2 classes/Flow.SkyLayer.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -199,7 +199,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Objects.AIObject.html b/Documentation/doc/2 classes/Objects.AIObject.html index 290626a04..c2a673b47 100644 --- a/Documentation/doc/2 classes/Objects.AIObject.html +++ b/Documentation/doc/2 classes/Objects.AIObject.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -372,7 +372,7 @@ aiObj:SetObjectID(TEN.Objects.ObjID.AI_PATROL1)
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html index 2b81eb147..ed23fa7e6 100644 --- a/Documentation/doc/2 classes/Objects.Camera.html +++ b/Documentation/doc/2 classes/Objects.Camera.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -260,7 +260,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index 324c4e627..d89f7958c 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -1488,7 +1488,7 @@ sas:SetPosition(destinationPosition)
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Objects.Sink.html b/Documentation/doc/2 classes/Objects.Sink.html index 329da6b12..bb1d7e3f7 100644 --- a/Documentation/doc/2 classes/Objects.Sink.html +++ b/Documentation/doc/2 classes/Objects.Sink.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -262,7 +262,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Objects.SoundSource.html b/Documentation/doc/2 classes/Objects.SoundSource.html index cfb423da8..f75d1282c 100644 --- a/Documentation/doc/2 classes/Objects.SoundSource.html +++ b/Documentation/doc/2 classes/Objects.SoundSource.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -260,7 +260,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Objects.Static.html b/Documentation/doc/2 classes/Objects.Static.html index e79e73406..4ec87c539 100644 --- a/Documentation/doc/2 classes/Objects.Static.html +++ b/Documentation/doc/2 classes/Objects.Static.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -358,7 +358,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html index d73bbcdd6..4448c7061 100644 --- a/Documentation/doc/2 classes/Strings.DisplayString.html +++ b/Documentation/doc/2 classes/Strings.DisplayString.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -307,7 +307,7 @@ TEN.Strings.DisplayStringOption.SHADOW -- will give the text a small shadow
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html index 1c762a147..ae3beb4e4 100644 --- a/Documentation/doc/3 primitive classes/Color.html +++ b/Documentation/doc/3 primitive classes/Color.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -312,7 +312,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html index 4dcb6d4fa..8a3550d64 100644 --- a/Documentation/doc/3 primitive classes/Rotation.html +++ b/Documentation/doc/3 primitive classes/Rotation.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -250,7 +250,7 @@ All values will be clamped to [-32768, 32767].

generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/3 primitive classes/Vec3.html b/Documentation/doc/3 primitive classes/Vec3.html index 3e37fa21e..3854494cc 100644 --- a/Documentation/doc/3 primitive classes/Vec3.html +++ b/Documentation/doc/3 primitive classes/Vec3.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -277,7 +277,7 @@ However, this function would return it as (0, 1, 1).
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/4 enums/Effects.BlendID.html b/Documentation/doc/4 enums/Effects.BlendID.html index 4ec654dd5..e28f95e94 100644 --- a/Documentation/doc/4 enums/Effects.BlendID.html +++ b/Documentation/doc/4 enums/Effects.BlendID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -149,7 +149,7 @@ ALPHABLEND
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/4 enums/Flow.InvID.html b/Documentation/doc/4 enums/Flow.InvID.html index fde91a227..f8cc82a68 100644 --- a/Documentation/doc/4 enums/Flow.InvID.html +++ b/Documentation/doc/4 enums/Flow.InvID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -358,7 +358,7 @@ EXAMINE_ITEM8_COMBO2
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index 74f8fea1f..d7319e080 100644 --- a/Documentation/doc/4 enums/Objects.ObjID.html +++ b/Documentation/doc/4 enums/Objects.ObjID.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -1096,7 +1096,7 @@ PANEL_MIDDLE_CORNER
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index be2753a3d..4433f4d59 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.1 Lua API + TombEngine 1.0.2 Lua API @@ -333,7 +333,7 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index c5d37ad0c..f9956d80e 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.1 Lua API + TombEngine 1.0.2 Lua API @@ -524,7 +524,7 @@ local myTimeFormat4 = {seconds = true}
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/5 lua utility modules/Util.html b/Documentation/doc/5 lua utility modules/Util.html index 5f54cb8a0..4b016dc95 100644 --- a/Documentation/doc/5 lua utility modules/Util.html +++ b/Documentation/doc/5 lua utility modules/Util.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -138,7 +138,7 @@
generated by LDoc 1.4.6 -Last updated 2022-08-11 22:43:52 +Last updated 2022-08-19 00:04:24
diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html index af9e6cbea..99e56b692 100644 --- a/Documentation/doc/index.html +++ b/Documentation/doc/index.html @@ -3,7 +3,7 @@ - TombEngine 1.0.1 Lua API + TombEngine 1.0.2 Lua API @@ -80,7 +80,7 @@
-

TombEngine 1.0.1 scripting interface

+

TombEngine 1.0.2 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 wiki here.

@@ -248,7 +248,7 @@ Util.ShortenTENCalls()
generated by LDoc 1.4.6 -Last updated 2022-08-14 20:33:42 +Last updated 2022-08-19 00:04:24
diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp index 37d8abb75..a3b8e0a47 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp @@ -49,7 +49,6 @@ void Level::Register(sol::table & parent) "layer1", &Level::Layer1, /// (@{Flow.SkyLayer}) Secondary sky layer -// __(not yet implemented)__ //@mem layer2 "layer2", &Level::Layer2, @@ -63,13 +62,6 @@ void Level::Register(sol::table & parent) //@mem horizon "horizon", &Level::Horizon, -/// (bool) Enable smooth transition from horizon graphic to sky layer. -// If set to false, there will be a black band between the two. -// -// __(not yet implemented)__ -//@mem colAddHorizon - "colAddHorizon", &Level::ColAddHorizon, - /// (bool) Enable flickering lightning in the sky. // Equivalent to classic TRLE's LIGHTNING setting. As in the TRC Ireland levels. // diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h index eba71e1b2..d0a4717b4 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h +++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.h @@ -29,7 +29,6 @@ struct Level : public ScriptInterfaceLevel std::string AmbientTrack; SkyLayer Layer1; SkyLayer Layer2; - bool ColAddHorizon{ false }; Fog Fog; bool Storm{ false }; WeatherType Weather{ WeatherType::None }; From 71f2ab7310b8c3d1d090ddd664250e07344f83da Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 19 Aug 2022 15:54:52 +1000 Subject: [PATCH 010/106] Demagic tr3_tiger.cpp --- TombEngine/Game/control/box.cpp | 42 ++--- TombEngine/Objects/TR3/Entity/tr3_tiger.cpp | 165 ++++++++++++-------- TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp | 12 +- 3 files changed, 121 insertions(+), 98 deletions(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index f11437934..5374e914d 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -449,7 +449,8 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) short top; auto* item = &g_Level.Items[itemNumber]; - if (!item->Data) + + if (!item->IsCreature()) return false; auto* creature = GetCreatureInfo(item); @@ -462,7 +463,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) else boxHeight = item->Floor; - auto old = item->Pose.Position; + auto oldPos = item->Pose.Position; AnimateItem(item); @@ -477,7 +478,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) int y = item->Pose.Position.y + bounds->Y1; short roomNumber = item->RoomNumber; - GetFloor(old.x, y, old.z, &roomNumber); + GetFloor(oldPos.x, y, oldPos.z, &roomNumber); FloorInfo* floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber); // TODO: Check why some blocks have box = -1 assigned to them -- Lwmte, 10.11.21 @@ -506,18 +507,18 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) { xPos = item->Pose.Position.x / SECTOR(1); zPos = item->Pose.Position.z / SECTOR(1); - shiftX = old.x / SECTOR(1); - shiftZ = old.z / SECTOR(1); + shiftX = oldPos.x / SECTOR(1); + shiftZ = oldPos.z / SECTOR(1); if (xPos < shiftX) - item->Pose.Position.x = old.x & (~(SECTOR(1) - 1)); + item->Pose.Position.x = oldPos.x & (~(SECTOR(1) - 1)); else if (xPos > shiftX) - item->Pose.Position.x = old.x | (SECTOR(1) - 1); + item->Pose.Position.x = oldPos.x | (SECTOR(1) - 1); if (zPos < shiftZ) - item->Pose.Position.z = old.z & (~(SECTOR(1) - 1)); + item->Pose.Position.z = oldPos.z & (~(SECTOR(1) - 1)); else if (zPos > shiftZ) - item->Pose.Position.z = old.z | (SECTOR(1) - 1); + item->Pose.Position.z = oldPos.z | (SECTOR(1) - 1); floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber); height = g_Level.Boxes[floor->Box].height; @@ -669,8 +670,8 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) { if (item->Pose.Position.y + top < ceiling) { - item->Pose.Position.x = old.x; - item->Pose.Position.z = old.z; + item->Pose.Position.x = oldPos.x; + item->Pose.Position.z = oldPos.z; dy = LOT->Fly; } else @@ -689,13 +690,13 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) } else if (item->Pose.Position.y <= height) { - dy = 0; item->Pose.Position.y = height; + dy = 0; } else { - item->Pose.Position.x = old.x; - item->Pose.Position.z = old.z; + item->Pose.Position.x = oldPos.x; + item->Pose.Position.z = oldPos.z; dy = -LOT->Fly; } @@ -732,11 +733,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) if (item->Pose.Position.y > item->Floor) { if (item->Pose.Position.y > (item->Floor + CLICK(1))) - { - item->Pose.Position.x = old.x; - item->Pose.Position.y = old.y; - item->Pose.Position.z = old.z; - } + item->Pose.Position = oldPos; else item->Pose.Position.y = item->Floor; } @@ -753,11 +750,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) top = bounds->Y1; // TODO: check if Y1 or Y2 if (item->Pose.Position.y + top < ceiling) - { - item->Pose.Position.x = old.x; - item->Pose.Position.z = old.z; - item->Pose.Position.y = old.y; - } + item->Pose.Position = oldPos; floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); item->Floor = GetFloorHeight(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); @@ -773,7 +766,6 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) } CreatureSwitchRoom(itemNumber); - return true; } diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp index 5a142f497..404fbaf58 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp @@ -19,19 +19,48 @@ namespace TEN::Entities::TR3 { constexpr auto TIGER_ATTACK_DAMAGE = 90; + constexpr auto TIGER_BITE_ATTACK_RANGE = SQUARE(SECTOR(0.33f)); + constexpr auto TIGER_POUNCE_ATTACK_RANGE = SQUARE(SECTOR(1)); + constexpr auto TIGER_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); + + constexpr auto TIGER_WALK_CHANCE = 0.035f; + constexpr auto TIGER_ROAR_CHANCE = 0.003f; + const auto TigerBite = BiteInfo(Vector3(19.0f, -13.0f, 3.0f), 26); const vector TigerAttackJoints = { 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; - // TODO + #define TIGER_WALK_TURN_RATE_MAX ANGLE(3.0f) + #define TIGER_RUN_TURN_RATE_MAX ANGLE(6.0f) + #define TIGER_POUNCE_ATTACK_TURN_RATE_MAX ANGLE(3.0f) + enum TigerState { - + TIGER_STATE_DEATH = 0, + TIGER_STATE_IDLE = 1, + TIGER_STATE_WALK_FORWARD = 2, + TIGER_STATE_RUN_FORWARD = 3, + // No state 4. + TIGER_STATE_ROAR = 5, + TIGER_STATE_BITE_ATTACK = 6, + TIGER_STATE_SWIPE_ATTACK = 7, + TIGER_STATE_POUNCE_ATTACK = 8 }; - // TODO enum TigerAnim { - + TIGER_ANIM_IDLE_TO_RUN_FORWARD = 0, + TIGER_ANIM_BITE_ATTACK = 1, + TIGER_ANIM_SWIPE_ATTACK = 2, + TIGER_ANIM_POUNCE_ATTACK_START = 3, + TIGER_ANIM_ROAR = 4, + TIGER_ANIM_RUN_FORWARD = 5, + TIGER_ANIM_RUN_FORWARD_TO_IDLE = 6, + TIGER_ANIM_IDLE = 7, + TIGER_ANIM_WALK_FORWARD = 8, + TIGER_ANIM_IDLE_TO_WALK_FORWARD = 9, + TIGER_ANIM_WALK_FORWARD_TO_IDLE = 10, + TIGER_ANIM_DEATH = 11, + TIGER_ANIM_POUNCE_ATTACK_END = 12 }; void TigerControl(short itemNumber) @@ -40,20 +69,16 @@ namespace TEN::Entities::TR3 return; auto* item = &g_Level.Items[itemNumber]; - auto* info = GetCreatureInfo(item); + auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; short tilt = 0; + auto extraHeadRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { - if (item->Animation.ActiveState != 9) - { - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 11; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 9; - } + if (item->Animation.ActiveState != TIGER_STATE_DEATH) + SetAnimation(item, TIGER_ANIM_DEATH); } else { @@ -61,99 +86,105 @@ namespace TEN::Entities::TR3 CreatureAIInfo(item, &AI); if (AI.ahead) - head = AI.angle; + extraHeadRot.y = AI.angle; - GetCreatureMood(item, &AI, 1); + GetCreatureMood(item, &AI, true); - if (info->Alerted && AI.zoneNumber != AI.enemyZone) - info->Mood = MoodType::Escape; + if (creature->Alerted && AI.zoneNumber != AI.enemyZone) + creature->Mood = MoodType::Escape; - CreatureMood(item, &AI, 1); + CreatureMood(item, &AI, true); - angle = CreatureTurn(item, info->MaxTurn); + angle = CreatureTurn(item, creature->MaxTurn); switch (item->Animation.ActiveState) { - case 1: - info->MaxTurn = 0; - info->Flags = 0; + case TIGER_STATE_IDLE: + creature->MaxTurn = 0; + creature->Flags = 0; - if (info->Mood == MoodType::Escape) + if (creature->Mood == MoodType::Escape) { if (Lara.TargetEntity != item && AI.ahead) - item->Animation.TargetState = 1; + item->Animation.TargetState = TIGER_STATE_IDLE; else - item->Animation.TargetState = 3; + item->Animation.TargetState = TIGER_STATE_RUN_FORWARD; } - else if (info->Mood == MoodType::Bored) + else if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.003f)) - item->Animation.TargetState = 5; - else if (TestProbability(0.035f)) - item->Animation.TargetState = 2; + if (TestProbability(TIGER_ROAR_CHANCE)) + item->Animation.TargetState = TIGER_STATE_ROAR; + else if (TestProbability(TIGER_WALK_CHANCE)) + item->Animation.TargetState = TIGER_STATE_WALK_FORWARD; } - else if (AI.bite && AI.distance < pow(340, 2)) - item->Animation.TargetState = 6; - else if (AI.bite && AI.distance < pow(SECTOR(1), 2)) + else if (AI.bite && AI.distance < TIGER_BITE_ATTACK_RANGE) + item->Animation.TargetState = TIGER_STATE_BITE_ATTACK; + else if (AI.bite && AI.distance < TIGER_POUNCE_ATTACK_RANGE) { - info->MaxTurn = ANGLE(3.0f); - item->Animation.TargetState = 8; + creature->MaxTurn = TIGER_POUNCE_ATTACK_TURN_RATE_MAX; + item->Animation.TargetState = TIGER_STATE_POUNCE_ATTACK; } else if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; - else if (info->Mood != MoodType::Attack && TestProbability(0.003f)) - item->Animation.TargetState = 5; + else if (creature->Mood != MoodType::Attack && TestProbability(TIGER_ROAR_CHANCE)) + item->Animation.TargetState = TIGER_STATE_ROAR; else - item->Animation.TargetState = 3; + item->Animation.TargetState = TIGER_STATE_RUN_FORWARD; break; - case 2: - info->MaxTurn = ANGLE(3.0f); + case TIGER_STATE_WALK_FORWARD: + creature->MaxTurn = TIGER_WALK_TURN_RATE_MAX; - if (info->Mood == MoodType::Escape || info->Mood == MoodType::Attack) - item->Animation.TargetState = 3; - else if (TestProbability(0.003f)) + if (creature->Mood == MoodType::Escape || + creature->Mood == MoodType::Attack) { - item->Animation.TargetState = 1; - item->Animation.RequiredState = 5; + item->Animation.TargetState = TIGER_STATE_RUN_FORWARD; + } + else if (TestProbability(TIGER_ROAR_CHANCE)) + { + item->Animation.TargetState = TIGER_STATE_IDLE; + item->Animation.RequiredState = TIGER_STATE_ROAR; } break; - case 3: - info->MaxTurn = ANGLE(6.0f); + case TIGER_STATE_RUN_FORWARD: + creature->MaxTurn = TIGER_RUN_TURN_RATE_MAX; - if (info->Mood == MoodType::Bored) - item->Animation.TargetState = 1; - else if (info->Flags && AI.ahead) - item->Animation.TargetState = 1; - else if (AI.bite && AI.distance < pow(SECTOR(1.5f), 2)) + if (creature->Mood == MoodType::Bored) + item->Animation.TargetState = TIGER_STATE_IDLE; + else if (creature->Flags && AI.ahead) + item->Animation.TargetState = TIGER_STATE_IDLE; + else if (AI.bite && AI.distance < TIGER_RUN_ATTACK_RANGE) { - if (LaraItem->Animation.Velocity.z == 0) - item->Animation.TargetState = 1; + if (LaraItem->Animation.Velocity.z == 0.0f) + item->Animation.TargetState = TIGER_STATE_IDLE; else - item->Animation.TargetState = 7; + item->Animation.TargetState = TIGER_STATE_SWIPE_ATTACK; } - else if (info->Mood != MoodType::Attack && TestProbability(0.003f)) + else if (creature->Mood != MoodType::Attack && TestProbability(TIGER_ROAR_CHANCE)) { - item->Animation.TargetState = 1; - item->Animation.RequiredState = 5; + item->Animation.TargetState = TIGER_STATE_IDLE; + item->Animation.RequiredState = TIGER_STATE_ROAR; + } + else if (creature->Mood == MoodType::Escape && + Lara.TargetEntity != item && AI.ahead) + { + item->Animation.TargetState = TIGER_STATE_IDLE; } - else if (info->Mood == MoodType::Escape && Lara.TargetEntity != item && AI.ahead) - item->Animation.TargetState = 1; - info->Flags = 0; + creature->Flags = 0; break; - case 6: - case 7: - case 8: - if (!info->Flags && item->TestBits(JointBitType::Touch, TigerAttackJoints)) + case TIGER_STATE_BITE_ATTACK: + case TIGER_STATE_SWIPE_ATTACK: + case TIGER_STATE_POUNCE_ATTACK: + if (!creature->Flags && item->TestBits(JointBitType::Touch, TigerAttackJoints)) { - DoDamage(info->Enemy, TIGER_ATTACK_DAMAGE); + DoDamage(creature->Enemy, TIGER_ATTACK_DAMAGE); CreatureEffect(item, TigerBite, DoBloodSplat); - info->Flags = 1; + creature->Flags = 1; } break; @@ -161,7 +192,7 @@ namespace TEN::Entities::TR3 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, head); + CreatureJoint(item, 0, extraHeadRot.y); CreatureAnimation(itemNumber, angle, tilt); } } diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp index 9c2dc71a3..9851152e8 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp @@ -131,7 +131,7 @@ namespace TEN::Entities::TR4 auto* creature = GetCreatureInfo(item); short angle = 0; - short headY = 0; + auto extraHeadRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { @@ -186,7 +186,7 @@ namespace TEN::Entities::TR4 } if (AI.ahead) - headY = AI.angle; + extraHeadRot.y = AI.angle; switch (item->Animation.ActiveState) { @@ -197,12 +197,12 @@ namespace TEN::Entities::TR4 if (item->AIBits & GUARD) { item->Animation.TargetState = AHMET_STATE_IDLE; - headY = AIGuard(creature); + extraHeadRot.y = AIGuard(creature); } else if (item->AIBits & PATROL1) { item->Animation.TargetState = AHMET_STATE_WALK_FORWARD; - headY = 0; + extraHeadRot.y = 0; } else if (creature->Mood == MoodType::Bored || creature->Mood == MoodType::Escape) { @@ -239,7 +239,7 @@ namespace TEN::Entities::TR4 if (item->AIBits & PATROL1) { item->Animation.TargetState = AHMET_STATE_WALK_FORWARD; - headY = 0; + extraHeadRot.y = 0; } else if (AI.bite && AI.distance < AHMET_IDLE_RANGE) item->Animation.TargetState = AHMET_STATE_IDLE; @@ -371,7 +371,7 @@ namespace TEN::Entities::TR4 TestTriggers(item, true); CreatureTilt(item, 0); - CreatureJoint(item, 0, headY); + CreatureJoint(item, 0, extraHeadRot.y); CreatureAnimation(itemNumber, angle, 0); } From a92a3c76447775e01891007bf08378c700a7a42b Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 19 Aug 2022 16:22:28 +1000 Subject: [PATCH 011/106] Demagic raptor ranges and probabilities --- TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 26 +++++++++++--------- TombEngine/Objects/TR3/Entity/tr3_tiger.cpp | 17 +++++++------ 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index 5a1864f7b..5ec7ab18c 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -19,6 +19,11 @@ using std::vector; namespace TEN::Entities::TR3 { constexpr auto RAPTOR_ATTACK_DAMAGE = 100; + constexpr auto RAPTOR_BITE_ATTACK_RANGE = SQUARE(585); + constexpr auto RAPTOR_JUMP_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); + constexpr auto RAPTOR_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); + constexpr auto RAPTOR_ROAR_CHANCE = 0.004f; + constexpr auto RAPTOR_SWITCH_TARGET_CHANCE = 0.008f; #define RAPTOR_WALK_TURN_RATE_MAX ANGLE(2.0f) #define RAPTOR_RUN_TURN_RATE_MAX ANGLE(2.0f) @@ -86,14 +91,13 @@ namespace TEN::Entities::TR3 } else { - if (creature->Enemy == nullptr || TestProbability(0.008f)) + if (creature->Enemy == nullptr || TestProbability(RAPTOR_SWITCH_TARGET_CHANCE)) { ItemInfo* nearestItem = nullptr; int minDistance = INT_MAX; - for (int i = 0; i < ActiveCreatures.size(); i++) + for (auto* currentCreature : ActiveCreatures) { - auto* currentCreature = ActiveCreatures[i]; if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber) { currentCreature++; @@ -106,7 +110,7 @@ namespace TEN::Entities::TR3 int y = (targetItem->Pose.Position.y - item->Pose.Position.y) / 64; int z = (targetItem->Pose.Position.z - item->Pose.Position.z) / 64; - int distance = pow(x, 2) + pow(y, 2) + pow(z, 2); + int distance = SQUARE(x) + SQUARE(y) + SQUARE(z); if (distance < minDistance && item->HitPoints > 0) { nearestItem = targetItem; @@ -118,7 +122,7 @@ namespace TEN::Entities::TR3 if (nearestItem != nullptr && (nearestItem->ObjectNumber != ID_RAPTOR || - (TestProbability(0.03f) && minDistance < pow(SECTOR(2), 2)))) + (TestProbability(0.03f) && minDistance < SQUARE(SECTOR(2))))) { creature->Enemy = nearestItem; } @@ -127,7 +131,7 @@ namespace TEN::Entities::TR3 int y = (LaraItem->Pose.Position.y - item->Pose.Position.y) / 64; int z = (LaraItem->Pose.Position.z - item->Pose.Position.z) / 64; - int distance = pow(x, 2) + pow(y, 2) + pow(z, 2); + int distance = SQUARE(x) + SQUARE(y) + SQUARE(z); if (distance <= minDistance) creature->Enemy = LaraItem; } @@ -164,11 +168,11 @@ namespace TEN::Entities::TR3 item->Animation.TargetState = RAPTOR_STATE_ROAR; } else if (item->TestBits(JointBitType::Touch, RaptorAttackJoints) || - (AI.distance < pow(585, 2) && AI.bite)) + (AI.distance < RAPTOR_BITE_ATTACK_RANGE && AI.bite)) { item->Animation.TargetState = RAPTOR_STATE_BITE_ATTACK; } - else if (AI.bite && AI.distance < pow(SECTOR(1.5f), 2)) + else if (AI.bite && AI.distance < RAPTOR_JUMP_ATTACK_RANGE) item->Animation.TargetState = RAPTOR_STATE_JUMP_ATTACK; else if (creature->Mood == MoodType::Escape && Lara.TargetEntity != item && AI.ahead && !item->HitStatus) @@ -188,7 +192,7 @@ namespace TEN::Entities::TR3 if (creature->Mood != MoodType::Bored) item->Animation.TargetState = RAPTOR_STATE_IDLE; - else if (AI.ahead && TestProbability(0.004f)) + else if (AI.ahead && TestProbability(RAPTOR_ROAR_CHANCE)) { item->Animation.TargetState = RAPTOR_STATE_IDLE; item->Animation.RequiredState = RAPTOR_STATE_ROAR; @@ -210,7 +214,7 @@ namespace TEN::Entities::TR3 item->Animation.RequiredState = RAPTOR_STATE_ROAR; creature->Flags &= ~2; } - else if (AI.bite && AI.distance < pow(SECTOR(1.5f), 2)) + else if (AI.bite && AI.distance < RAPTOR_RUN_ATTACK_RANGE) { if (item->Animation.TargetState == RAPTOR_STATE_RUN_FORWARD) { @@ -221,7 +225,7 @@ namespace TEN::Entities::TR3 } } else if (AI.ahead && creature->Mood != MoodType::Escape && - TestProbability(0.004f)) + TestProbability(RAPTOR_ROAR_CHANCE)) { item->Animation.TargetState = RAPTOR_STATE_IDLE; item->Animation.RequiredState = RAPTOR_STATE_ROAR; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp index 404fbaf58..cadb2a7bd 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp @@ -18,11 +18,9 @@ using std::vector; namespace TEN::Entities::TR3 { constexpr auto TIGER_ATTACK_DAMAGE = 90; - constexpr auto TIGER_BITE_ATTACK_RANGE = SQUARE(SECTOR(0.33f)); constexpr auto TIGER_POUNCE_ATTACK_RANGE = SQUARE(SECTOR(1)); constexpr auto TIGER_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); - constexpr auto TIGER_WALK_CHANCE = 0.035f; constexpr auto TIGER_ROAR_CHANCE = 0.003f; @@ -42,7 +40,7 @@ namespace TEN::Entities::TR3 // No state 4. TIGER_STATE_ROAR = 5, TIGER_STATE_BITE_ATTACK = 6, - TIGER_STATE_SWIPE_ATTACK = 7, + TIGER_STATE_RUN_SWIPE_ATTACK = 7, TIGER_STATE_POUNCE_ATTACK = 8 }; @@ -50,7 +48,7 @@ namespace TEN::Entities::TR3 { TIGER_ANIM_IDLE_TO_RUN_FORWARD = 0, TIGER_ANIM_BITE_ATTACK = 1, - TIGER_ANIM_SWIPE_ATTACK = 2, + TIGER_ANIM_RUN_SWIPE_ATTACK = 2, TIGER_ANIM_POUNCE_ATTACK_START = 3, TIGER_ANIM_ROAR = 4, TIGER_ANIM_RUN_FORWARD = 5, @@ -63,6 +61,11 @@ namespace TEN::Entities::TR3 TIGER_ANIM_POUNCE_ATTACK_END = 12 }; + enum TigerFlags + { + TIGER_FLAG_ATTACKING = (1 << 0) + }; + void TigerControl(short itemNumber) { if (!CreatureActive(itemNumber)) @@ -161,7 +164,7 @@ namespace TEN::Entities::TR3 if (LaraItem->Animation.Velocity.z == 0.0f) item->Animation.TargetState = TIGER_STATE_IDLE; else - item->Animation.TargetState = TIGER_STATE_SWIPE_ATTACK; + item->Animation.TargetState = TIGER_STATE_RUN_SWIPE_ATTACK; } else if (creature->Mood != MoodType::Attack && TestProbability(TIGER_ROAR_CHANCE)) { @@ -178,13 +181,13 @@ namespace TEN::Entities::TR3 break; case TIGER_STATE_BITE_ATTACK: - case TIGER_STATE_SWIPE_ATTACK: + case TIGER_STATE_RUN_SWIPE_ATTACK: case TIGER_STATE_POUNCE_ATTACK: if (!creature->Flags && item->TestBits(JointBitType::Touch, TigerAttackJoints)) { DoDamage(creature->Enemy, TIGER_ATTACK_DAMAGE); CreatureEffect(item, TigerBite, DoBloodSplat); - creature->Flags = 1; + creature->Flags = TIGER_FLAG_ATTACKING; } break; From 99086467de91036c4cc94598c23bcbfcf5414982 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 19 Aug 2022 16:49:27 +1000 Subject: [PATCH 012/106] Cleanup --- TombEngine/Objects/TR3/Entity/tr3_cobra.cpp | 3 +- TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 6 ++- TombEngine/Objects/TR3/Entity/tr3_tiger.cpp | 4 +- TombEngine/Objects/TR3/Entity/tr3_trex.cpp | 48 +++++++++++--------- 4 files changed, 35 insertions(+), 26 deletions(-) diff --git a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp index 899c40376..fdb3806ec 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp @@ -24,7 +24,6 @@ namespace TEN::Entities::TR3 constexpr auto COBRA_SLEEP_RANGE = SQUARE(SECTOR(2.5f)); constexpr auto PLAYER_DISTURB_VELOCITY = 15; - constexpr auto COBRA_SLEEP_FRAME = 45; const auto CobraBite = BiteInfo(Vector3::Zero, 13); @@ -65,9 +64,9 @@ namespace TEN::Entities::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; short tilt = 0; + short head = 0; if (item->HitPoints <= 0 && item->HitPoints != NOT_TARGETABLE) { diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index 5ec7ab18c..a74c292dc 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -19,9 +19,11 @@ using std::vector; namespace TEN::Entities::TR3 { constexpr auto RAPTOR_ATTACK_DAMAGE = 100; + constexpr auto RAPTOR_BITE_ATTACK_RANGE = SQUARE(585); constexpr auto RAPTOR_JUMP_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); constexpr auto RAPTOR_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); + constexpr auto RAPTOR_ROAR_CHANCE = 0.004f; constexpr auto RAPTOR_SWITCH_TARGET_CHANCE = 0.008f; @@ -79,10 +81,10 @@ namespace TEN::Entities::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; - short neck = 0; short angle = 0; short tilt = 0; + short head = 0; + short neck = 0; if (item->HitPoints <= 0) { diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp index cadb2a7bd..918e2729d 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp @@ -18,9 +18,11 @@ using std::vector; namespace TEN::Entities::TR3 { constexpr auto TIGER_ATTACK_DAMAGE = 90; + constexpr auto TIGER_BITE_ATTACK_RANGE = SQUARE(SECTOR(0.33f)); constexpr auto TIGER_POUNCE_ATTACK_RANGE = SQUARE(SECTOR(1)); constexpr auto TIGER_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); + constexpr auto TIGER_WALK_CHANCE = 0.035f; constexpr auto TIGER_ROAR_CHANCE = 0.003f; @@ -124,8 +126,8 @@ namespace TEN::Entities::TR3 item->Animation.TargetState = TIGER_STATE_BITE_ATTACK; else if (AI.bite && AI.distance < TIGER_POUNCE_ATTACK_RANGE) { - creature->MaxTurn = TIGER_POUNCE_ATTACK_TURN_RATE_MAX; item->Animation.TargetState = TIGER_STATE_POUNCE_ATTACK; + creature->MaxTurn = TIGER_POUNCE_ATTACK_TURN_RATE_MAX; } else if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp index d68260be4..256ee4738 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp @@ -17,10 +17,15 @@ using std::vector; namespace TEN::Entities::TR3 { + constexpr auto TREX_ROAR_CHANCE = 0.015f; + constexpr auto LARA_ANIM_TREX_DEATH_ANIM = 4; const vector TRexAttackJoints = { 12, 13 }; + #define TREX_WALK_TURN_RATE_MAX ANGLE(2.0f) + #define TREX_RUN_TURN_RATE_MAX ANGLE(4.0f) + enum TRexState { TREX_STATE_NONE = 0, @@ -57,8 +62,9 @@ namespace TEN::Entities::TR3 if (laraItem->RoomNumber != tRexItem->RoomNumber) ItemNewRoom(Lara.ItemNumber, tRexItem->RoomNumber); - laraItem->Pose.Position = tRexItem->Pose.Position; - laraItem->Pose.Orientation = Vector3Shrt(0, tRexItem->Pose.Orientation.y, 0); + laraItem->Pose = PHD_3DPOS( + tRexItem->Pose.Position, + Vector3Shrt(0, tRexItem->Pose.Orientation.y, 0)); laraItem->Animation.IsAirborne = false; laraItem->Animation.AnimNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex + LARA_ANIM_TREX_DEATH_ANIM; @@ -82,10 +88,10 @@ namespace TEN::Entities::TR3 return; auto* item = &g_Level.Items[itemNumber]; - auto* info = GetCreatureInfo(item); + auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; + short head = 0; if (item->HitPoints <= 0) { @@ -105,18 +111,18 @@ namespace TEN::Entities::TR3 GetCreatureMood(item, &AI, true); CreatureMood(item, &AI, true); - angle = CreatureTurn(item, info->MaxTurn); + angle = CreatureTurn(item, creature->MaxTurn); if (item->TouchBits) DoDamage(LaraItem, (item->Animation.ActiveState == TREX_STATE_RUN_FORWARD) ? 10 : 1); - info->Flags = (info->Mood != MoodType::Escape && !AI.ahead && AI.enemyFacing > -FRONT_ARC && AI.enemyFacing < FRONT_ARC); + 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.bite && !info->Flags) + AI.bite && !creature->Flags) { - info->Flags = 1; + creature->Flags = 1; } switch (item->Animation.ActiveState) @@ -126,7 +132,7 @@ namespace TEN::Entities::TR3 item->Animation.TargetState = item->Animation.RequiredState; else if (AI.distance < pow(1500, 2) && AI.bite) item->Animation.TargetState = TREX_STATE_ATTACK; - else if (info->Mood == MoodType::Bored || info->Flags) + else if (creature->Mood == MoodType::Bored || creature->Flags) item->Animation.TargetState = TREX_STATE_WALK_FORWARD; else item->Animation.TargetState = TREX_STATE_RUN_FORWARD; @@ -134,32 +140,32 @@ namespace TEN::Entities::TR3 break; case TREX_STATE_WALK_FORWARD: - info->MaxTurn = ANGLE(2.0f); + creature->MaxTurn = TREX_WALK_TURN_RATE_MAX; - if (info->Mood != MoodType::Bored || !info->Flags) + if (creature->Mood != MoodType::Bored || !creature->Flags) item->Animation.TargetState = TREX_STATE_IDLE; - else if (AI.ahead && TestProbability(0.015f)) + else if (AI.ahead && TestProbability(TREX_ROAR_CHANCE)) { - item->Animation.RequiredState = TREX_STATE_ROAR; item->Animation.TargetState = TREX_STATE_IDLE; + item->Animation.RequiredState = TREX_STATE_ROAR; } break; case TREX_STATE_RUN_FORWARD: - info->MaxTurn = ANGLE(4.0f); + creature->MaxTurn = TREX_RUN_TURN_RATE_MAX; if (AI.distance < pow(SECTOR(5), 2) && AI.bite) item->Animation.TargetState = TREX_STATE_IDLE; - else if (info->Flags) + else if (creature->Flags) item->Animation.TargetState = TREX_STATE_IDLE; - else if (info->Mood != MoodType::Escape && - AI.ahead && TestProbability(0.015f)) + else if (creature->Mood != MoodType::Escape && + AI.ahead && TestProbability(TREX_ROAR_CHANCE)) { - item->Animation.RequiredState = TREX_STATE_ROAR; item->Animation.TargetState = TREX_STATE_IDLE; + item->Animation.RequiredState = TREX_STATE_ROAR; } - else if (info->Mood == MoodType::Bored) + else if (creature->Mood == MoodType::Bored) item->Animation.TargetState = TREX_STATE_IDLE; break; @@ -178,8 +184,8 @@ namespace TEN::Entities::TR3 } } - CreatureJoint(item, 0, (short)(head * 2)); - info->JointRotation[1] = info->JointRotation[0]; + CreatureJoint(item, 0, head * 2); + creature->JointRotation[1] = creature->JointRotation[0]; CreatureAnimation(itemNumber, angle, 0); From 44e80f88f85d9604f4ae5dcc56bb0bfc64006dba Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 19 Aug 2022 22:42:16 +0100 Subject: [PATCH 013/106] Add mechanism for adding callbacks to be called before/after OnControlPhase --- TombEngine/Game/savegame.cpp | 28 ++++-- .../Scripting/Include/ScriptInterfaceGame.h | 3 + .../Scripting/Internal/ReservedScriptNames.h | 7 +- .../Internal/TEN/Logic/LogicHandler.cpp | 86 +++++++++++++++++++ .../Internal/TEN/Logic/LogicHandler.h | 36 +++----- .../Internal/TEN/Rotation/Rotation.cpp | 3 +- .../flatbuffers/ten_savegame_generated.h | 48 +++++++++-- .../Specific/savegame/schema/ten_savegame.fbs | 2 + 8 files changed, 175 insertions(+), 38 deletions(-) diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index a58985c66..377aab6bf 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -1026,16 +1026,9 @@ bool SaveGame::Save(int slot) alternatePendulumOffset = alternatePendulumInfo.Finish(); } - - std::vector> levelTableVec; - std::vector> levelStringVec2; - - //std::vector savedTables; - std::vector savedStrings; std::vector savedVars; g_GameScript->GetVariables(savedVars); - std::vector> varsVec; for (auto const& s : savedVars) @@ -1107,6 +1100,13 @@ bool SaveGame::Save(int slot) uvb.add_members(unionVec); auto unionVecOffset = uvb.Finish(); + std::vector callbackVecPreControl; + std::vector callbackVecPostControl; + g_GameScript->GetCallbackStrings(callbackVecPreControl, callbackVecPostControl); + + auto stringsCallbackPreControl = fbb.CreateVectorOfStrings(callbackVecPreControl); + auto stringsCallbackPostControl = fbb.CreateVectorOfStrings(callbackVecPostControl); + Save::SaveGameBuilder sgb{ fbb }; sgb.add_header(headerOffset); @@ -1150,6 +1150,8 @@ bool SaveGame::Save(int slot) } sgb.add_script_vars(unionVecOffset); + sgb.add_callbacks_pre_control(stringsCallbackPreControl); + sgb.add_callbacks_post_control(stringsCallbackPostControl); auto sg = sgb.Finish(); fbb.Finish(sg); @@ -1927,6 +1929,18 @@ bool SaveGame::Load(int slot) g_GameScript->SetVariables(loadedVars); + std::vector callbacksPreControlVec; + auto callbacksPreControlOffsetVec = s->callbacks_pre_control(); + for (auto const& s : *callbacksPreControlOffsetVec) + callbacksPreControlVec.push_back(s->str()); + + std::vector callbacksPostControlVec; + auto callbacksPostControlOffsetVec = s->callbacks_post_control(); + for (auto const& s : *callbacksPostControlOffsetVec) + callbacksPostControlVec.push_back(s->str()); + + g_GameScript->SetCallbackStrings(callbacksPreControlVec, callbacksPostControlVec); + return true; } diff --git a/TombEngine/Scripting/Include/ScriptInterfaceGame.h b/TombEngine/Scripting/Include/ScriptInterfaceGame.h index 33b7b3344..e49e5c80d 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceGame.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceGame.h @@ -41,6 +41,9 @@ public: virtual void GetVariables(std::vector & vars) = 0; virtual void SetVariables(std::vector const& vars) = 0; + + virtual void GetCallbackStrings(std::vector & preControl, std::vector & postControl) const = 0; + virtual void SetCallbackStrings(std::vector const & preControl, std::vector const & postControl) = 0; }; extern ScriptInterfaceGame* g_GameScript; diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h index ef99ae505..6ce0294ab 100644 --- a/TombEngine/Scripting/Internal/ReservedScriptNames.h +++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h @@ -19,6 +19,7 @@ static constexpr char ScriptReserved_SoundSource[] = "SoundSource"; static constexpr char ScriptReserved_AIObject[] = "AIObject"; static constexpr char ScriptReserved_DisplayString[] = "DisplayString"; static constexpr char ScriptReserved_Vec3[] = "Vec3"; +static constexpr char ScriptReserved_Rotation[] = "Rotation"; // Member functions static constexpr char ScriptReserved_New[] = "New"; @@ -92,8 +93,6 @@ static constexpr char ScriptReserved_SetTitleScreenImagePath[] = "SetTitleScreen static constexpr char ScriptReserved_SetFarView[] = "SetFarView"; static constexpr char ScriptReserved_SetSettings[] = "SetSettings"; static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations"; - -// Flow Functions static constexpr char ScriptReserved_SetStrings[] = "SetStrings"; static constexpr char ScriptReserved_GetString[] = "GetString"; static constexpr char ScriptReserved_SetLanguageNames[] = "SetLanguageNames"; @@ -129,6 +128,9 @@ static constexpr char ScriptReserved_ScreenToPercent[] = "ScreenToPercent"; static constexpr char ScriptReserved_PercentToScreen[] = "PercentToScreen"; static constexpr char ScriptReserved_HasLineOfSight[] = "HasLineOfSight"; +static constexpr char ScriptReserved_AddCallback[] = "AddCallback"; +static constexpr char ScriptReserved_RemoveCallback[] = "RemoveCallback"; + static constexpr char ScriptReserved_EmitParticle[] = "EmitParticle"; static constexpr char ScriptReserved_EmitLightningArc[] = "EmitLightningArc"; static constexpr char ScriptReserved_EmitShockwave[] = "EmitShockwave"; @@ -154,6 +156,7 @@ static constexpr char ScriptReserved_KeyClear[] = "KeyClear"; static constexpr char ScriptReserved_ObjID[] = "ObjID"; static constexpr char ScriptReserved_BlendID[] = "BlendID"; static constexpr char ScriptReserved_DisplayStringOption[] = "DisplayStringOption"; +static constexpr char ScriptReserved_CallbackPoint[] = "CallbackPoint"; static constexpr char ScriptReserved_LevelVars[] = "LevelVars"; static constexpr char ScriptReserved_GameVars[] = "GameVars"; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 9057db93e..5590508f8 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -17,6 +17,18 @@ Saving data, triggering functions, and callbacks for level-specific scripts. @pragma nostrip */ +enum class CallbackPoint +{ + PreControl, + PostControl, +}; + +static const std::unordered_map kCallbackPoints +{ + {"PreControlPhase", CallbackPoint::PreControl}, + {"PostControlPhase", CallbackPoint::PostControl}, +}; + void SetVariable(sol::table tab, sol::object key, sol::object value) { switch (value.get_type()) @@ -63,6 +75,16 @@ sol::object GetVariable(sol::table tab, sol::object key) LogicHandler::LogicHandler(sol::state* lua, sol::table & parent) : m_handler{ lua } { m_handler.GetState()->set_function("print", &LogicHandler::LogPrint, this); + + sol::table table_logic{ m_handler.GetState()->lua_state(), sol::create }; + + parent.set(ScriptReserved_Logic, table_logic); + + table_logic.set_function(ScriptReserved_AddCallback, &LogicHandler::AddCallback, this); + table_logic.set_function(ScriptReserved_RemoveCallback, &LogicHandler::RemoveCallback, this); + + m_handler.MakeReadOnlyTable(table_logic, ScriptReserved_CallbackPoint, kCallbackPoints); + ResetScripts(true); } @@ -71,6 +93,33 @@ void LogicHandler::ResetGameTables() MakeSpecialTable(m_handler.GetState(), ScriptReserved_GameVars, &GetVariable, &SetVariable); } +void LogicHandler::AddCallback(CallbackPoint point, std::string const & name) +{ + switch(point) + { + case CallbackPoint::PreControl: + m_callbacksPreControl.insert(name); + break; + + case CallbackPoint::PostControl: + m_callbacksPostControl.insert(name); + break; + } +} + +void LogicHandler::RemoveCallback(CallbackPoint point, std::string const & name) +{ + switch(point) + { + case CallbackPoint::PreControl: + m_callbacksPreControl.erase(name); + break; + + case CallbackPoint::PostControl: + m_callbacksPostControl.erase(name); + break; + } +} void LogicHandler::ResetLevelTables() { @@ -121,6 +170,9 @@ void LogicHandler::ResetScripts(bool clearGameVars) { FreeLevelScripts(); + m_callbacksPreControl.clear(); + m_callbacksPostControl.clear(); + auto currentPackage = m_handler.GetState()->get("package"); auto currentLoaded = currentPackage.get("loaded"); @@ -347,6 +399,24 @@ void LogicHandler::GetVariables(std::vector & vars) populate(tab); } +void LogicHandler::GetCallbackStrings(std::vector& preControl, std::vector& postControl) const +{ + for (auto const& s : m_callbacksPreControl) + preControl.push_back(s); + + for (auto const& s : m_callbacksPostControl) + postControl.push_back(s); +} + +void LogicHandler::SetCallbackStrings(std::vector const & preControl, std::vector const & postControl) +{ + for (auto const& s : preControl) + m_callbacksPreControl.insert(s); + + for (auto const& s : postControl) + m_callbacksPostControl.insert(s); +} + template std::unique_ptr GetByName(std::string const & type, std::string const & name, mapType const & map) { @@ -428,9 +498,25 @@ void LogicHandler::OnLoad() void LogicHandler::OnControlPhase(float dt) { + sol::table levelFuncs = (*m_handler.GetState())[ScriptReserved_LevelFuncs]; + + auto tryCall = [dt, &levelFuncs](std::string const& name) + { + if (!levelFuncs[name].valid()) + ScriptAssertF(false, "Callback {} not valid", name); + else + levelFuncs[name].call(dt); + }; + + for (auto& name : m_callbacksPreControl) + tryCall(name); + lua_gc(m_handler.GetState()->lua_state(), LUA_GCCOLLECT, 0); if(m_onControlPhase.valid()) doCallback(m_onControlPhase, dt); + + for (auto& name : m_callbacksPostControl) + tryCall(name); } void LogicHandler::OnSave() diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index db58965f6..498102f1c 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -5,28 +5,7 @@ #include #include "Strings/StringsHandler.h" -struct LuaFunction { - std::string Name; - std::string Code; - bool Executed; -}; - -struct GameScriptVector3 { - float x; - float y; - float z; -}; - -struct LuaVariable -{ - bool IsGlobal; - std::string Name; - int Type; - float FloatValue; - int IntValue; - std::string StringValue; - bool BoolValue; -}; +enum class CallbackPoint; class LogicHandler : public ScriptInterfaceGame { @@ -38,6 +17,9 @@ private: sol::protected_function m_onSave{}; sol::protected_function m_onEnd{}; + std::unordered_set m_callbacksPreControl; + std::unordered_set m_callbacksPostControl; + void ResetLevelTables(); void ResetGameTables(); LuaHandler m_handler; @@ -49,6 +31,10 @@ public: void LogPrint(sol::variadic_args va); bool SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value); + + void AddCallback(CallbackPoint point, std::string const& name); + void RemoveCallback(CallbackPoint point, std::string const & name); + void ResetScripts(bool clearGameVars) override; sol::protected_function GetLevelFunc(sol::table tab, std::string const& luaName); @@ -59,13 +45,17 @@ public: void ExecuteFunction(std::string const& name, short idOne, short idTwo) override; void GetVariables(std::vector& vars) override; + void SetVariables(std::vector const& vars) override; void ResetVariables(); - void SetVariables(std::vector const& vars) override; + void SetCallbackStrings(std::vector const& preControl, std::vector const& postControl) override; + void GetCallbackStrings(std::vector& preControl, std::vector& postControl) const override; + void InitCallbacks() override; void OnStart() override; void OnLoad() override; void OnControlPhase(float dt) override; void OnSave() override; void OnEnd() override; + }; diff --git a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp index 88f796cb4..479e9c9f1 100644 --- a/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp +++ b/TombEngine/Scripting/Internal/TEN/Rotation/Rotation.cpp @@ -1,5 +1,6 @@ #include "framework.h" #include "Rotation.h" +#include "ReservedScriptNames.h" #include "Specific/phd_global.h" /*** Represents a rotation. @@ -13,7 +14,7 @@ All values will be clamped to [-32768, 32767]. void Rotation::Register(sol::table & parent) { using ctors = sol::constructors; - parent.new_usertype("Rotation", + parent.new_usertype(ScriptReserved_Rotation, ctors(), sol::call_constructor, ctors(), sol::meta_function::to_string, &Rotation::ToString, diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index a3ce470cc..9d157a5a0 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h @@ -5849,6 +5849,8 @@ struct SaveGameT : public flatbuffers::NativeTable { std::vector> volume_states{}; std::vector> call_counters{}; std::unique_ptr script_vars{}; + std::vector callbacks_pre_control{}; + std::vector callbacks_post_control{}; }; struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { @@ -5891,7 +5893,9 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { VT_ALTERNATE_PENDULUM = 68, VT_VOLUME_STATES = 70, VT_CALL_COUNTERS = 72, - VT_SCRIPT_VARS = 74 + VT_SCRIPT_VARS = 74, + VT_CALLBACKS_PRE_CONTROL = 76, + VT_CALLBACKS_POST_CONTROL = 78 }; const TEN::Save::SaveGameHeader *header() const { return GetPointer(VT_HEADER); @@ -6001,6 +6005,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const TEN::Save::UnionVec *script_vars() const { return GetPointer(VT_SCRIPT_VARS); } + const flatbuffers::Vector> *callbacks_pre_control() const { + return GetPointer> *>(VT_CALLBACKS_PRE_CONTROL); + } + const flatbuffers::Vector> *callbacks_post_control() const { + return GetPointer> *>(VT_CALLBACKS_POST_CONTROL); + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyOffset(verifier, VT_HEADER) && @@ -6079,6 +6089,12 @@ struct SaveGame FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { verifier.VerifyVectorOfTables(call_counters()) && VerifyOffset(verifier, VT_SCRIPT_VARS) && verifier.VerifyTable(script_vars()) && + VerifyOffset(verifier, VT_CALLBACKS_PRE_CONTROL) && + verifier.VerifyVector(callbacks_pre_control()) && + verifier.VerifyVectorOfStrings(callbacks_pre_control()) && + VerifyOffset(verifier, VT_CALLBACKS_POST_CONTROL) && + verifier.VerifyVector(callbacks_post_control()) && + verifier.VerifyVectorOfStrings(callbacks_post_control()) && verifier.EndTable(); } SaveGameT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; @@ -6198,6 +6214,12 @@ struct SaveGameBuilder { void add_script_vars(flatbuffers::Offset script_vars) { fbb_.AddOffset(SaveGame::VT_SCRIPT_VARS, script_vars); } + void add_callbacks_pre_control(flatbuffers::Offset>> callbacks_pre_control) { + fbb_.AddOffset(SaveGame::VT_CALLBACKS_PRE_CONTROL, callbacks_pre_control); + } + void add_callbacks_post_control(flatbuffers::Offset>> callbacks_post_control) { + fbb_.AddOffset(SaveGame::VT_CALLBACKS_POST_CONTROL, callbacks_post_control); + } explicit SaveGameBuilder(flatbuffers::FlatBufferBuilder &_fbb) : fbb_(_fbb) { start_ = fbb_.StartTable(); @@ -6246,10 +6268,14 @@ inline flatbuffers::Offset CreateSaveGame( flatbuffers::Offset alternate_pendulum = 0, flatbuffers::Offset>> volume_states = 0, flatbuffers::Offset>> call_counters = 0, - flatbuffers::Offset script_vars = 0) { + flatbuffers::Offset script_vars = 0, + flatbuffers::Offset>> callbacks_pre_control = 0, + flatbuffers::Offset>> callbacks_post_control = 0) { SaveGameBuilder builder_(_fbb); 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_script_vars(script_vars); builder_.add_call_counters(call_counters); builder_.add_volume_states(volume_states); @@ -6329,7 +6355,9 @@ inline flatbuffers::Offset CreateSaveGameDirect( flatbuffers::Offset alternate_pendulum = 0, const std::vector> *volume_states = nullptr, const std::vector> *call_counters = nullptr, - flatbuffers::Offset script_vars = 0) { + flatbuffers::Offset script_vars = 0, + const std::vector> *callbacks_pre_control = nullptr, + const std::vector> *callbacks_post_control = nullptr) { auto items__ = items ? _fbb.CreateVector>(*items) : 0; auto room_items__ = room_items ? _fbb.CreateVector(*room_items) : 0; auto fxinfos__ = fxinfos ? _fbb.CreateVector>(*fxinfos) : 0; @@ -6349,6 +6377,8 @@ inline flatbuffers::Offset CreateSaveGameDirect( auto cd_flags__ = cd_flags ? _fbb.CreateVector(*cd_flags) : 0; auto volume_states__ = volume_states ? _fbb.CreateVector>(*volume_states) : 0; auto call_counters__ = call_counters ? _fbb.CreateVector>(*call_counters) : 0; + auto callbacks_pre_control__ = callbacks_pre_control ? _fbb.CreateVector>(*callbacks_pre_control) : 0; + auto callbacks_post_control__ = callbacks_post_control ? _fbb.CreateVector>(*callbacks_post_control) : 0; return TEN::Save::CreateSaveGame( _fbb, header, @@ -6386,7 +6416,9 @@ inline flatbuffers::Offset CreateSaveGameDirect( alternate_pendulum, volume_states__, call_counters__, - script_vars); + script_vars, + callbacks_pre_control__, + callbacks_post_control__); } flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuilder &_fbb, const SaveGameT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); @@ -8117,6 +8149,8 @@ inline void SaveGame::UnPackTo(SaveGameT *_o, const flatbuffers::resolver_functi { auto _e = volume_states(); if (_e) { _o->volume_states.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->volume_states[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = call_counters(); if (_e) { _o->call_counters.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->call_counters[_i] = std::unique_ptr(_e->Get(_i)->UnPack(_resolver)); } } } { auto _e = script_vars(); if (_e) _o->script_vars = std::unique_ptr(_e->UnPack(_resolver)); } + { auto _e = callbacks_pre_control(); if (_e) { _o->callbacks_pre_control.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->callbacks_pre_control[_i] = _e->Get(_i)->str(); } } } + { auto _e = callbacks_post_control(); if (_e) { _o->callbacks_post_control.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->callbacks_post_control[_i] = _e->Get(_i)->str(); } } } } inline flatbuffers::Offset SaveGame::Pack(flatbuffers::FlatBufferBuilder &_fbb, const SaveGameT* _o, const flatbuffers::rehasher_function_t *_rehasher) { @@ -8163,6 +8197,8 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild auto _volume_states = _fbb.CreateVector> (_o->volume_states.size(), [](size_t i, _VectorArgs *__va) { return CreateVolumeState(*__va->__fbb, __va->__o->volume_states[i].get(), __va->__rehasher); }, &_va ); auto _call_counters = _fbb.CreateVector> (_o->call_counters.size(), [](size_t i, _VectorArgs *__va) { return CreateEventSetCallCounters(*__va->__fbb, __va->__o->call_counters[i].get(), __va->__rehasher); }, &_va ); auto _script_vars = _o->script_vars ? CreateUnionVec(_fbb, _o->script_vars.get(), _rehasher) : 0; + auto _callbacks_pre_control = _fbb.CreateVectorOfStrings(_o->callbacks_pre_control); + auto _callbacks_post_control = _fbb.CreateVectorOfStrings(_o->callbacks_post_control); return TEN::Save::CreateSaveGame( _fbb, _header, @@ -8200,7 +8236,9 @@ inline flatbuffers::Offset CreateSaveGame(flatbuffers::FlatBufferBuild _alternate_pendulum, _volume_states, _call_counters, - _script_vars); + _script_vars, + _callbacks_pre_control, + _callbacks_post_control); } inline bool VerifyVarUnion(flatbuffers::Verifier &verifier, const void *obj, VarUnion type) { diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs index 2e1d13b31..f5f467269 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -458,6 +458,8 @@ table SaveGame { volume_states: [VolumeState]; call_counters: [EventSetCallCounters]; script_vars: UnionVec; + callbacks_pre_control: [string]; + callbacks_post_control: [string]; } root_type TEN.Save.SaveGame; From 0f8bc8676855bff38742931f1c85d5b11ec00045 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 19 Aug 2022 23:18:03 +0100 Subject: [PATCH 014/106] Add documentation. Put constants in caps for consistency. --- Documentation/doc/1 modules/Logic.html | 83 +++++++++++++++++++ .../Internal/TEN/Logic/LogicHandler.cpp | 28 ++++++- 2 files changed, 109 insertions(+), 2 deletions(-) diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index 75f3dbfed..9c1deb41d 100644 --- a/Documentation/doc/1 modules/Logic.html +++ b/Documentation/doc/1 modules/Logic.html @@ -32,6 +32,7 @@

Contents

@@ -94,6 +95,17 @@

+

Functions

+ + + + + + + + + +
AddCallback(CallbackPoint, string)Register a function as a callback.
RemoveCallback(CallbackPoint, string)Deregister a function as a callback.

Special objects

@@ -121,6 +133,77 @@
+

Functions

+ +
+
+ + AddCallback(CallbackPoint, string) +
+
+ Register a function as a callback. +Possible values for CallbackPoint:

+
PRECONTROLPHASE -- will be called immediately before OnControlPhase
+POSTCONTROLPHASE -- will be called immediately after OnControlPhase
+
+ +

The order in which two functions with the same CallbackPoint are called is undefined. +i.e. if you register MyFunc and MyFunc2 with PRECONTROLPHASE, both will be called before OnControlPhase, but there is no guarantee whether MyFunc will be called before MyFunc2, or vice-versa. + + +

Parameters:

+
    +
  • CallbackPoint + point + When should the callback be called? +
  • +
  • string + func + The LevelFuncs function to be called. Will receive as an argument the time in seconds since the last frame. +
  • +
+ + + + +

Usage:

+
    +
    LevelFuncs.MyFunc = function(dt) print(dt) end
    +TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc")
    +
+ +
+
+ + RemoveCallback(CallbackPoint, string) +
+
+ Deregister a function as a callback. +Will have no effect if the function was not registered as a callback + + +

Parameters:

+
    +
  • CallbackPoint + point + The callback point the function was registered with. See AddCallback +
  • +
  • string + func + The LevelFuncs function to remove. +
  • +
+ + + + +

Usage:

+
    +
    TEN.Logic.RemoveCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc")
    +
+ +
+

Special objects

diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 5590508f8..c1d2ec656 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -25,8 +25,8 @@ enum class CallbackPoint static const std::unordered_map kCallbackPoints { - {"PreControlPhase", CallbackPoint::PreControl}, - {"PostControlPhase", CallbackPoint::PostControl}, + {"PRECONTROLPHASE", CallbackPoint::PreControl}, + {"POSTCONTROLPHASE", CallbackPoint::PostControl}, }; void SetVariable(sol::table tab, sol::object key, sol::object value) @@ -93,6 +93,21 @@ void LogicHandler::ResetGameTables() MakeSpecialTable(m_handler.GetState(), ScriptReserved_GameVars, &GetVariable, &SetVariable); } +/*** Register a function as a callback. +Possible values for CallbackPoint: + PRECONTROLPHASE -- will be called immediately before OnControlPhase + POSTCONTROLPHASE -- will be called immediately after OnControlPhase + +The order in which two functions with the same CallbackPoint are called is undefined. +i.e. if you register `MyFunc` and `MyFunc2` with `PRECONTROLPHASE`, both will be called before `OnControlPhase`, but there is no guarantee whether `MyFunc` will be called before `MyFunc2`, or vice-versa. + +@function AddCallback +@tparam point CallbackPoint When should the callback be called? +@tparam func string The LevelFuncs function to be called. Will receive as an argument the time in seconds since the last frame. +@usage + LevelFuncs.MyFunc = function(dt) print(dt) end + TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") +*/ void LogicHandler::AddCallback(CallbackPoint point, std::string const & name) { switch(point) @@ -107,6 +122,15 @@ void LogicHandler::AddCallback(CallbackPoint point, std::string const & name) } } +/*** Deregister a function as a callback. +Will have no effect if the function was not registered as a callback + +@function RemoveCallback +@tparam point CallbackPoint The callback point the function was registered with. See @{AddCallback} +@tparam func string The LevelFuncs function to remove. +@usage + TEN.Logic.RemoveCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") +*/ void LogicHandler::RemoveCallback(CallbackPoint point, std::string const & name) { switch(point) From 267b05c91f9a0a3ef6aaa19b9e576f94463eec2a Mon Sep 17 00:00:00 2001 From: hispidence Date: Sat, 20 Aug 2022 14:23:07 +0100 Subject: [PATCH 015/106] Allow Vec3s to be saved and loaded in LevelVars and GameVars --- TombEngine/Game/savegame.cpp | 60 ++++---- .../Scripting/Include/ScriptInterfaceGame.h | 2 +- .../Internal/TEN/Logic/LogicHandler.cpp | 71 ++++++--- .../TEN/Objects/Moveable/MoveableObject.cpp | 2 - .../Scripting/Internal/TEN/Vec3/Vec3.cpp | 9 ++ TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h | 5 + .../flatbuffers/ten_savegame_generated.h | 141 +++++++++++++++++- .../Specific/savegame/schema/ten_savegame.fbs | 7 +- 8 files changed, 240 insertions(+), 57 deletions(-) diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index 377aab6bf..6ee4de384 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -1033,29 +1033,38 @@ bool SaveGame::Save(int slot) std::vector> varsVec; for (auto const& s : savedVars) { - flatbuffers::Offset scriptTableOffset; - flatbuffers::Offset strOffset; - flatbuffers::Offset doubleOffset; - flatbuffers::Offset boolOffset; + auto putDataInVec = [&varsVec, &fbb](Save::VarUnion type, auto const & offsetVar) + { + Save::UnionTableBuilder ut{ fbb }; + ut.add_u_type(type); + ut.add_u(offsetVar.Union()); + varsVec.push_back(ut.Finish()); + }; if (std::holds_alternative(s)) { auto strOffset2 = fbb.CreateString(std::get(s)); Save::stringTableBuilder stb{ fbb }; stb.add_str(strOffset2); - strOffset = stb.Finish(); + auto strOffset = stb.Finish(); + + putDataInVec(Save::VarUnion::str, strOffset); } else if (std::holds_alternative(s)) { Save::doubleTableBuilder dtb{ fbb }; dtb.add_scalar(std::get(s)); - doubleOffset = dtb.Finish(); + auto doubleOffset = dtb.Finish(); + + putDataInVec(Save::VarUnion::num, doubleOffset); } else if (std::holds_alternative(s)) { Save::boolTableBuilder btb{ fbb }; btb.add_scalar(std::get(s)); - boolOffset = btb.Finish(); + auto boolOffset = btb.Finish(); + + putDataInVec(Save::VarUnion::boolean, boolOffset); } else if (std::holds_alternative(s)) { @@ -1069,31 +1078,20 @@ bool SaveGame::Save(int slot) auto vecOffset = fbb.CreateVectorOfStructs(keyValVec); Save::ScriptTableBuilder stb{ fbb }; stb.add_keys_vals(vecOffset); - scriptTableOffset = stb.Finish(); - } + auto scriptTableOffset = stb.Finish(); - Save::UnionTableBuilder ut{ fbb }; - if (std::holds_alternative(s)) - { - ut.add_u_type(Save::VarUnion::str); - ut.add_u(strOffset.Union()); + putDataInVec(Save::VarUnion::tab, scriptTableOffset); } - else if (std::holds_alternative(s)) + else if (std::holds_alternative(s)) { - ut.add_u_type(Save::VarUnion::num); - ut.add_u(doubleOffset.Union()); + Save::vec3TableBuilder vtb{ fbb }; + Vector3Int data = std::get(s); + Save::Vector3 saveVec = FromVector3(std::get(s)); + vtb.add_vec(&saveVec); + auto vec3Offset = vtb.Finish(); + + putDataInVec(Save::VarUnion::vec3, vec3Offset); } - else if (std::holds_alternative(s)) - { - ut.add_u_type(Save::VarUnion::boolean); - ut.add_u(boolOffset.Union()); - } - else if (std::holds_alternative(s)) - { - ut.add_u_type(Save::VarUnion::tab); - ut.add_u(scriptTableOffset.Union()); - } - varsVec.push_back(ut.Finish()); } auto unionVec = fbb.CreateVector(varsVec); Save::UnionVecBuilder uvb{ fbb }; @@ -1918,12 +1916,16 @@ bool SaveGame::Load(int slot) { auto tab = var->u_as_tab()->keys_vals(); auto& loadedTab = loadedVars.emplace_back(IndexTable{}); - + for (auto const& p : *tab) { std::get(loadedTab).push_back(std::make_pair(p->key(), p->val())); } } + else if (var->u_type() == Save::VarUnion::vec3) + { + loadedVars.push_back(ToVector3Int(var->u_as_vec3()->vec())); + } } } diff --git a/TombEngine/Scripting/Include/ScriptInterfaceGame.h b/TombEngine/Scripting/Include/ScriptInterfaceGame.h index e49e5c80d..7c4c087a2 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceGame.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceGame.h @@ -19,7 +19,7 @@ using VarSaveType = std::variant; using IndexTable = std::vector>; -using SavedVar = std::variant; +using SavedVar = std::variant; class ScriptInterfaceGame { public: diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index c1d2ec656..e51798363 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -8,6 +8,7 @@ #include "Game/effects/lightning.h" #include "ScriptUtil.h" #include "Objects/Moveable/MoveableObject.h" +#include "Vec3/Vec3.h" using namespace TEN::Effects::Lightning; @@ -290,6 +291,11 @@ void LogicHandler::SetVariables(std::vector const & vars) solTables[i][vars[first]] = vars[second]; } } + else if (std::holds_alternative(vars[second])) + { + auto theVec = Vec3{ std::get(vars[second]) }; + solTables[i][vars[first]] = theVec; + } else { solTables[i][vars[first]] = vars[second]; @@ -322,12 +328,20 @@ void LogicHandler::GetVariables(std::vector & vars) std::unordered_map varsMap; std::unordered_map numMap; std::unordered_map boolMap; - size_t nVars = 0; - auto handleNum = [&](double num) - { - auto [first, second] = numMap.insert(std::pair(num, nVars)); - // true if the var was inserted + size_t nVars = 0; + + // The following functions will all try to put their values in a map. If it succeeds + // then the value was not already in the map, so we can put it into the var vector. + // If it fails, the value is in the map, and thus will also be in the var vector. + // We then return the value's position in the var vector. + + // The purpose of this is to only store each value once, and to fill our tables with + // indices to the values rather than copies of the values. + auto handleNum = [&](double num) + { + auto [first, second] = numMap.insert(std::make_pair(num, nVars)); + if (second) { vars.push_back(num); @@ -339,9 +353,8 @@ void LogicHandler::GetVariables(std::vector & vars) auto handleBool = [&](bool num) { - auto [first, second] = boolMap.insert(std::pair(num, nVars)); + auto [first, second] = boolMap.insert(std::make_pair(num, nVars)); - // true if the var was inserted if (second) { vars.push_back(num); @@ -354,9 +367,8 @@ void LogicHandler::GetVariables(std::vector & vars) auto handleStr = [&](sol::object const& obj) { auto str = obj.as(); - auto [first, second] = varsMap.insert(std::pair(str.data(), nVars)); + auto [first, second] = varsMap.insert(std::make_pair(str.data(), nVars)); - // true if the string was inserted if (second) { vars.push_back(std::string{ str.data() }); @@ -366,11 +378,23 @@ void LogicHandler::GetVariables(std::vector & vars) return first->second; }; + auto handleVec3 = [&](Vec3 const & vec) + { + auto [first, second] = varsMap.insert(std::make_pair(&vec, nVars)); + + if (second) + { + vars.push_back(vec); + ++nVars; + } + + return first->second; + }; + std::function populate = [&](sol::table const & obj) { - auto [first, second] = varsMap.insert(std::pair(obj.pointer(), nVars)); + auto [first, second] = varsMap.insert(std::make_pair(obj.pointer(), nVars)); - // true if the table was inserted if(second) { ++nVars; @@ -394,24 +418,33 @@ void LogicHandler::GetVariables(std::vector & vars) ScriptAssert(false, "Tried saving an unsupported type as a key"); } + auto putInVars = [&vars, id, keyIndex](uint32_t valIndex) + { + std::get(vars[id]).push_back(std::make_pair(keyIndex, valIndex)); + }; + uint32_t valIndex = 0; switch (second.get_type()) { case sol::type::table: - valIndex = populate(second.as()); - std::get(vars[id]).push_back(std::make_pair(keyIndex, valIndex)); + putInVars(populate(second.as())); break; case sol::type::string: - valIndex = handleStr(second); - std::get(vars[id]).push_back(std::make_pair(keyIndex, valIndex)); + putInVars(handleStr(second)); break; case sol::type::number: - valIndex = handleNum(second.as()); - std::get(vars[id]).push_back(std::make_pair(keyIndex, valIndex)); + putInVars(handleNum(second.as())); break; case sol::type::boolean: - valIndex = handleBool(second.as()); - std::get(vars[id]).push_back(std::make_pair(keyIndex, valIndex)); + putInVars(handleBool(second.as())); + break; + case sol::type::userdata: + { + if(second.is()) + putInVars(handleVec3(second.as())); + else + ScriptAssert(false, "Tried saving an unsupported userdata as a value"); + } break; default: ScriptAssert(false, "Tried saving an unsupported type as a value"); diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index f2354ea10..8edc6cb58 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -89,8 +89,6 @@ most can just be ignored (see usage). 0, -- room ) */ - - static std::unique_ptr Create( GAME_OBJECT_ID objID, std::string const & name, diff --git a/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.cpp b/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.cpp index 5c7de764f..c435f8dd7 100644 --- a/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.cpp +++ b/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.cpp @@ -63,6 +63,15 @@ Vec3::Vec3(PHD_3DPOS const& pos) : x{pos.Position.x}, y{pos.Position.y}, z{pos.P { } +Vec3::Vec3(Vector3Int const& pos) : x{pos.x}, y{pos.y}, z{pos.z} +{ +} + +Vec3::operator Vector3Int() const +{ + return Vector3Int{ x, y, z }; +}; + void Vec3::StoreInPHDPos(PHD_3DPOS& pos) const { pos.Position.x = x; diff --git a/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h b/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h index 0d51b62a9..4713b3cff 100644 --- a/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h +++ b/TombEngine/Scripting/Internal/TEN/Vec3/Vec3.h @@ -1,5 +1,7 @@ #pragma once +struct Vector3Int; + namespace sol { class state; } @@ -15,6 +17,9 @@ public: Vec3(int x, int y, int z); Vec3(PHD_3DPOS const& pos); + Vec3(Vector3Int const& pos); + + operator Vector3Int() const; [[nodiscard]] std::string ToString() const; diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index 9d157a5a0..ad9d4a229 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h @@ -139,6 +139,10 @@ struct boolTable; struct boolTableBuilder; struct boolTableT; +struct vec3Table; +struct vec3TableBuilder; +struct vec3TableT; + struct UnionTable; struct UnionTableBuilder; struct UnionTableT; @@ -201,35 +205,38 @@ enum class VarUnion : uint8_t { tab = 2, num = 3, boolean = 4, + vec3 = 5, MIN = NONE, - MAX = boolean + MAX = vec3 }; -inline const VarUnion (&EnumValuesVarUnion())[5] { +inline const VarUnion (&EnumValuesVarUnion())[6] { static const VarUnion values[] = { VarUnion::NONE, VarUnion::str, VarUnion::tab, VarUnion::num, - VarUnion::boolean + VarUnion::boolean, + VarUnion::vec3 }; return values; } inline const char * const *EnumNamesVarUnion() { - static const char * const names[6] = { + static const char * const names[7] = { "NONE", "str", "tab", "num", "boolean", + "vec3", nullptr }; return names; } inline const char *EnumNameVarUnion(VarUnion e) { - if (flatbuffers::IsOutRange(e, VarUnion::NONE, VarUnion::boolean)) return ""; + if (flatbuffers::IsOutRange(e, VarUnion::NONE, VarUnion::vec3)) return ""; const size_t index = static_cast(e); return EnumNamesVarUnion()[index]; } @@ -254,6 +261,10 @@ template<> struct VarUnionTraits { static const VarUnion enum_value = VarUnion::boolean; }; +template<> struct VarUnionTraits { + static const VarUnion enum_value = VarUnion::vec3; +}; + struct VarUnionUnion { VarUnion type; void *value; @@ -318,6 +329,14 @@ struct VarUnionUnion { return type == VarUnion::boolean ? reinterpret_cast(value) : nullptr; } + TEN::Save::vec3TableT *Asvec3() { + return type == VarUnion::vec3 ? + reinterpret_cast(value) : nullptr; + } + const TEN::Save::vec3TableT *Asvec3() const { + return type == VarUnion::vec3 ? + reinterpret_cast(value) : nullptr; + } }; bool VerifyVarUnion(flatbuffers::Verifier &verifier, const void *obj, VarUnion type); @@ -5361,6 +5380,64 @@ struct boolTable::Traits { flatbuffers::Offset CreateboolTable(flatbuffers::FlatBufferBuilder &_fbb, const boolTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct vec3TableT : public flatbuffers::NativeTable { + typedef vec3Table TableType; + std::unique_ptr vec{}; +}; + +struct vec3Table FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef vec3TableT NativeTableType; + typedef vec3TableBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_VEC = 4 + }; + const TEN::Save::Vector3 *vec() const { + return GetStruct(VT_VEC); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyField(verifier, VT_VEC) && + verifier.EndTable(); + } + vec3TableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(vec3TableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const vec3TableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct vec3TableBuilder { + typedef vec3Table Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_vec(const TEN::Save::Vector3 *vec) { + fbb_.AddStruct(vec3Table::VT_VEC, vec); + } + explicit vec3TableBuilder(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 Createvec3Table( + flatbuffers::FlatBufferBuilder &_fbb, + const TEN::Save::Vector3 *vec = 0) { + vec3TableBuilder builder_(_fbb); + builder_.add_vec(vec); + return builder_.Finish(); +} + +struct vec3Table::Traits { + using type = vec3Table; + static auto constexpr Create = Createvec3Table; +}; + +flatbuffers::Offset Createvec3Table(flatbuffers::FlatBufferBuilder &_fbb, const vec3TableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct UnionTableT : public flatbuffers::NativeTable { typedef UnionTable TableType; TEN::Save::VarUnionUnion u{}; @@ -5393,6 +5470,9 @@ struct UnionTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const TEN::Save::boolTable *u_as_boolean() const { return u_type() == TEN::Save::VarUnion::boolean ? static_cast(u()) : nullptr; } + const TEN::Save::vec3Table *u_as_vec3() const { + return u_type() == TEN::Save::VarUnion::vec3 ? static_cast(u()) : nullptr; + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_U_TYPE) && @@ -5421,6 +5501,10 @@ template<> inline const TEN::Save::boolTable *UnionTable::u_as inline const TEN::Save::vec3Table *UnionTable::u_as() const { + return u_as_vec3(); +} + struct UnionTableBuilder { typedef UnionTable Table; flatbuffers::FlatBufferBuilder &fbb_; @@ -7958,6 +8042,32 @@ inline flatbuffers::Offset CreateboolTable(flatbuffers::FlatBufferBui _scalar); } +inline vec3TableT *vec3Table::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::make_unique(); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void vec3Table::UnPackTo(vec3TableT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = vec(); if (_e) _o->vec = std::unique_ptr(new TEN::Save::Vector3(*_e)); } +} + +inline flatbuffers::Offset vec3Table::Pack(flatbuffers::FlatBufferBuilder &_fbb, const vec3TableT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return Createvec3Table(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset Createvec3Table(flatbuffers::FlatBufferBuilder &_fbb, const vec3TableT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const vec3TableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _vec = _o->vec ? _o->vec.get() : 0; + return TEN::Save::Createvec3Table( + _fbb, + _vec); +} + inline UnionTableT *UnionTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = std::make_unique(); UnPackTo(_o.get(), _resolver); @@ -8262,6 +8372,10 @@ inline bool VerifyVarUnion(flatbuffers::Verifier &verifier, const void *obj, Var auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } + case VarUnion::vec3: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } default: return true; } } @@ -8296,6 +8410,10 @@ inline void *VarUnionUnion::UnPack(const void *obj, VarUnion type, const flatbuf auto ptr = reinterpret_cast(obj); return ptr->UnPack(resolver); } + case VarUnion::vec3: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } default: return nullptr; } } @@ -8318,6 +8436,10 @@ inline flatbuffers::Offset VarUnionUnion::Pack(flatbuffers::FlatBufferBuil auto ptr = reinterpret_cast(value); return CreateboolTable(_fbb, ptr, _rehasher).Union(); } + case VarUnion::vec3: { + auto ptr = reinterpret_cast(value); + return Createvec3Table(_fbb, ptr, _rehasher).Union(); + } default: return 0; } } @@ -8340,6 +8462,10 @@ inline VarUnionUnion::VarUnionUnion(const VarUnionUnion &u) : type(u.type), valu value = new TEN::Save::boolTableT(*reinterpret_cast(u.value)); break; } + case VarUnion::vec3: { + FLATBUFFERS_ASSERT(false); // TEN::Save::vec3TableT not copyable. + break; + } default: break; } @@ -8367,6 +8493,11 @@ inline void VarUnionUnion::Reset() { delete ptr; break; } + case VarUnion::vec3: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } default: break; } value = nullptr; diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs index f5f467269..90e21696b 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -385,11 +385,16 @@ table boolTable { scalar: bool; } +table vec3Table { + vec: Vector3; +} + union VarUnion { str: stringTable, tab: ScriptTable, num: doubleTable, - boolean: boolTable + boolean: boolTable, + vec3: vec3Table } table UnionTable{ From fe8b5d0025c161e0f77edc2b2cab9ddde71bfc7b Mon Sep 17 00:00:00 2001 From: hispidence Date: Sat, 20 Aug 2022 17:05:25 +0100 Subject: [PATCH 016/106] Timer and EventSequence no longer require you to call Timer.UpdateAll --- .../5 lua utility modules/EventSequence.html | 8 ++--- .../doc/5 lua utility modules/Timer.html | 33 ++----------------- Scripts/EventSequence.lua | 8 ++--- Scripts/Timer.lua | 23 +++++++------ 4 files changed, 22 insertions(+), 50 deletions(-) diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index 4433f4d59..456664b91 100644 --- a/Documentation/doc/5 lua utility modules/EventSequence.html +++ b/Documentation/doc/5 lua utility modules/EventSequence.html @@ -90,6 +90,9 @@

Event sequence - a chain of functions to call at specified times, modeled after TRNG's organizers.

+ +

Works atop the Timer, and so is updated automatically pre-OnControlPhase, and saved automatically when the game is saved.

+

Example usage:

@@ -126,11 +129,6 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
     -- event sequences are inactive to begin with and so need to be started
     mySeq:Start()
 end
-
--- EventSequence runs on Timer, so this call is required
-LevelFuncs.OnControlPhase = function(dt)
-    Timer.UpdateAll(dt)
-end
 

diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index f9956d80e..493b98dee 100644 --- a/Documentation/doc/5 lua utility modules/Timer.html +++ b/Documentation/doc/5 lua utility modules/Timer.html @@ -90,6 +90,9 @@

Basic timer - after a specified number of seconds, the specified thing happens.

+ +

Timers are updated automatically every frame before OnControlPhase.

+

Example usage:

@@ -112,10 +115,6 @@
         "Well done!")
     myTimer:Start()
 end
-
-LevelFuncs.OnControlPhase = function(dt)
-    Timer.UpdateAll(dt)
-end
 

@@ -132,10 +131,6 @@ LevelFuncs.OnControlPhase = function(dt)
- - - - @@ -280,28 +275,6 @@ local myTimeFormat4 = {seconds = true} - -
- - UpdateAll(dt) -
-
- Update all active timers. - Should be called in LevelFuncs.OnControlPhase - - -

Parameters:

-
    -
  • dt - number - The time in seconds since the last frame -
  • -
- - - - -
diff --git a/Scripts/EventSequence.lua b/Scripts/EventSequence.lua index 6fde9d7bc..8e99b9257 100644 --- a/Scripts/EventSequence.lua +++ b/Scripts/EventSequence.lua @@ -1,5 +1,8 @@ ----- --- Event sequence - a chain of functions to call at specified times, modeled after TRNG's organizers. +-- +-- Works atop the Timer, and so is updated automatically pre-OnControlPhase, and saved automatically when the game is saved. +-- -- Example usage: -- local EventSequence = require("EventSequence") -- @@ -35,11 +38,6 @@ -- mySeq:Start() -- end -- --- -- EventSequence runs on Timer, so this call is required --- LevelFuncs.OnControlPhase = function(dt) --- Timer.UpdateAll(dt) --- end --- -- @luautil EventSequence local Timer = require("Timer") diff --git a/Scripts/Timer.lua b/Scripts/Timer.lua index 66567506e..99eb821cf 100644 --- a/Scripts/Timer.lua +++ b/Scripts/Timer.lua @@ -1,5 +1,8 @@ ----- --- Basic timer - after a specified number of seconds, the specified thing happens. +-- +-- Timers are updated automatically every frame before OnControlPhase. +-- -- Example usage: -- local Timer = require("Timer") -- @@ -21,10 +24,6 @@ -- myTimer:Start() -- end -- --- LevelFuncs.OnControlPhase = function(dt) --- Timer.UpdateAll(dt) --- end --- -- @luautil Timer LevelVars.__TEN_timer = {timers = {}} @@ -35,6 +34,7 @@ local unpausedColor = TEN.Color(255, 255, 255) local pausedColor = TEN.Color(255, 255, 0) local str = TEN.Strings.DisplayString("TIMER", 0, 0, unpausedColor, false, {TEN.Strings.DisplayStringOption.CENTER, TEN.Strings.DisplayStringOption.SHADOW} ) + Timer = { --- Create (but do not start) a new timer. -- @@ -190,13 +190,8 @@ Timer = { end end; - --- Update all active timers. - -- Should be called in LevelFuncs.OnControlPhase - -- @number dt The time in seconds since the last frame UpdateAll = function(dt) - for _, t in pairs(LevelVars.__TEN_timer.timers) do - Timer.Update(t, dt) - end + print("Timer.UpdateAll is deprecated; timers and event sequences now get updated automatically pre-control phase.") end; --- Give the timer a new function and args @@ -296,5 +291,13 @@ Timer = { end; } +LevelFuncs.__TEN_timer_updateAll = function(dt) + for _, t in pairs(LevelVars.__TEN_timer.timers) do + Timer.Update(t, dt) + end +end + +TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "__TEN_timer_updateAll") + return Timer From 412b6d2de8be285c29a90cd74aae415fa531f646 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 13:42:55 +1000 Subject: [PATCH 017/106] Demagic some entity TouchBits --- TombEngine/Objects/TR2/Entity/tr2_dragon.cpp | 49 ++++++-------------- TombEngine/Objects/TR2/Entity/tr2_yeti.cpp | 24 ++++++---- 2 files changed, 29 insertions(+), 44 deletions(-) diff --git a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp index 8bb783680..d8234d996 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp @@ -18,28 +18,23 @@ #include "Specific/setup.h" using namespace TEN::Input; +using std::vector; namespace TEN::Entities::TR2 { - const auto DragonMouthBite = BiteInfo(Vector3(35.0f, 171.0f, 1168.0f), 12); - constexpr auto DRAGON_SWIPE_ATTACK_DAMAGE = 250; - constexpr auto DRAGON_TOUCH_DAMAGE = 10; - + constexpr auto DRAGON_CONTACT_DAMAGE = 10; + const auto DragonMouthBite = BiteInfo(Vector3(35.0f, 171.0f, 1168.0f), 12); + const vector DragonSwipeAttackJointsLeft = { 24, 25, 26, 27, 28, 29, 30 }; + const vector DragonSwipeAttackJointsRight = { 1, 2, 3, 4, 5, 6, 7 }; // TODO: Organise. - #define DRAGON_SWIPE_DAMAGE 250 - #define DRAGON_TOUCH_DAMAGE 10 - #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_FLAME_SPEED 200 - #define DRAGON_TOUCH_R 0x0fe - #define DRAGON_TOUCH_L 0x7f000000 - #define DRAGON_ALMOST_LIVE 100 #define BOOM_TIME 130 #define BOOM_TIME_MIDDLE 140 @@ -255,8 +250,8 @@ namespace TEN::Entities::TR2 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; + short head = 0; bool ahead; @@ -318,9 +313,7 @@ namespace TEN::Entities::TR2 ahead = (AI.ahead && AI.distance > DRAGON_CLOSE_RANGE && AI.distance < DRAGON_STATE_IDLE_RANGE); if (item->TouchBits) - { - DoDamage(creature->Enemy, DRAGON_TOUCH_DAMAGE); - } + DoDamage(creature->Enemy, DRAGON_CONTACT_DAMAGE); switch (item->Animation.ActiveState) { @@ -350,19 +343,19 @@ namespace TEN::Entities::TR2 break; case DRAGON_STATE_SWIPE_LEFT: - if (item->TouchBits & DRAGON_TOUCH_L) + if (item->TestBits(JointBitType::Touch, DragonSwipeAttackJointsLeft)) { + DoDamage(creature->Enemy, DRAGON_SWIPE_ATTACK_DAMAGE); creature->Flags = 0; - DoDamage(creature->Enemy, DRAGON_SWIPE_DAMAGE); } break; case DRAGON_STATE_SWIPE_RIGHT: - if (item->TouchBits & DRAGON_TOUCH_R) + if (item->TestBits(JointBitType::Touch, DragonSwipeAttackJointsRight)) { + DoDamage(creature->Enemy, DRAGON_SWIPE_ATTACK_DAMAGE); creature->Flags = 0; - DoDamage(creature->Enemy, DRAGON_SWIPE_DAMAGE); } break; @@ -404,13 +397,11 @@ namespace TEN::Entities::TR2 case DRAGON_STATE_TURN_LEFT: item->Pose.Orientation.y += -(ANGLE(1.0f) - angle); creature->Flags = 0; - break; case DRAGON_STATE_TURN_RIGHT: item->Pose.Orientation.y += (ANGLE(1.0f) - angle); creature->Flags = 0; - break; case DRAGON_STATE_AIM_1: @@ -434,12 +425,11 @@ namespace TEN::Entities::TR2 case DRAGON_STATE_FIRE_1: item->Pose.Orientation.y -= angle; + SoundEffect(SFX_TR2_DRAGON_FIRE, &item->Pose); if (AI.ahead) head = -AI.angle; - SoundEffect(SFX_TR2_DRAGON_FIRE, &item->Pose); - if (creature->Flags) { if (AI.ahead) @@ -459,12 +449,7 @@ namespace TEN::Entities::TR2 back->Animation.ActiveState = item->Animation.ActiveState; back->Animation.AnimNumber = Objects[ID_DRAGON_BACK].animIndex + (item->Animation.AnimNumber - Objects[ID_DRAGON_FRONT].animIndex); back->Animation.FrameNumber = g_Level.Anims[back->Animation.AnimNumber].frameBase + (item->Animation.FrameNumber - g_Level.Anims[item->Animation.AnimNumber].frameBase); - back->Pose.Position.x = item->Pose.Position.x; - back->Pose.Position.y = item->Pose.Position.y; - back->Pose.Position.z = item->Pose.Position.z; - back->Pose.Orientation.x = item->Pose.Orientation.x; - back->Pose.Orientation.y = item->Pose.Orientation.y; - back->Pose.Orientation.z = item->Pose.Orientation.z; + back->Pose = item->Pose; if (back->RoomNumber != item->RoomNumber) ItemNewRoom(backItemNumber, item->RoomNumber); @@ -484,9 +469,7 @@ namespace TEN::Entities::TR2 { auto* back = &g_Level.Items[backItem]; back->ObjectNumber = ID_DRAGON_BACK; - back->Pose.Position.x = item->Pose.Position.x; - back->Pose.Position.y = item->Pose.Position.y; - back->Pose.Position.z = item->Pose.Position.z; + back->Pose.Position = item->Pose.Position; back->Pose.Orientation.y = item->Pose.Orientation.y; back->RoomNumber = item->RoomNumber; back->Status = ITEM_INVISIBLE; @@ -500,9 +483,7 @@ namespace TEN::Entities::TR2 auto* front = &g_Level.Items[frontItem]; front->ObjectNumber = ID_DRAGON_FRONT; - front->Pose.Position.x = item->Pose.Position.x; - front->Pose.Position.y = item->Pose.Position.y; - front->Pose.Position.z = item->Pose.Position.z; + front->Pose.Position = item->Pose.Position; front->Pose.Orientation.y = item->Pose.Orientation.y; front->RoomNumber = item->RoomNumber; front->Status = ITEM_INVISIBLE; diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp index 0a80c62bb..173ba1dd8 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp @@ -13,11 +13,14 @@ #include "Specific/setup.h" using namespace TEN::Math::Random; +using std::vector; namespace TEN::Entities::TR2 { - const auto YetiBiteLeft = BiteInfo(Vector3(12.0f, 101.0f, 19.0f), 13); + const auto YetiBiteLeft = BiteInfo(Vector3(12.0f, 101.0f, 19.0f), 13); const auto YetiBiteRight = BiteInfo(Vector3(12.0f, 101.0f, 19.0f), 10); + const vector YetiAttackJoints1 = { 10, 12 }; // TODO: Rename. + const vector YetiAttackJoints2 = { 8, 9, 10 }; // TODO enum YetiState @@ -50,9 +53,9 @@ namespace TEN::Entities::TR2 bool isLaraAlive = LaraItem->HitPoints > 0; short angle = 0; + short tilt = 0; short torso = 0; short head = 0; - short tilt = 0; if (item->HitPoints <= 0) { @@ -213,8 +216,7 @@ namespace TEN::Entities::TR2 if (AI.ahead) torso = AI.angle; - if (!info->Flags && - item->TouchBits & 0x1400) + if (!info->Flags && item->TestBits(JointBitType::Touch, YetiAttackJoints1)) { CreatureEffect(item, YetiBiteRight, DoBloodSplat); DoDamage(info->Enemy, 100); @@ -230,11 +232,12 @@ namespace TEN::Entities::TR2 torso = AI.angle; if (!info->Flags && - item->TouchBits & (0x0700 | 0x1400)) + (item->TestBits(JointBitType::Touch, YetiAttackJoints1) || item->TestBits(JointBitType::Touch, YetiAttackJoints2))) { - if (item->TouchBits & 0x0700) + if (item->TestBits(JointBitType::Touch, YetiAttackJoints2)) CreatureEffect(item, YetiBiteLeft, DoBloodSplat); - if (item->TouchBits & 0x1400) + + if (item->TestBits(JointBitType::Touch, YetiAttackJoints1)) CreatureEffect(item, YetiBiteRight, DoBloodSplat); DoDamage(info->Enemy, 150); @@ -248,11 +251,12 @@ namespace TEN::Entities::TR2 torso = AI.angle; if (!info->Flags && - item->TouchBits & (0x0700 | 0x1400)) + (item->TestBits(JointBitType::Touch, YetiAttackJoints1) || item->TestBits(JointBitType::Touch, YetiAttackJoints2))) { - if (item->TouchBits & 0x0700) + if (item->TestBits(JointBitType::Touch, YetiAttackJoints2)) CreatureEffect(item, YetiBiteLeft, DoBloodSplat); - if (item->TouchBits & 0x1400) + + if (item->TestBits(JointBitType::Touch, YetiAttackJoints1)) CreatureEffect(item, YetiBiteRight, DoBloodSplat); DoDamage(info->Enemy, 200); From 21865430af6544406cd44b3ffbf90deb455c3980 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 14:58:30 +1000 Subject: [PATCH 018/106] Cleanup --- TombEngine/Game/control/box.cpp | 2 +- .../Objects/TR5/Entity/tr5_doberman.cpp | 340 +++++++++--------- .../Objects/TR5/Entity/tr5_lagoon_witch.cpp | 31 +- TombEngine/Objects/TR5/Entity/tr5_larson.cpp | 61 ++-- TombEngine/Objects/TR5/Entity/tr5_lion.cpp | 4 +- .../Objects/TR5/Entity/tr5_submarine.cpp | 194 +++++----- .../Objects/TR5/Entity/tr5_willowwisp.cpp | 5 +- 7 files changed, 312 insertions(+), 325 deletions(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 5374e914d..8e7e99e0e 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -1084,7 +1084,7 @@ int CreatureActive(short itemNumber) if (item->Flags & IFLAG_KILLED) return false; // Object is already dead - if (item->Status == ITEM_INVISIBLE || !item->Data.is()) + if (item->Status == ITEM_INVISIBLE || !item->IsCreature()) { if (!EnableEntityAI(itemNumber, 0)) return false; // AI couldn't be activated diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp index 7c386d4bd..eb3e4543a 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp @@ -79,198 +79,198 @@ namespace TEN::Entities::TR5 void DobermanControl(short itemNumber) { - if (CreatureActive(itemNumber)) + auto* item = &g_Level.Items[itemNumber]; + auto* creature = GetCreatureInfo(item); + + if (!CreatureActive(itemNumber)) + return; + + short angle = 0; + short tilt = 0; + short joint = 0; + + if (item->HitPoints > 0) { - short angle = 0; - short tilt = 0; - short joint = 0; + AI_INFO AI; + CreatureAIInfo(item, &AI); - auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); + if (AI.ahead) + joint = AI.angle; - if (item->HitPoints > 0) + GetCreatureMood(item, &AI, false); + CreatureMood(item, &AI, false); + + angle = CreatureTurn(item, creature->MaxTurn); + + switch (item->Animation.ActiveState) { - AI_INFO AI; - CreatureAIInfo(item, &AI); + case DOBERMAN_STATE_WALK_FORWARD: + creature->MaxTurn = ANGLE(3.0f); - if (AI.ahead) - joint = AI.angle; - - GetCreatureMood(item, &AI, false); - CreatureMood(item, &AI, false); - - angle = CreatureTurn(item, creature->MaxTurn); - - switch (item->Animation.ActiveState) + if (creature->Mood != MoodType::Bored) + item->Animation.TargetState = DOBERMAN_STATE_RUN_FORWARD; + else { - case DOBERMAN_STATE_WALK_FORWARD: - creature->MaxTurn = ANGLE(3.0f); - - if (creature->Mood != MoodType::Bored) - item->Animation.TargetState = DOBERMAN_STATE_RUN_FORWARD; - else - { - if (TestProbability(0.025f)) - { - item->Animation.RequiredState = DOBERMAN_STATE_STAND_LOW_BITE_ATTACK; - item->Animation.TargetState = DOBERMAN_STATE_STOP; - break; - } - - if (TestProbability(0.045f)) - { - item->Animation.RequiredState = DOBERMAN_STATE_SIT_IDLE; - item->Animation.TargetState = DOBERMAN_STATE_STOP; - break; - } - - if (TestProbability(0.085f)) - { - item->Animation.TargetState = DOBERMAN_STATE_STOP; - break; - } - } - - break; - - case DOBERMAN_STATE_RUN_FORWARD: - tilt = angle; - creature->MaxTurn = ANGLE(6.0f); - - if (creature->Mood == MoodType::Bored) + if (TestProbability(0.025f)) { + item->Animation.RequiredState = DOBERMAN_STATE_STAND_LOW_BITE_ATTACK; item->Animation.TargetState = DOBERMAN_STATE_STOP; break; } - if (AI.distance < pow(768, 2)) - item->Animation.TargetState = DOBERMAN_STATE_JUMP_BITE_ATTACK; - - break; - - case DOBERMAN_STATE_STOP: - creature->MaxTurn = 0; - creature->Flags = 0; - - if (creature->Mood != MoodType::Bored) + if (TestProbability(0.045f)) { - if (creature->Mood != MoodType::Escape && - AI.distance < pow(341, 2) && - AI.ahead) - { - item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; - } - else - item->Animation.TargetState = DOBERMAN_STATE_RUN_FORWARD; - } - else - { - if (item->Animation.RequiredState) - item->Animation.TargetState = item->Animation.RequiredState; - else - { - if (TestProbability(0.975f)) - { - if (TestProbability(0.95f)) - { - if (TestProbability(0.3f)) - item->Animation.TargetState = DOBERMAN_STATE_WALK_FORWARD; - } - else - item->Animation.TargetState = DOBERMAN_STATE_SIT_IDLE; - } - else - item->Animation.TargetState = DOBERMAN_STATE_STAND_LOW_BITE_ATTACK; - } - } - - break; - - case DOBERMAN_STATE_STAND_LOW_BITE_ATTACK: - if (creature->Mood != MoodType::Bored || TestProbability(0.04f)) + item->Animation.RequiredState = DOBERMAN_STATE_SIT_IDLE; item->Animation.TargetState = DOBERMAN_STATE_STOP; + break; + } - break; - - case DOBERMAN_STATE_SIT_IDLE: - if (creature->Mood != MoodType::Bored || TestProbability(0.008f)) + if (TestProbability(0.085f)) + { item->Animation.TargetState = DOBERMAN_STATE_STOP; - - break; - - case DOBERMAN_STATE_STAND_IDLE: - if (creature->Mood != MoodType::Bored || TestProbability(0.015f)) - item->Animation.TargetState = DOBERMAN_STATE_STOP; - - break; - - case DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK: - creature->MaxTurn = ANGLE(0.5f); - - if (creature->Flags != 1 && AI.ahead && - item->TouchBits & 0x122000) - { - DoDamage(creature->Enemy, 30); - CreatureEffect(item, DobermanBite, DoBloodSplat); - creature->Flags = 1; + break; } + } - if (AI.distance <= pow(341, 2) || AI.distance >= pow(682, 2)) - item->Animation.TargetState = DOBERMAN_STATE_STOP; - else - item->Animation.TargetState = DOBERMAN_STATE_LEAP_BITE_ATTACK; + break; - break; + case DOBERMAN_STATE_RUN_FORWARD: + creature->MaxTurn = ANGLE(6.0f); + tilt = angle; - case DOBERMAN_STATE_JUMP_BITE_ATTACK: - if (creature->Flags != 2 && item->TouchBits & 0x122000) - { - DoDamage(creature->Enemy, 80); - CreatureEffect(item, DobermanBite, DoBloodSplat); - creature->Flags = 2; - } - - if (AI.distance >= pow(341, 2)) - { - if (AI.distance < pow(682, 2)) - item->Animation.TargetState = DOBERMAN_STATE_LEAP_BITE_ATTACK; - } - else - item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; - - break; - - case DOBERMAN_STATE_LEAP_BITE_ATTACK: - creature->MaxTurn = ANGLE(6.0f); - - if (creature->Flags != 3 && item->TouchBits & 0x122000) - { - DoDamage(creature->Enemy, 50); - CreatureEffect(item, DobermanBite, DoBloodSplat); - creature->Flags = 3; - } - - if (AI.distance < pow(341, 2)) - item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; - - break; - - default: + if (creature->Mood == MoodType::Bored) + { + item->Animation.TargetState = DOBERMAN_STATE_STOP; break; } - } - else if (item->Animation.ActiveState != DOBERMAN_STATE_DEATH) - { - item->Animation.AnimNumber = Objects[ID_DOBERMAN].animIndex + DOBERMAN_ANIM_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = DOBERMAN_STATE_DEATH; - } - CreatureTilt(item, tilt); - CreatureJoint(item, 0, 0); - CreatureJoint(item, 1, joint); - CreatureJoint(item, 2, 0); - CreatureAnimation(itemNumber, angle, tilt); + if (AI.distance < pow(768, 2)) + item->Animation.TargetState = DOBERMAN_STATE_JUMP_BITE_ATTACK; + + break; + + case DOBERMAN_STATE_STOP: + creature->MaxTurn = 0; + creature->Flags = 0; + + if (creature->Mood != MoodType::Bored) + { + if (creature->Mood != MoodType::Escape && + AI.distance < pow(341, 2) && + AI.ahead) + { + item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; + } + else + item->Animation.TargetState = DOBERMAN_STATE_RUN_FORWARD; + } + else + { + if (item->Animation.RequiredState) + item->Animation.TargetState = item->Animation.RequiredState; + else + { + if (TestProbability(0.975f)) + { + if (TestProbability(0.95f)) + { + if (TestProbability(0.3f)) + item->Animation.TargetState = DOBERMAN_STATE_WALK_FORWARD; + } + else + item->Animation.TargetState = DOBERMAN_STATE_SIT_IDLE; + } + else + item->Animation.TargetState = DOBERMAN_STATE_STAND_LOW_BITE_ATTACK; + } + } + + break; + + case DOBERMAN_STATE_STAND_LOW_BITE_ATTACK: + if (creature->Mood != MoodType::Bored || TestProbability(0.04f)) + item->Animation.TargetState = DOBERMAN_STATE_STOP; + + break; + + case DOBERMAN_STATE_SIT_IDLE: + if (creature->Mood != MoodType::Bored || TestProbability(0.008f)) + item->Animation.TargetState = DOBERMAN_STATE_STOP; + + break; + + case DOBERMAN_STATE_STAND_IDLE: + if (creature->Mood != MoodType::Bored || TestProbability(0.015f)) + item->Animation.TargetState = DOBERMAN_STATE_STOP; + + break; + + case DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK: + creature->MaxTurn = ANGLE(0.5f); + + if (creature->Flags != 1 && AI.ahead && + item->TouchBits & 0x122000) + { + DoDamage(creature->Enemy, 30); + CreatureEffect(item, DobermanBite, DoBloodSplat); + creature->Flags = 1; + } + + if (AI.distance <= pow(341, 2) || AI.distance >= pow(682, 2)) + item->Animation.TargetState = DOBERMAN_STATE_STOP; + else + item->Animation.TargetState = DOBERMAN_STATE_LEAP_BITE_ATTACK; + + break; + + case DOBERMAN_STATE_JUMP_BITE_ATTACK: + if (creature->Flags != 2 && item->TouchBits & 0x122000) + { + DoDamage(creature->Enemy, 80); + CreatureEffect(item, DobermanBite, DoBloodSplat); + creature->Flags = 2; + } + + if (AI.distance >= pow(341, 2)) + { + if (AI.distance < pow(682, 2)) + item->Animation.TargetState = DOBERMAN_STATE_LEAP_BITE_ATTACK; + } + else + item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; + + break; + + case DOBERMAN_STATE_LEAP_BITE_ATTACK: + creature->MaxTurn = ANGLE(6.0f); + + if (creature->Flags != 3 && item->TouchBits & 0x122000) + { + DoDamage(creature->Enemy, 50); + CreatureEffect(item, DobermanBite, DoBloodSplat); + creature->Flags = 3; + } + + if (AI.distance < pow(341, 2)) + item->Animation.TargetState = DOBERMAN_STATE_STAND_HIGH_BITE_ATTACK; + + break; + + default: + break; + } } + else if (item->Animation.ActiveState != DOBERMAN_STATE_DEATH) + { + item->Animation.AnimNumber = Objects[ID_DOBERMAN].animIndex + DOBERMAN_ANIM_DEATH; + item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + item->Animation.ActiveState = DOBERMAN_STATE_DEATH; + } + + CreatureTilt(item, tilt); + CreatureJoint(item, 0, 0); + CreatureJoint(item, 1, joint); + CreatureJoint(item, 2, 0); + CreatureAnimation(itemNumber, angle, tilt); } } diff --git a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp index 149d45168..170b4f6b8 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp @@ -1,20 +1,25 @@ #include "framework.h" -#include "tr5_lagoon_witch.h" +#include "Objects/TR5/Entity/tr5_lagoon_witch.h" -#include "Game/items.h" #include "Game/control/box.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" #include "Game/gui.h" -#include "Specific/setup.h" -#include "Specific/level.h" -#include "Game/Lara/lara.h" #include "Game/itemdata/creature_info.h" +#include "Game/items.h" +#include "Game/Lara/lara.h" #include "Game/misc.h" +#include "Specific/level.h" +#include "Specific/setup.h" + +using std::vector; namespace TEN::Entities::TR5 { + constexpr auto LAGOON_WITCH_ATTACK_DAMAGE = 100; + const auto LagoonWitchBite = BiteInfo(Vector3::Zero, 7); + const vector LagoonWitchAttackJoints = { 6, 7, 8, 9, 14, 15, 16, 17 }; enum LagoonWitchState { @@ -35,11 +40,7 @@ namespace TEN::Entities::TR5 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 1; - item->Animation.TargetState = WITCH_STATE_IDLE; - item->Animation.ActiveState = WITCH_STATE_IDLE; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + SetAnimation(item, 1); item->Pose.Position.y += CLICK(2); } @@ -54,17 +55,17 @@ namespace TEN::Entities::TR5 short joint2 = 0; auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); auto* object = &Objects[item->ObjectNumber]; + auto* creature = GetCreatureInfo(item); if (item->HitPoints <= 0) { if (item->Animation.ActiveState != WITCH_STATE_DEATH) { - item->HitPoints = 0; item->Animation.ActiveState = WITCH_STATE_DEATH; item->Animation.AnimNumber = object->animIndex + WITCH_ANIM_DEATH; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + item->HitPoints = 0; } } else @@ -127,10 +128,10 @@ namespace TEN::Entities::TR5 creature->MaxTurn = ANGLE(2.0f); if (!creature->Flags && - item->TouchBits & 0x3C3C0 && + item->TestBits(JointBitType::Touch, LagoonWitchAttackJoints) && item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 29) { - DoDamage(creature->Enemy, 100); + DoDamage(creature->Enemy, LAGOON_WITCH_ATTACK_DAMAGE); CreatureEffect2(item, LagoonWitchBite, 10, item->Pose.Orientation.y, DoBloodSplat); creature->Flags = WITCH_STATE_SWIM; } @@ -149,7 +150,7 @@ namespace TEN::Entities::TR5 item->ItemFlags[3]++; creature->ReachedGoal = false; - creature->Enemy = 0; + creature->Enemy = nullptr; } } } diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index 99147a8c1..48d874e13 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -35,15 +35,12 @@ namespace TEN::Entities::TR5 const auto PierreGun1 = BiteInfo(Vector3(60.0f, 200.0f, 0.0f), 11); const auto PierreGun2 = BiteInfo(Vector3(-57.0f, 200.0f, 0.0f), 14); - void InitialiseLarson(short itemNum) + void InitialiseLarson(short itemNumber) { - auto* item = &g_Level.Items[itemNum]; + auto* item = &g_Level.Items[itemNumber]; - ClearItem(itemNum); - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.TargetState = STATE_TR5_LARSON_STOP; - item->Animation.ActiveState = STATE_TR5_LARSON_STOP; + ClearItem(itemNumber); + SetAnimation(item, 0); if (!item->TriggerFlags) return; @@ -66,23 +63,23 @@ namespace TEN::Entities::TR5 if (!CreatureActive(itemNumber)) return; - short tilt = 0; + auto* item = &g_Level.Items[itemNumber]; + auto* creature = GetCreatureInfo(item); + short angle = 0; + short tilt = 0; short joint0 = 0; short joint1 = 0; short joint2 = 0; - auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); - - // In Streets of Rome when Larson HP are below 40 he runs way + // TODO: When Larson's HP is below 40, he runs away in Streets of Rome. Keeping block commented for reference. /*if (item->HitPoints <= TR5_LARSON_MIN_HP && !(item->flags & IFLAG_INVISIBLE)) { item->HitPoints = TR5_LARSON_MIN_HP; creature->flags++; }*/ - // Fire weapon effects + // Fire weapon effects. if (creature->FiredWeapon) { auto pos = Vector3Int(LarsonGun.Position); @@ -96,18 +93,18 @@ namespace TEN::Entities::TR5 { if (CurrentLevel == 2) { - item->ItemFlags[3] = 1; item->Animation.IsAirborne = false; - item->HitStatus = false; - item->Collidable = false; item->Status = ITEM_DEACTIVATED; + item->Collidable = false; + item->HitStatus = false; + item->ItemFlags[3] = 1; } else { item->Animation.IsAirborne = false; - item->HitStatus = false; - item->Collidable = false; item->Status = ITEM_ACTIVE; + item->Collidable = false; + item->HitStatus = false; } item->TriggerFlags = 0; @@ -126,15 +123,15 @@ namespace TEN::Entities::TR5 if (AI.ahead) joint2 = AI.angle; - // FIXME: this should make Larson running away, but it's broken + // FIXME: This should make Larson run away, but it doesn't work. /*if (creature->flags) { item->HitPoints = 60; item->IsAirborne = false; - item->hitStatus = false; - item->collidable = false; - item->status = ITEM_DESACTIVATED; - creature->flags = 0; + item->HitStatus = false; + item->Collidable = false; + item->Status = ITEM_DESACTIVATED; + creature->Flags = 0; }*/ GetCreatureMood(item, &AI, true); @@ -231,8 +228,8 @@ namespace TEN::Entities::TR5 break; case STATE_TR5_LARSON_RUN: - tilt = angle / 2; creature->MaxTurn = ANGLE(11.0f); + tilt = angle / 2; if (AI.ahead) joint2 = AI.angle; @@ -259,16 +256,16 @@ namespace TEN::Entities::TR5 } else { - item->Animation.RequiredState = STATE_TR5_LARSON_IDLE; item->Animation.TargetState = STATE_TR5_LARSON_STOP; + item->Animation.RequiredState = STATE_TR5_LARSON_IDLE; } break; case STATE_TR5_LARSON_AIM: + creature->MaxTurn = 0; joint0 = AI.angle / 2; joint2 = AI.angle / 2; - creature->MaxTurn = 0; if (AI.ahead) joint1 = AI.xAngle; @@ -311,9 +308,9 @@ namespace TEN::Entities::TR5 break; case STATE_TR5_LARSON_ATTACK: + creature->MaxTurn = 0; joint0 = AI.angle / 2; joint2 = AI.angle / 2; - creature->MaxTurn = 0; if (AI.ahead) joint1 = AI.xAngle; @@ -394,12 +391,12 @@ namespace TEN::Entities::TR5 { item->TargetState = STATE_TR5_LARSON_STOP; item->RequiredState = STATE_TR5_LARSON_STOP; - creature->reachedGoal = false; + creature->ReachedGoal = false; item->IsAirborne = false; - item->hitStatus = false; - item->collidable = false; - item->status = ITEM_NOT_ACTIVE; - item->triggerFlags = 0; + item->HitStatus = false; + item->Collidable = false; + item->Status = ITEM_NOT_ACTIVE; + item->TriggerFlags = 0; } else { diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp index a5443ddfd..72c780d24 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp @@ -181,9 +181,9 @@ namespace TEN::Entities::TR5 if (!item->Animation.RequiredState && item->TestBits(JointBitType::Touch, LionAttackJoints)) { - item->Animation.RequiredState = LION_STATE_IDLE; DoDamage(creature->Enemy, LION_POUNCE_ATTACK_DAMAGE); CreatureEffect2(item, LionBite1, 10, item->Pose.Orientation.y, DoBloodSplat); + item->Animation.RequiredState = LION_STATE_IDLE; } break; @@ -194,9 +194,9 @@ namespace TEN::Entities::TR5 if (!item->Animation.RequiredState && item->TestBits(JointBitType::Touch, LionAttackJoints)) { - item->Animation.RequiredState = LION_STATE_IDLE; DoDamage(creature->Enemy, LION_BITE_ATTACK_DAMAGE); CreatureEffect2(item, LionBite2, 10, item->Pose.Orientation.y, DoBloodSplat); + item->Animation.RequiredState = LION_STATE_IDLE; } break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp index 208386092..4581b2184 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp @@ -1,24 +1,26 @@ #include "framework.h" -#include "tr5_submarine.h" -#include "Game/items.h" -#include "Game/control/box.h" -#include "Game/people.h" +#include "Objects/TR5/Entity/tr5_submarine.h" + +#include "Game/animation.h" #include "Game/collision/collide_item.h" #include "Game/collision/collide_room.h" +#include "Game/control/box.h" #include "Game/control/los.h" #include "Game/effects/effects.h" #include "Game/effects/tomb4fx.h" #include "Game/itemdata/creature_info.h" -#include "Game/animation.h" +#include "Game/items.h" #include "Game/Lara/lara.h" #include "Game/Lara/lara_one_gun.h" -#include "Specific/setup.h" -#include "Specific/level.h" +#include "Game/misc.h" +#include "Game/people.h" #include "Sound/sound.h" +#include "Specific/level.h" +#include "Specific/setup.h" namespace TEN::Entities::TR5 { - static void TriggerSubmarineSparks(short itemNumber) + void TriggerSubmarineSparks(short itemNumber) { auto* spark = GetFreeParticle(); @@ -50,7 +52,7 @@ namespace TEN::Entities::TR5 spark->dSize = spark->sSize = spark->size = (GetRandomControl() & 7) + 192; } - static void TriggerTorpedoBubbles(Vector3Int* pos1, Vector3Int* pos2, char factor) + void TriggerTorpedoBubbles(Vector3Int* pos1, Vector3Int* pos2, char factor) { auto* spark = GetFreeParticle(); @@ -83,7 +85,7 @@ namespace TEN::Entities::TR5 spark->dSize = spark->size * 2; } - static void TriggerTorpedoSparks2(Vector3Int* pos1, Vector3Int* pos2, char scale) + void TriggerTorpedoSparks2(Vector3Int* pos1, Vector3Int* pos2, char scale) { auto* spark = GetFreeParticle(); @@ -115,55 +117,56 @@ namespace TEN::Entities::TR5 spark->dSize = spark->size * 2; } - static void SubmarineAttack(ItemInfo* item) + void SubmarineAttack(ItemInfo* item) { short itemNumber = CreateItem(); + if (itemNumber == NO_ITEM) + return; - if (itemNumber != NO_ITEM) + auto* torpedoItem = &g_Level.Items[itemNumber]; + + SoundEffect(SFX_TR5_UNDERWATER_TORPEDO, &torpedoItem->Pose, SoundEnvironment::Always); + + torpedoItem->ObjectNumber = ID_TORPEDO; + torpedoItem->Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f); + + Vector3Int pos1; + Vector3Int pos2; + + for (int i = 0; i < 8; i++) { - auto* torpedoItem = &g_Level.Items[itemNumber]; + auto pos1 = Vector3Int( + (GetRandomControl() & 0x7F) - 414, + -320, + 352 + ); + GetJointAbsPosition(item, &pos1, 4); - SoundEffect(SFX_TR5_UNDERWATER_TORPEDO, &torpedoItem->Pose, SoundEnvironment::Always); + auto pos2 = Vector3Int( + (GetRandomControl() & 0x3FF) - 862, + -320 - (GetRandomControl() & 0x3FF), + (GetRandomControl() & 0x3FF) - 160 + ); + GetJointAbsPosition(item, &pos2, 4); - torpedoItem->ObjectNumber = ID_TORPEDO; - torpedoItem->Color = Vector4(0.5f, 0.5f, 0.5f, 1.0f); - - Vector3Int pos1; - Vector3Int pos2; - - for (int i = 0; i < 8; i++) - { - pos1.x = (GetRandomControl() & 0x7F) - 414; - pos1.y = -320; - pos1.z = 352; - GetJointAbsPosition(item, &pos1, 4); - - pos2.x = (GetRandomControl() & 0x3FF) - 862; - pos2.y = -320 - (GetRandomControl() & 0x3FF); - pos2.z = (GetRandomControl() & 0x3FF) - 160; - GetJointAbsPosition(item, &pos2, 4); - - TriggerTorpedoSparks2(&pos1, &pos2, 0); - } - - torpedoItem->RoomNumber = item->RoomNumber; - GetFloor(pos1.x, pos1.y, pos1.z, &torpedoItem->RoomNumber); - - torpedoItem->Pose.Position.x = pos1.x; - torpedoItem->Pose.Position.y = pos1.y; - torpedoItem->Pose.Position.z = pos1.z; - - InitialiseItem(itemNumber); - - torpedoItem->Pose.Orientation.x = 0; - torpedoItem->Pose.Orientation.y = item->Pose.Orientation.y; - torpedoItem->Pose.Orientation.z = 0; - torpedoItem->Animation.Velocity.z = 0; - torpedoItem->Animation.Velocity.y = 0; - torpedoItem->ItemFlags[0] = -1; - - AddActiveItem(itemNumber); + TriggerTorpedoSparks2(&pos1, &pos2, 0); } + + torpedoItem->RoomNumber = item->RoomNumber; + GetFloor(pos1.x, pos1.y, pos1.z, &torpedoItem->RoomNumber); + + torpedoItem->Pose.Position = pos1; + + InitialiseItem(itemNumber); + + torpedoItem->Animation.Velocity.y = 0.0f; + torpedoItem->Animation.Velocity.z = 0.0f; + torpedoItem->Pose.Orientation.x = 0; + torpedoItem->Pose.Orientation.y = item->Pose.Orientation.y; + torpedoItem->Pose.Orientation.z = 0; + torpedoItem->ItemFlags[0] = -1; + + AddActiveItem(itemNumber); } void InitialiseSubmarine(short itemNumber) @@ -171,10 +174,7 @@ namespace TEN::Entities::TR5 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.TargetState = 0; - item->Animation.ActiveState = 0; + SetAnimation(item, 0); if (!item->TriggerFlags) item->TriggerFlags = 120; @@ -186,14 +186,14 @@ namespace TEN::Entities::TR5 return; auto* item = &g_Level.Items[itemNumber]; - auto* creature = (CreatureInfo*)item->Data; + auto* creature = GetCreatureInfo(item); if (item->AIBits) GetAITarget(creature); else creature->Enemy = LaraItem; - AI_INFO AI, laraInfo; + AI_INFO AI, laraAI; CreatureAIInfo(item, &AI); GetCreatureMood(item, &AI, true); @@ -203,34 +203,34 @@ namespace TEN::Entities::TR5 if (creature->Enemy == LaraItem) { - laraInfo.angle = AI.angle; - laraInfo.distance = AI.distance; + laraAI.angle = AI.angle; + laraAI.distance = AI.distance; } else { int dx = LaraItem->Pose.Position.x - item->Pose.Position.x; int dz = LaraItem->Pose.Position.z - item->Pose.Position.z; - laraInfo.angle = phd_atan(dz, dx) - item->Pose.Orientation.y; - laraInfo.distance = pow(dx, 2) + pow(dz, 2); - laraInfo.ahead = true; + laraAI.angle = phd_atan(dz, dx) - item->Pose.Orientation.y; + laraAI.distance = pow(dx, 2) + pow(dz, 2); + laraAI.ahead = true; } int tilt = item->ItemFlags[0] + (angle / 2); - if (tilt > 2048) - tilt = 2048; - else if (tilt < -2048) - tilt = -2048; + if (tilt > ANGLE(11.25f)) + tilt = ANGLE(11.25f); + else if (tilt < ANGLE(-11.25f)) + tilt = ANGLE(-11.25f); item->ItemFlags[0] = tilt; - if (abs(tilt) >= 64) + if (abs(tilt) >= ANGLE(0.35f)) { if (tilt > 0) - item->ItemFlags[0] -= 64; + item->ItemFlags[0] -= ANGLE(0.35f); else - item->ItemFlags[0] += 64; + item->ItemFlags[0] += ANGLE(0.35f); } else item->ItemFlags[0] = 0; @@ -245,17 +245,17 @@ namespace TEN::Entities::TR5 auto* enemy = creature->Enemy; creature->Enemy = LaraItem; - if (Targetable(item, &laraInfo)) + if (Targetable(item, &laraAI)) { if (creature->Flags >= item->TriggerFlags && - laraInfo.angle > -ANGLE(90.0f) && - laraInfo.angle < ANGLE(90.0f)) + laraAI.angle > -ANGLE(90.0f) && + laraAI.angle < ANGLE(90.0f)) { SubmarineAttack(item); creature->Flags = 0; } - if (laraInfo.distance >= pow(SECTOR(3), 2)) + if (laraAI.distance >= pow(SECTOR(3), 2)) { item->Animation.TargetState = 1; SoundEffect(SFX_TR5_VEHICLE_DIVESUIT_LOOP, &item->Pose, SoundEnvironment::Always); @@ -266,15 +266,15 @@ namespace TEN::Entities::TR5 if (AI.distance < pow(SECTOR(1), 2)) { creature->MaxTurn = 0; - if (abs(laraInfo.angle) >= ANGLE(2.0f)) + if (abs(laraAI.angle) >= ANGLE(2.0f)) { - if (laraInfo.angle >= 0) + if (laraAI.angle >= 0) item->Pose.Orientation.y += ANGLE(2.0f); else item->Pose.Orientation.y -= ANGLE(2.0f); } else - item->Pose.Orientation.y += laraInfo.angle; + item->Pose.Orientation.y += laraAI.angle; } } else @@ -288,36 +288,36 @@ namespace TEN::Entities::TR5 if (GlobalCounter & 1) { - Vector3Int pos1 = { 200, 320, 90 }; + auto pos1 = Vector3Int(200, 320, 90); GetJointAbsPosition(item, &pos1, 1); - Vector3Int pos2 = { 200, 1280, 90 }; + auto pos2 = Vector3Int(200, 1280, 90); GetJointAbsPosition(item, &pos2, 1); TriggerTorpedoBubbles(&pos1, &pos2, 0); - pos1 = { 200, 320, -100 }; + pos1 = Vector3Int(200, 320, -100); GetJointAbsPosition(item, &pos1, 1); - pos2 = { 200, 1280, -100 }; + pos2 = Vector3Int(200, 1280, -100); GetJointAbsPosition(item, &pos2, 1); TriggerTorpedoBubbles(&pos1, &pos2, 0); } else { - Vector3Int pos1 = { -200, 320, 90 }; + auto pos1 = Vector3Int(-200, 320, 90); GetJointAbsPosition(item, &pos1, 2); - Vector3Int pos2 = { -200, 1280, 90 }; + auto pos2 = Vector3Int(-200, 1280, 90); GetJointAbsPosition(item, &pos2, 2); TriggerTorpedoBubbles(&pos1, &pos2, 0); - pos1 = { -200, 320, -100 }; + pos1 = Vector3Int(-200, 320, -100); GetJointAbsPosition(item, &pos1, 2); - pos2 = { -200, 1280, -100 }; + pos2 = Vector3Int(-200, 1280, -100); GetJointAbsPosition(item, &pos2, 2); TriggerTorpedoBubbles(&pos1, &pos2, 0); @@ -384,8 +384,8 @@ namespace TEN::Entities::TR5 if (TestEnvironment(ENV_FLAG_WATER, item->RoomNumber)) { - item->Animation.Velocity.z += (5 - item->Animation.Velocity.z) / 2; - item->Animation.Velocity.y+= (5 - item->Animation.Velocity.y) / 2; + item->Animation.Velocity.y += (5.0f - item->Animation.Velocity.y) / 2.0f; + item->Animation.Velocity.z += (5.0f - item->Animation.Velocity.z) / 2.0f; } else item->Animation.Velocity.y += GRAVITY; @@ -440,20 +440,14 @@ namespace TEN::Entities::TR5 if (searchItem->ObjectNumber == ID_CHAFF && searchItem->Active) { item->ItemFlags[0] = i; - pos.x = searchItem->Pose.Position.x; - pos.y = searchItem->Pose.Position.y; - pos.z = searchItem->Pose.Position.z; + pos = searchItem->Pose.Position; found = true; break; } } if (!found) - { - pos.x = LaraItem->Pose.Position.x; - pos.y = LaraItem->Pose.Position.y; - pos.z = LaraItem->Pose.Position.z; - } + pos = LaraItem->Pose.Position; } else { @@ -461,9 +455,7 @@ namespace TEN::Entities::TR5 if (chaffItem->Active && chaffItem->ObjectNumber == ID_CHAFF) { - pos.x = chaffItem->Pose.Position.x; - pos.y = chaffItem->Pose.Position.y; - pos.z = chaffItem->Pose.Position.z; + pos = chaffItem->Pose.Position; item->Animation.ActiveState = pos.x / 4; item->Animation.TargetState = pos.y / 4; item->Animation.RequiredState = pos.z / 4; @@ -478,13 +470,13 @@ namespace TEN::Entities::TR5 auto angles = GetVectorAngles(pos.x - item->Pose.Position.x, pos.y - item->Pose.Position.y, pos.z - item->Pose.Position.z); - if (item->Animation.Velocity.z >= 48) + if (item->Animation.Velocity.z >= 48.0f) { - if (item->Animation.Velocity.z < 192) + if (item->Animation.Velocity.z < 192.0f) item->Animation.Velocity.z++; } else - item->Animation.Velocity.z += 4; + item->Animation.Velocity.z += 4.0f; item->ItemFlags[1]++; diff --git a/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp b/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp index f2c8e6a04..5cbeef02e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp @@ -17,9 +17,6 @@ namespace TEN::Entities::TR5 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = WWISP_STATE_UNK; - item->Animation.TargetState = WWISP_STATE_UNK; + SetAnimation(item, 0); } } From 5782965e11690c38212f0f33775f42a2e5625a3c Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 15:13:45 +1000 Subject: [PATCH 019/106] Move TR5 creatures into more appropriate namespace --- TombEngine/Game/itemdata/itemdata.h | 2 +- .../Objects/TR4/Entity/tr4_big_scorpion.cpp | 2 +- .../Objects/TR5/Entity/tr5_autoguns.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_autoguns.h | 2 +- .../Objects/TR5/Entity/tr5_brownbeast.cpp | 2 +- .../Objects/TR5/Entity/tr5_brownbeast.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_chef.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_chef.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_cyborg.h | 2 +- .../Objects/TR5/Entity/tr5_doberman.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_doberman.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_dog.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_dog.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_ghost.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_ghost.h | 2 +- .../Objects/TR5/Entity/tr5_gladiator.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_gladiator.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_guard.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_gunship.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_gunship.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_hydra.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_hydra.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_imp.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_imp.h | 2 +- .../Objects/TR5/Entity/tr5_lagoon_witch.cpp | 2 +- .../Objects/TR5/Entity/tr5_lagoon_witch.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_larson.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_larson.h | 2 +- .../Objects/TR5/Entity/tr5_laser_head.cpp | 2 +- .../Objects/TR5/Entity/tr5_laser_head.h | 2 +- .../Objects/TR5/Entity/tr5_laserhead_info.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_lion.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_lion.h | 2 +- TombEngine/Objects/TR5/Entity/tr5_reaper.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_reaper.h | 2 +- .../Objects/TR5/Entity/tr5_roman_statue.cpp | 2 +- .../Objects/TR5/Entity/tr5_roman_statue.h | 2 +- .../Objects/TR5/Entity/tr5_submarine.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_submarine.h | 2 +- .../Objects/TR5/Entity/tr5_willowwisp.cpp | 2 +- .../Objects/TR5/Entity/tr5_willowwisp.h | 2 +- .../TR5/Switch/tr5_crowdove_switch.cpp | 16 ++++---- .../Objects/TR5/Switch/tr5_crowdove_switch.h | 5 +-- TombEngine/Objects/TR5/tr5_objects.cpp | 40 +++++++++---------- 46 files changed, 73 insertions(+), 74 deletions(-) diff --git a/TombEngine/Game/itemdata/itemdata.h b/TombEngine/Game/itemdata/itemdata.h index fa34c7a83..cf44da884 100644 --- a/TombEngine/Game/itemdata/itemdata.h +++ b/TombEngine/Game/itemdata/itemdata.h @@ -26,7 +26,7 @@ template struct visitor : Ts... { using Ts::operator()...; }; template visitor(Ts...)->visitor; // line not needed in C++20... using namespace TEN::Entities::TR4; -using namespace TEN::Entities::TR5; +using namespace TEN::Entities::Creatures::TR5; using namespace TEN::Entities::Vehicles; struct ItemInfo; diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp index 4d920706a..84481377b 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp @@ -22,7 +22,7 @@ namespace TEN::Entities::TR4 { constexpr auto BIG_SCORPION_ATTACK_DAMAGE = 120; constexpr auto BIG_SCORPION_TROOP_ATTACK_DAMAGE = 15; - constexpr auto BIG_SCORPION_STINGER_POISON_POTENCY = 8; + constexpr auto BIG_SCORPION_STINGER_POISON_POTENCY = 16; constexpr auto BIG_SCORPION_ATTACK_RANGE = SQUARE(SECTOR(1.35)); constexpr auto BIG_SCORPION_RUN_RANGE = SQUARE(SECTOR(2)); diff --git a/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp b/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp index 380cc0bfb..c11ab4975 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_autoguns.cpp @@ -14,7 +14,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseAutoGuns(short itemNumber) { diff --git a/TombEngine/Objects/TR5/Entity/tr5_autoguns.h b/TombEngine/Objects/TR5/Entity/tr5_autoguns.h index d9d344551..3c37772dd 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_autoguns.h +++ b/TombEngine/Objects/TR5/Entity/tr5_autoguns.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseAutoGuns(short itemNumber); void AutoGunsControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp index ebd6f23b6..5fffd2aa9 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { constexpr auto BROWN_BEAST_ATTACK_DAMAGE = 150; diff --git a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.h b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.h index aad8f18a9..fa5cab857 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.h +++ b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseBrownBeast(short itemNumber); void ControlBrowsBeast(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_chef.cpp b/TombEngine/Objects/TR5/Entity/tr5_chef.cpp index 6e58f1cda..2085c9a1f 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_chef.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_chef.cpp @@ -13,7 +13,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto ChefBite = BiteInfo(Vector3(0.0f, 200.0f, 0.0f), 13); diff --git a/TombEngine/Objects/TR5/Entity/tr5_chef.h b/TombEngine/Objects/TR5/Entity/tr5_chef.h index 46b2aaaf3..da801ab5d 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_chef.h +++ b/TombEngine/Objects/TR5/Entity/tr5_chef.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseChef(short itemNumber); void ControlChef(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp index a9cfe4c9a..c0ab19da9 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp @@ -19,7 +19,7 @@ using namespace TEN::Effects::Lara; using namespace TEN::Effects::Lightning; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto CyborgGunBite = BiteInfo(Vector3(0.0f, 300.0f, 64.0f), 7); byte HitmanJoints[12] = { 15, 14, 13, 6, 5, 12, 7, 4, 10, 11, 19 }; diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.h b/TombEngine/Objects/TR5/Entity/tr5_cyborg.h index b81f7a942..80ec07d97 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.h +++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseCyborg(short itemNumber); void CyborgControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp index eb3e4543a..ca562e8fc 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp @@ -14,7 +14,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto DobermanBite = BiteInfo(Vector3(0.0f, 30.0f, 141.0f), 20); diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.h b/TombEngine/Objects/TR5/Entity/tr5_doberman.h index 2edd5c50b..bba3b5fb1 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.h +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseDoberman(short itemNumber); void DobermanControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_dog.cpp b/TombEngine/Objects/TR5/Entity/tr5_dog.cpp index 6fa38a571..dec3abace 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_dog.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_dog.cpp @@ -11,7 +11,7 @@ #include "Game/items.h" #include "Game/misc.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto DogBite = BiteInfo(Vector3(0.0f, 0.0f, 100.0f), 3); static BYTE DogAnims[] = { 20, 21, 22, 20 }; diff --git a/TombEngine/Objects/TR5/Entity/tr5_dog.h b/TombEngine/Objects/TR5/Entity/tr5_dog.h index 3021da3b5..82e278d2c 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_dog.h +++ b/TombEngine/Objects/TR5/Entity/tr5_dog.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseTr5Dog(short itemNumber); void Tr5DogControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp b/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp index af812e63f..52b543a91 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_ghost.cpp @@ -10,7 +10,7 @@ #include "Sound/sound.h" #include "Game/itemdata/creature_info.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto InvisibleGhostBite = BiteInfo(Vector3::Zero, 17); diff --git a/TombEngine/Objects/TR5/Entity/tr5_ghost.h b/TombEngine/Objects/TR5/Entity/tr5_ghost.h index 40ef99ba3..62ccb4596 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_ghost.h +++ b/TombEngine/Objects/TR5/Entity/tr5_ghost.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseInvisibleGhost(short itemNumber); void InvisibleGhostControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index aae3085dd..8434d8639 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -18,7 +18,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { constexpr auto GLADIATOR_ATTACK_DAMAGE = 120; diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.h b/TombEngine/Objects/TR5/Entity/tr5_gladiator.h index a28b30371..752637ef9 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.h +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseGladiator(short itemNumber); void ControlGladiator(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp index aa39aee12..eefc48524 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp @@ -19,7 +19,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto SwatGunBite = BiteInfo(Vector3(80.0f, 200.0f, 13.0f), 0); const auto SniperGunBite = BiteInfo(Vector3(0.0f, 480.0f, 110.0f), 13); diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.h b/TombEngine/Objects/TR5/Entity/tr5_guard.h index 847958397..68aa3e723 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_guard.h +++ b/TombEngine/Objects/TR5/Entity/tr5_guard.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseGuard(short itemNumber); void GuardControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp b/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp index 782e180bf..6ecc0e7c7 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp @@ -12,7 +12,7 @@ #include "Game/items.h" #include "Game/Lara/lara.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { int GunShipCounter = 0; diff --git a/TombEngine/Objects/TR5/Entity/tr5_gunship.h b/TombEngine/Objects/TR5/Entity/tr5_gunship.h index 60ba90808..9f862512a 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gunship.h +++ b/TombEngine/Objects/TR5/Entity/tr5_gunship.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void ControlGunShip(short itemNumber); } diff --git a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp index 94230274b..05e51a6ff 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_hydra.cpp @@ -17,7 +17,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto HydraBite = BiteInfo(Vector3::Zero, 11); diff --git a/TombEngine/Objects/TR5/Entity/tr5_hydra.h b/TombEngine/Objects/TR5/Entity/tr5_hydra.h index 0567421b4..324ca600d 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_hydra.h +++ b/TombEngine/Objects/TR5/Entity/tr5_hydra.h @@ -1,7 +1,7 @@ #pragma once #include "Specific/phd_global.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseHydra(short itemNumber); void HydraControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp index 29c2e501b..b8715c98b 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp @@ -14,7 +14,7 @@ using namespace TEN::Entities::Generic; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto ImpBite = BiteInfo(Vector3(0.0f, 100.0f, 0.0f), 9); diff --git a/TombEngine/Objects/TR5/Entity/tr5_imp.h b/TombEngine/Objects/TR5/Entity/tr5_imp.h index f32d76ab6..2b3f5882e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_imp.h +++ b/TombEngine/Objects/TR5/Entity/tr5_imp.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseImp(short itemNumber); void ImpControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp index 170b4f6b8..e73250c6f 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.cpp @@ -14,7 +14,7 @@ using std::vector; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { constexpr auto LAGOON_WITCH_ATTACK_DAMAGE = 100; diff --git a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.h b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.h index f4808d67e..b43431ba4 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.h +++ b/TombEngine/Objects/TR5/Entity/tr5_lagoon_witch.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseLagoonWitch(short itemNumber); void LagoonWitchControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index 48d874e13..89e698ca5 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { #define STATE_TR5_LARSON_STOP 1 #define STATE_TR5_LARSON_WALK 2 diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.h b/TombEngine/Objects/TR5/Entity/tr5_larson.h index 15c75470b..4e86b61c9 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.h +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseLarson(short itemNumber); void LarsonControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp index a1a848331..a889a960e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_laser_head.cpp @@ -19,7 +19,7 @@ using namespace TEN::Effects::Lara; using namespace TEN::Effects::Lightning; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { struct LaserHeadStruct { diff --git a/TombEngine/Objects/TR5/Entity/tr5_laser_head.h b/TombEngine/Objects/TR5/Entity/tr5_laser_head.h index 5990de0b3..abd3542b4 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_laser_head.h +++ b/TombEngine/Objects/TR5/Entity/tr5_laser_head.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseLaserHead(short itemNumber); void LaserHeadControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h b/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h index a0b038821..52adc215f 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h +++ b/TombEngine/Objects/TR5/Entity/tr5_laserhead_info.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { struct LaserHeadInfo { diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp index 72c780d24..66fd9992e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { constexpr auto LION_POUNCE_ATTACK_DAMAGE = 200; constexpr auto LION_BITE_ATTACK_DAMAGE = 60; diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.h b/TombEngine/Objects/TR5/Entity/tr5_lion.h index 85d223a2d..4218188f4 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.h +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseLion(short itemNumber); void LionControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp b/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp index f8f1ba0ac..4018b8e2a 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_reaper.cpp @@ -9,7 +9,7 @@ #include "Game/itemdata/creature_info.h" #include "Game/control/control.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseReaper(short itemNumber) { diff --git a/TombEngine/Objects/TR5/Entity/tr5_reaper.h b/TombEngine/Objects/TR5/Entity/tr5_reaper.h index 464d8dae5..cebde76ff 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_reaper.h +++ b/TombEngine/Objects/TR5/Entity/tr5_reaper.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseReaper(short itemNumber); void ReaperControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp index a7d242b5e..3bccfa45d 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp @@ -18,7 +18,7 @@ using namespace TEN::Effects::Lightning; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { const auto RomanStatueBite = BiteInfo(Vector3::Zero, 15); diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.h b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.h index d2b9ee411..0b35f6e09 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.h +++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.h @@ -1,7 +1,7 @@ #pragma once #include "Specific/phd_global.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseRomanStatue(short itemNumber); void RomanStatueControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp index 4581b2184..bfdde4086 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp @@ -18,7 +18,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void TriggerSubmarineSparks(short itemNumber) { diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.h b/TombEngine/Objects/TR5/Entity/tr5_submarine.h index ab76d34ca..7a3db051e 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_submarine.h +++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseSubmarine(short itemNumber); void SubmarineControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp b/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp index 5cbeef02e..d99d28674 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_willowwisp.cpp @@ -5,7 +5,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { enum WillowWispState { diff --git a/TombEngine/Objects/TR5/Entity/tr5_willowwisp.h b/TombEngine/Objects/TR5/Entity/tr5_willowwisp.h index 778c3ea29..6271a9c6f 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_willowwisp.h +++ b/TombEngine/Objects/TR5/Entity/tr5_willowwisp.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR5 +namespace TEN::Entities::Creatures::TR5 { void InitialiseLightingGuide(short itemNumber); } diff --git a/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp b/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp index 274bb64bb..7f725661a 100644 --- a/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp +++ b/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.cpp @@ -1,21 +1,21 @@ #include "framework.h" #include "tr5_crowdove_switch.h" + +#include "Game/animation.h" +#include "Game/collision/collide_item.h" #include "Game/control/control.h" -#include "Specific/input.h" -#include "Specific/level.h" +#include "Game/effects/debris.h" +#include "Game/items.h" #include "Game/Lara/lara.h" #include "Game/Lara/lara_helpers.h" #include "Objects/Generic/Switches/generic_switch.h" #include "Sound/sound.h" -#include "Game/animation.h" -#include "Game/items.h" -#include "Game/collision/collide_item.h" -#include "Game/effects/debris.h" +#include "Specific/input.h" +#include "Specific/level.h" using namespace TEN::Input; -using namespace TEN::Entities::Switches; -namespace TEN::Entities::TR5 +namespace TEN::Entities::Switches { OBJECT_COLLISION_BOUNDS CrowDoveBounds = { diff --git a/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.h b/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.h index 8aeeea90f..c32c73df8 100644 --- a/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.h +++ b/TombEngine/Objects/TR5/Switch/tr5_crowdove_switch.h @@ -1,9 +1,8 @@ #pragma once - -#include "Game/items.h" #include "Game/collision/collide_room.h" +#include "Game/items.h" -namespace TEN::Entities::TR5 +namespace TEN::Entities::Switches { void InitialiseCrowDoveSwitch(short itemNumber); void CrowDoveSwitchControl(short itemNumber); diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp index 1efa9b1dd..aa98ec944 100644 --- a/TombEngine/Objects/TR5/tr5_objects.cpp +++ b/TombEngine/Objects/TR5/tr5_objects.cpp @@ -1,7 +1,20 @@ #include "framework.h" #include "Objects/TR5/tr5_objects.h" -/// Entities +#include "Game/collision/collide_item.h" +#include "Game/control/box.h" +#include "Game/itemdata/creature_info.h" +#include "Game/Lara/lara_flare.h" +#include "Game/Lara/lara_initialise.h" +#include "Game/Lara/lara_one_gun.h" +#include "Game/pickup/pickup.h" +#include "Objects/Generic/Object/objects.h" +#include "Objects/Generic/Switches/switch.h" +#include "Objects/Utils/object_helper.h" +#include "Specific/level.h" +#include "Specific/setup.h" + +// Creatures #include "tr5_autoguns.h" // OK #include "tr5_brownbeast.h" // OK #include "tr5_chef.h" // OK @@ -23,13 +36,13 @@ #include "tr5_submarine.h" // OK #include "tr5_willowwisp.h" // OK -/// Emitters +// Emitters #include "Objects/TR5/Emitter/tr5_rats_emitter.h" #include "Objects/TR5/Emitter/tr5_bats_emitter.h" #include "Objects/TR5/Emitter/tr5_spider_emitter.h" #include "tr5_smoke_emitter.h" -/// Objects +// Objects #include "Objects/TR5/Object/tr5_pushableblock.h" #include "tr5_twoblockplatform.h" #include "tr5_raisingcog.h" @@ -42,7 +55,7 @@ #include "tr5_missile.h" #include "tr5_genslot.h" -/// Traps +// Traps #include "tr5_ventilator.h" #include "tr5_deathslide.h" #include "Objects/Effects/tr5_electricity.h" @@ -55,24 +68,11 @@ // Switches #include "tr5_crowdove_switch.h" -/// shatter +// Shatters #include "Objects/TR5/Shatter/tr5_smashobject.h" -/// necessary import -#include "Game/collision/collide_item.h" -#include "Game/Lara/lara_one_gun.h" -#include "Game/Lara/lara_flare.h" -#include "Game/Lara/lara_initialise.h" -#include "Game/pickup/pickup.h" -#include "Specific/setup.h" -#include "Objects/Generic/Switches/switch.h" -#include "Objects/Generic/Object/objects.h" -#include "Specific/level.h" -/// register objects -#include "Objects/Utils/object_helper.h" -#include "Game/itemdata/creature_info.h" -#include "Game/control/box.h" -using namespace TEN::Entities::TR5; +using namespace TEN::Entities::Creatures::TR5; +using namespace TEN::Entities::Switches; static void StartEntity(ObjectInfo *obj) { From 658498d17b9d20943996264c2792f5d455df214b Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 15:17:57 +1000 Subject: [PATCH 020/106] Move TR1 creatures into more appropriate namespace --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_ape.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_bear.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_big_rat.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_centaur.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_centaur.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_doppelganger.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_giant_mutant.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_natla.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_natla.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_winged_mutant.h | 2 +- TombEngine/Objects/TR1/Entity/tr1_wolf.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_wolf.h | 2 +- TombEngine/Objects/TR1/tr1_objects.cpp | 5 ++--- 19 files changed, 20 insertions(+), 21 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 23ddb3759..baa2cf01d 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto APE_ATTACK_DAMAGE = 200; diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.h b/TombEngine/Objects/TR1/Entity/tr1_ape.h index 9edc287ab..081f18fdf 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.h +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void ApeControl(short itemNumber); } diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp index 49cf01acb..e84b60561 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto BEAR_RUN_DAMAGE = 3; constexpr auto BEAR_ATTACK_DAMAGE = 200; diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.h b/TombEngine/Objects/TR1/Entity/tr1_bear.h index dcfd85eb9..24107b33d 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_bear.h +++ b/TombEngine/Objects/TR1/Entity/tr1_bear.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void BearControl(short itemNumber); } diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp index 69e96d258..219a35439 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto BIG_RAT_BITE_ATTACK_DAMAGE = 20; constexpr auto BIG_RAT_POUNCE_ATTACK_DAMAGE = 25; diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.h b/TombEngine/Objects/TR1/Entity/tr1_big_rat.h index bdf2afe97..d0e38f9a6 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.h +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void InitialiseBigRat(short itemNumber); void BigRatControl(short itemNumber); diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp index 3f9029d35..ffe8549a5 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp @@ -21,7 +21,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto CENTAUR_REAR_DAMAGE = 200; constexpr auto CENTAUR_REAR_RANGE = SECTOR(1.5f); diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.h b/TombEngine/Objects/TR1/Entity/tr1_centaur.h index ebf3a4984..cf34267d2 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_centaur.h +++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto SHARD_VELOCITY = 250; constexpr auto BOMB_VELOCITY = 220; diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp index 828dbc715..7c9c06de0 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp @@ -14,7 +14,7 @@ // - Bacon Lara cannot be targeted. // - Bacon Lara cannot move like Lara. -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { // Original: void InitialiseDoppelganger(short itemNumber) diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.h b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.h index 0c44a7406..d0b6df5ed 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.h +++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void InitialiseDoppelganger(short itemNumber); void DoppelgangerControl(short itemNumber); diff --git a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp index 46709db1e..9d9f200f7 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp @@ -18,7 +18,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto MUTANT_ATTACK_DAMAGE = 500; constexpr auto MUTANT_CONTACT_DAMAGE = 6; diff --git a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.h b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.h index 67c8af943..7c34920d3 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.h +++ b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void GiantMutantControl(short itemNumber); } diff --git a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp index f18c25f1e..31aaf4f5f 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_natla.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_natla.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { // TODO: Organise. constexpr auto NATLA_SHOT_DAMAGE = 100; diff --git a/TombEngine/Objects/TR1/Entity/tr1_natla.h b/TombEngine/Objects/TR1/Entity/tr1_natla.h index 1140021da..1cbebf286 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_natla.h +++ b/TombEngine/Objects/TR1/Entity/tr1_natla.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void NatlaControl(short itemNumber); } diff --git a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp index 4684f4326..65954e623 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp @@ -19,7 +19,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto WINGED_MUTANT_IDLE_JUMP_ATTACK_DAMAGE = 150; constexpr auto WINGED_MUTANT_RUN_JUMP_ATTACK_DAMAGE = 100; diff --git a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.h b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.h index d8d9f8688..e637dead4 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.h +++ b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void InitialiseWingedMutant(short itemNumber); void WingedMutantControl(short itemNumber); diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp index a8a293eb8..cdb15b63b 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { constexpr auto WOLF_BITE_DAMAGE = 100; constexpr auto WOLF_LUNGE_DAMAGE = 50; diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.h b/TombEngine/Objects/TR1/Entity/tr1_wolf.h index c9a4ec7ec..38b83ab1c 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_wolf.h +++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR1 +namespace TEN::Entities::Creatures::TR1 { void InitialiseWolf(short itemNumber); void WolfControl(short itemNumber); diff --git a/TombEngine/Objects/TR1/tr1_objects.cpp b/TombEngine/Objects/TR1/tr1_objects.cpp index bd5211126..942ca6f0f 100644 --- a/TombEngine/Objects/TR1/tr1_objects.cpp +++ b/TombEngine/Objects/TR1/tr1_objects.cpp @@ -1,7 +1,6 @@ #include "framework.h" #include "Objects/TR1/tr1_objects.h" -/// necessary import #include "Game/control/box.h" #include "Game/collision/collide_item.h" #include "Game/itemdata/creature_info.h" @@ -9,7 +8,7 @@ #include "Specific/setup.h" #include "Specific/level.h" -/// entities +// Creatures #include "Objects/TR1/Entity/tr1_ape.h" // OK #include "Objects/TR1/Entity/tr1_bear.h" // OK #include "Objects/TR1/Entity/tr1_doppelganger.h" // OK @@ -21,7 +20,7 @@ #include "Objects/TR1/Entity/tr1_winged_mutant.h" #include "Objects/Utils/object_helper.h" -using namespace TEN::Entities::TR1; +using namespace TEN::Entities::Creatures::TR1; static void StartEntity(ObjectInfo* obj) { From deca190af548debb37a2888dd3750229b9ed90b0 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 15:20:13 +1000 Subject: [PATCH 021/106] Move TR2 creatures into more appropriate namespace --- TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_barracuda.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_bird_monster.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_dragon.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_dragon.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_knife_thrower.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_mercenary.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_monk.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_monk.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_rat.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_rat.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_shark.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_shark.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_silencer.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_silencer.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_skidman.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_skidman.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_spear_guardian.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_spider.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_spider.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_sword_guardian.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.h | 2 +- TombEngine/Objects/TR2/Entity/tr2_yeti.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_yeti.h | 2 +- TombEngine/Objects/TR2/tr2_objects.cpp | 2 +- 39 files changed, 39 insertions(+), 39 deletions(-) diff --git a/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp b/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp index 4346a201c..68e717b09 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp @@ -12,7 +12,7 @@ using std::vector; -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { constexpr auto BARRACUDA_ATTACK_DAMAGE = 100; constexpr auto BARRACUDA_IDLE_ATTACK_RANGE = SQUARE(SECTOR(0.67f)); diff --git a/TombEngine/Objects/TR2/Entity/tr2_barracuda.h b/TombEngine/Objects/TR2/Entity/tr2_barracuda.h index dfde88ccf..64ddf1939 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_barracuda.h +++ b/TombEngine/Objects/TR2/Entity/tr2_barracuda.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void BarracudaControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp index 1d56afbcf..a71985072 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp @@ -14,7 +14,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { constexpr auto BIRD_MONSTER_ATTACK_DAMAGE = 200; constexpr auto BIRD_MONSTER_SLAM_CRUSH_ATTACK_RANGE = SQUARE(SECTOR(1)); diff --git a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.h b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.h index 5756af247..3c97478ce 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.h +++ b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void BirdMonsterControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp index d8234d996..2ab45bf54 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp @@ -20,7 +20,7 @@ using namespace TEN::Input; using std::vector; -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { constexpr auto DRAGON_SWIPE_ATTACK_DAMAGE = 250; constexpr auto DRAGON_CONTACT_DAMAGE = 10; diff --git a/TombEngine/Objects/TR2/Entity/tr2_dragon.h b/TombEngine/Objects/TR2/Entity/tr2_dragon.h index 0809af93a..d501de501 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_dragon.h +++ b/TombEngine/Objects/TR2/Entity/tr2_dragon.h @@ -2,7 +2,7 @@ #include "Game/collision/collide_room.h" #include "Game/items.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void DragonCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); void DragonControl(short backNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp index a5b078769..b59911c68 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.cpp @@ -10,7 +10,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto EagleBite = BiteInfo(Vector3(15.0f, 46.0f, 21.0f), 6); const auto CrowBite = BiteInfo(Vector3(2.0f, 10.0f, 60.0f), 14); diff --git a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.h b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.h index 4b704e256..828b15bf8 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.h +++ b/TombEngine/Objects/TR2/Entity/tr2_eagle_or_crow.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseEagle(short itemNumber); void EagleControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp index bde2bff9c..de1b22b40 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp @@ -18,7 +18,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { constexpr auto KNIFE_PROJECTILE_DAMAGE = 50; diff --git a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.h b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.h index 640373f24..2204a999c 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.h +++ b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void KnifeControl(short fxNumber); void KnifeThrowerControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp b/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp index b166e57f0..c312e5002 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_mercenary.cpp @@ -11,7 +11,7 @@ #include "Specific/setup.h" #include "Specific/trmath.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto MercenaryUziBite = BiteInfo(Vector3(0.0f, 150.0f, 19.0f), 17); const auto MercenaryAutoPistolBite = BiteInfo(Vector3(0.0f, 230.0f, 9.0f), 17); diff --git a/TombEngine/Objects/TR2/Entity/tr2_mercenary.h b/TombEngine/Objects/TR2/Entity/tr2_mercenary.h index 5199716ad..80f95100d 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_mercenary.h +++ b/TombEngine/Objects/TR2/Entity/tr2_mercenary.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void MercenaryUziControl(short itemNumber); void MercenaryAutoPistolControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_monk.cpp b/TombEngine/Objects/TR2/Entity/tr2_monk.cpp index 6dd61eb4d..1308c90e5 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_monk.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_monk.cpp @@ -11,7 +11,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto MonkBite = BiteInfo(Vector3(-23.0f, 16.0f, 265.0f), 14); diff --git a/TombEngine/Objects/TR2/Entity/tr2_monk.h b/TombEngine/Objects/TR2/Entity/tr2_monk.h index dcf98f279..5fa99a252 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_monk.h +++ b/TombEngine/Objects/TR2/Entity/tr2_monk.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void MonkControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp index 473e071b2..a636344e6 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp @@ -14,7 +14,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { constexpr auto RAT_ATTACK_DAMAGE = 20; constexpr auto RAT_ATTACK_RANGE = SQUARE(CLICK(0.7f)); diff --git a/TombEngine/Objects/TR2/Entity/tr2_rat.h b/TombEngine/Objects/TR2/Entity/tr2_rat.h index 1b4ebadcc..9afbf9b8a 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_rat.h +++ b/TombEngine/Objects/TR2/Entity/tr2_rat.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void RatControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_shark.cpp b/TombEngine/Objects/TR2/Entity/tr2_shark.cpp index 6d1e71a10..2f1ef3ae8 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_shark.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_shark.cpp @@ -11,7 +11,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto SharkBite = BiteInfo(Vector3(17.0f, -22.0f, 344.0f), 12); diff --git a/TombEngine/Objects/TR2/Entity/tr2_shark.h b/TombEngine/Objects/TR2/Entity/tr2_shark.h index 1f2d76299..5788ee192 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_shark.h +++ b/TombEngine/Objects/TR2/Entity/tr2_shark.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void SharkControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index c5f124b5f..6261b52d3 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -10,7 +10,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto SilencerGunBite = BiteInfo(Vector3(3.0f, 331.0f, 56.0f), 10); diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.h b/TombEngine/Objects/TR2/Entity/tr2_silencer.h index 3b91c1f71..69e903dfc 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.h +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void SilencerControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp index dec4daf4e..fb0c8b51c 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp @@ -17,7 +17,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { #define SMAN_MIN_TURN (ANGLE(2.0f)) #define SMAN_TARGET_ANGLE ANGLE(15.0f) diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.h b/TombEngine/Objects/TR2/Entity/tr2_skidman.h index 3a79818c5..bc6147943 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_skidman.h +++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.h @@ -2,7 +2,7 @@ #include "Game/collision/collide_room.h" #include "Game/items.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseSkidooMan(short itemNumber); void SkidooManCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); diff --git a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp index 3ad9912e7..32a46fbf1 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp @@ -12,7 +12,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto SpearBiteLeft = BiteInfo(Vector3(0.0f, 0.0f, 920.0f), 11); const auto SpearBiteRight = BiteInfo(Vector3(0.0f, 0.0f, 920.0f), 18); diff --git a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.h b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.h index d7965b761..e46bb4ea1 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.h +++ b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseSpearGuardian(short itemNumber); void SpearGuardianControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_spider.cpp b/TombEngine/Objects/TR2/Entity/tr2_spider.cpp index 7043d2fc6..e7bb5ac5a 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spider.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spider.cpp @@ -14,7 +14,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto SpiderBite = BiteInfo(Vector3(0.0f, 0.0f, 41.0f), 1); diff --git a/TombEngine/Objects/TR2/Entity/tr2_spider.h b/TombEngine/Objects/TR2/Entity/tr2_spider.h index 23d72cc40..9b5876eec 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spider.h +++ b/TombEngine/Objects/TR2/Entity/tr2_spider.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void SmallSpiderControl(short itemNumber); void BigSpiderControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp index 155e51721..062eb22e9 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp @@ -13,7 +13,7 @@ #include "Sound/sound.h" #include "Specific/level.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto SwordBite = BiteInfo(Vector3(0.0f, 37.0f, 550.0f), 15); diff --git a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.h b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.h index 9c837688b..588df13b8 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.h +++ b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseSwordGuardian(short itemNumber); void SwordGuardianControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp index 66e424bf2..5ab9a903b 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.cpp @@ -10,7 +10,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto WorkerDualGunBiteLeft = BiteInfo(Vector3(-2.0f, 275.0f, 23.0f), 6); const auto WorkerDualGunBiteRight = BiteInfo(Vector3(2.0f, 275.0f, 23.0f), 10); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.h b/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.h index fd95395f8..d4a1761d3 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.h +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_dualrevolver.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void WorkerDualGunControl(short itemNumber); } diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp index a1ed233eb..ee7738029 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.cpp @@ -16,7 +16,7 @@ #include "Specific/level.h" #include "Specific/trmath.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto WorkerFlamethrowerOffset = Vector3Int(0, 140, 0); const auto WorkerFlamethrowerBite = BiteInfo(Vector3(0.0f, 250.0f, 32.0f), 9); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.h b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.h index 89fa4122b..f8b851421 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.h +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_flamethrower.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseWorkerFlamethrower(short itemNumber); void WorkerFlamethrower(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp index 6a69c3e15..2a198c8f5 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.cpp @@ -11,7 +11,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto WorkerMachineGunBite = BiteInfo(Vector3(0.0f, 308.0f, 32.0f), 9); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.h b/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.h index fef58f199..1ba9b187a 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.h +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_machinegun.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseWorkerMachineGun(short itemNumber); void WorkerMachineGunControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp index b5bb9e0d1..9f44426e1 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.cpp @@ -12,7 +12,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto WorkerShotgunBite = BiteInfo(Vector3(0.0f, 281.0f, 40.0f), 9); diff --git a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.h b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.h index a6ad5f5a6..5022fcbd7 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.h +++ b/TombEngine/Objects/TR2/Entity/tr2_worker_shotgun.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseWorkerShotgun(short itemNumber); void WorkerShotgunControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp index 173ba1dd8..8dcd9889c 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { const auto YetiBiteLeft = BiteInfo(Vector3(12.0f, 101.0f, 19.0f), 13); const auto YetiBiteRight = BiteInfo(Vector3(12.0f, 101.0f, 19.0f), 10); diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.h b/TombEngine/Objects/TR2/Entity/tr2_yeti.h index aa6ae5f16..f77c73350 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_yeti.h +++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR2 +namespace TEN::Entities::Creatures::TR2 { void InitialiseYeti(short itemNumber); void YetiControl(short itemNumber); diff --git a/TombEngine/Objects/TR2/tr2_objects.cpp b/TombEngine/Objects/TR2/tr2_objects.cpp index 67c07965b..599a45b7d 100644 --- a/TombEngine/Objects/TR2/tr2_objects.cpp +++ b/TombEngine/Objects/TR2/tr2_objects.cpp @@ -37,7 +37,7 @@ #include "Objects/TR2/Vehicles/speedboat.h" #include "Objects/TR2/Vehicles/skidoo.h" -using namespace TEN::Entities::TR2; +using namespace TEN::Entities::Creatures::TR2; static void StartEntity(ObjectInfo* obj) { From 1455ff52a6badabc8451999ef760d0a3bedd3d05 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 15:23:13 +1000 Subject: [PATCH 022/106] Move TR3 creatures into more appropriate namespace --- TombEngine/Objects/TR3/Entity/tr3_civvy.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_civvy.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_cobra.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_cobra.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_flamethrower.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_monkey.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_mp_gun.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_mp_stick.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_raptor.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_scuba_diver.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_shiva.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_shiva.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_sophia.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_sophia.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_tiger.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_tiger.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_tony.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_tony.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_trex.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_trex.h | 2 +- TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_tribesman.h | 2 +- TombEngine/Objects/TR3/tr3_objects.cpp | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp index aad4a59a4..7ffafd62a 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto CIVVY_ATTACK_DAMAGE = 40; constexpr auto CIVVY_SWIPE_DAMAGE = 50; diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.h b/TombEngine/Objects/TR3/Entity/tr3_civvy.h index 0bb46d8b8..f541c16e5 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_civvy.h +++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void InitialiseCivvy(short itemNumber); void CivvyControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp index fdb3806ec..aaff1fb58 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp @@ -14,7 +14,7 @@ using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto COBRA_BITE_ATTACK_DAMAGE = 80; constexpr auto COBRA_BITE_POISON_POTENCY = 8; diff --git a/TombEngine/Objects/TR3/Entity/tr3_cobra.h b/TombEngine/Objects/TR3/Entity/tr3_cobra.h index 53e817328..261d28bd3 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_cobra.h +++ b/TombEngine/Objects/TR3/Entity/tr3_cobra.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void InitialiseCobra(short itemNum); void CobraControl(short itemNum); diff --git a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp index 66a437818..c3b67735f 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.cpp @@ -9,7 +9,7 @@ #include "Objects/TR3/fish.h" #include "Specific/level.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { int PirahnaHitWait = false; int CarcassItem = NO_ITEM; diff --git a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h index c8168a1c7..0f3f8cc2a 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h +++ b/TombEngine/Objects/TR3/Entity/tr3_fish_emitter.h @@ -1,7 +1,7 @@ #pragma once #include "Game/items.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void SetupShoal(int shoalNumber); void ControlFish(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index 5af828ce5..7531abd3e 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -19,7 +19,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { const auto FlamethrowerOffset = Vector3Int(0, 340, 0); const auto FlamethrowerBite = BiteInfo(Vector3(0.0f, 340.0f, 64.0f), 7); diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.h b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.h index 61044cf99..761df41cf 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.h +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void FlameThrowerControl(short itemNumber); } diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index 63816c709..5b912e7d1 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { // TODO: Work out damage constants. constexpr auto MONKEY_SWIPE_ATTACK_PLAYER_DAMAGE = 40; diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.h b/TombEngine/Objects/TR3/Entity/tr3_monkey.h index e136456b9..8b617e255 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.h +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void InitialiseMonkey(short itemNumber); void MonkeyControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index a46c432c2..e3e72d317 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -19,7 +19,7 @@ using namespace TEN::Math::Random; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { const auto MPGunBite = BiteInfo(Vector3(0.0f, 160.0f, 40.0f), 13); diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.h b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.h index 9c768f11b..47a21c4e1 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.h +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void MPGunControl(short itemNumber); } diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index 3378fed0e..525f60f34 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -17,7 +17,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { const auto MPStickBite1 = BiteInfo(Vector3(247.0f, 10.0f, 11.0f), 13); const auto MPStickBite2 = BiteInfo(Vector3(0.0f, 0.0f, 100.0f), 6); diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.h b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.h index 75d1addcb..8848a7f72 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.h +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void InitialiseMPStick(short itemNumber); void MPStickControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index a74c292dc..2e651aaed 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -16,7 +16,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto RAPTOR_ATTACK_DAMAGE = 100; diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.h b/TombEngine/Objects/TR3/Entity/tr3_raptor.h index a9424ca89..640e202ec 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.h +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void RaptorControl(short itemNumber); } diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp index f432647a3..c290527e4 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp @@ -13,7 +13,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto SCUBA_DIVER_ATTACK_DAMAGE = 50; diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.h b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.h index d5bc5b60d..23f9b6167 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.h +++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void ScubaHarpoonControl(short itemNumber); void ScubaControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp b/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp index 3a8eb3d89..b5fd5f8cb 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp @@ -19,7 +19,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto SHIVA_GRAB_ATTACK_DAMAGE = 150; constexpr auto SHIVA_DOWNWARD_ATTACK_DAMAGE = 180; diff --git a/TombEngine/Objects/TR3/Entity/tr3_shiva.h b/TombEngine/Objects/TR3/Entity/tr3_shiva.h index 2aa7cac52..4f208c955 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_shiva.h +++ b/TombEngine/Objects/TR3/Entity/tr3_shiva.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void InitialiseShiva(short itemNumber); void ShivaControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_sophia.cpp b/TombEngine/Objects/TR3/Entity/tr3_sophia.cpp index f28c82d3e..123e255da 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_sophia.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_sophia.cpp @@ -9,7 +9,7 @@ #include "Sound/sound.h" #include "Specific/level.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { static BOSS_STRUCT BossData; diff --git a/TombEngine/Objects/TR3/Entity/tr3_sophia.h b/TombEngine/Objects/TR3/Entity/tr3_sophia.h index 52778680c..5a96a3725 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_sophia.h +++ b/TombEngine/Objects/TR3/Entity/tr3_sophia.h @@ -1,7 +1,7 @@ #pragma once #include "Game/items.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void ControlLaserBolts(short itemNumber); void ControlLondBossPlasmaBall(short fxNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp index 918e2729d..d80433f11 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto TIGER_ATTACK_DAMAGE = 90; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.h b/TombEngine/Objects/TR3/Entity/tr3_tiger.h index d1966b8fb..4f002d68a 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.h +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void TigerControl(short itemNumber); } diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp index 762c1685d..55f663cd7 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp @@ -20,7 +20,7 @@ using namespace TEN::Effects::Lara; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { static BOSS_STRUCT BossData; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.h b/TombEngine/Objects/TR3/Entity/tr3_tony.h index 398cb37e5..2606a52a2 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tony.h +++ b/TombEngine/Objects/TR3/Entity/tr3_tony.h @@ -1,7 +1,7 @@ #pragma once #include "Game/items.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void InitialiseTony(short itemNumber); void TonyControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp index 256ee4738..c96d26d90 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { constexpr auto TREX_ROAR_CHANCE = 0.015f; diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.h b/TombEngine/Objects/TR3/Entity/tr3_trex.h index 7975f0b52..af6ba80f7 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_trex.h +++ b/TombEngine/Objects/TR3/Entity/tr3_trex.h @@ -1,7 +1,7 @@ #pragma once #include "Game/items.h" -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void LaraTRexDeath(ItemInfo* tRexItem, ItemInfo* laraItem); void TRexControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index f8abb0681..68f121572 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -20,7 +20,7 @@ using namespace TEN::Entities::Traps; using namespace TEN::Math::Random; using std::vector; -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { const auto TribesmanAxeBite = BiteInfo(Vector3(0.0f, 16.0f, 265.0f), 13); const auto TribesmanDartBite1 = BiteInfo(Vector3(0.0f, 0.0f, -200.0f), 13); diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.h b/TombEngine/Objects/TR3/Entity/tr3_tribesman.h index 72743252a..696518dea 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.h +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.h @@ -1,6 +1,6 @@ #pragma once -namespace TEN::Entities::TR3 +namespace TEN::Entities::Creatures::TR3 { void TribemanAxeControl(short itemNumber); void TribemanDartsControl(short itemNumber); diff --git a/TombEngine/Objects/TR3/tr3_objects.cpp b/TombEngine/Objects/TR3/tr3_objects.cpp index c9dde913f..4cd5a68ec 100644 --- a/TombEngine/Objects/TR3/tr3_objects.cpp +++ b/TombEngine/Objects/TR3/tr3_objects.cpp @@ -35,7 +35,7 @@ #include "Objects/TR3/Vehicles/upv.h" #include "Objects/TR3/Vehicles/rubber_boat.h" -using namespace TEN::Entities::TR3; +using namespace TEN::Entities::Creatures::TR3; static void StartEntity(ObjectInfo* obj) { From 6fe5dfa425a968e8a99ab80ecac76b026ef9619a Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 16:13:21 +1000 Subject: [PATCH 023/106] Minor organising --- TombEngine/Objects/TR3/Entity/tr3_civvy.cpp | 65 +++++++++---------- TombEngine/Objects/TR3/Entity/tr3_cobra.cpp | 45 +++++++------ .../Objects/TR3/Entity/tr3_flamethrower.cpp | 63 ++++++++---------- 3 files changed, 84 insertions(+), 89 deletions(-) diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp index 7ffafd62a..be9f320fe 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp @@ -89,11 +89,10 @@ namespace TEN::Entities::Creatures::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short torsoX = 0; - short torsoY = 0; - short head = 0; short angle = 0; short tilt = 0; + auto extraHeadRot = Vector3Shrt::Zero; + auto extraTorsoRot = Vector3Shrt::Zero; if (item->BoxNumber != NO_BOX && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED)) { @@ -119,18 +118,18 @@ namespace TEN::Entities::Creatures::TR3 AI_INFO AI; CreatureAIInfo(item, &AI); - AI_INFO laraAiInfo; + AI_INFO laraAI; if (creature->Enemy == LaraItem) { - laraAiInfo.angle = AI.angle; - laraAiInfo.distance = AI.distance; + laraAI.angle = AI.angle; + laraAI.distance = AI.distance; } else { int laraDz = LaraItem->Pose.Position.z - item->Pose.Position.z; int laraDx = LaraItem->Pose.Position.x - item->Pose.Position.x; - laraAiInfo.angle = phd_atan(laraDz, laraDx) - item->Pose.Orientation.y; - laraAiInfo.distance = pow(laraDx, 2) + pow(laraDz, 2); + laraAI.angle = phd_atan(laraDz, laraDx) - item->Pose.Orientation.y; + laraAI.distance = pow(laraDx, 2) + pow(laraDz, 2); } GetCreatureMood(item, &AI, true); @@ -150,7 +149,7 @@ namespace TEN::Entities::Creatures::TR3 auto* realEnemy = creature->Enemy; creature->Enemy = LaraItem; - if ((laraAiInfo.distance < CIVVY_AWARE_RANGE || item->HitStatus || TargetVisible(item, &laraAiInfo)) && + if ((laraAI.distance < CIVVY_AWARE_RANGE || item->HitStatus || TargetVisible(item, &laraAI)) && !(item->AIBits & FOLLOW)) { if (!creature->Alerted) @@ -170,13 +169,13 @@ namespace TEN::Entities::Creatures::TR3 } case CIVVY_STATE_IDLE: - head = laraAiInfo.angle; creature->MaxTurn = 0; creature->Flags = 0; + extraHeadRot.y = laraAI.angle; if (item->AIBits & GUARD) { - head = AIGuard(creature); + extraHeadRot.y = AIGuard(creature); if (!(GetRandomControl() & 0xFF)) { if (item->Animation.ActiveState == CIVVY_STATE_IDLE) @@ -199,7 +198,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = CIVVY_STATE_RUN_FORWARD; } else if (creature->Mood == MoodType::Bored || - (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAiInfo.distance > pow(SECTOR(2), 2)))) + (item->AIBits & FOLLOW && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2)))) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; @@ -221,11 +220,11 @@ namespace TEN::Entities::Creatures::TR3 case CIVVY_STATE_WALK_FORWARD: creature->MaxTurn = CIVVY_WALK_TURN_RATE_MAX; - head = laraAiInfo.angle; + extraHeadRot.y = laraAI.angle; if (item->AIBits & PATROL1) { - head = 0; + extraHeadRot.y = 0; item->Animation.TargetState = CIVVY_STATE_WALK_FORWARD; } else if (creature->Mood == MoodType::Escape) @@ -252,7 +251,7 @@ namespace TEN::Entities::Creatures::TR3 tilt = angle / 2; if (AI.ahead) - head = AI.angle; + extraHeadRot.y = AI.angle; if (item->AIBits & GUARD) item->Animation.TargetState = CIVVY_WAIT; @@ -262,7 +261,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = CIVVY_STATE_IDLE; break; } - else if ((item->AIBits & FOLLOW) && (creature->ReachedGoal || laraAiInfo.distance > pow(SECTOR(2), 2))) + else if ((item->AIBits & FOLLOW) && (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) item->Animation.TargetState = CIVVY_STATE_IDLE; else if (creature->Mood == MoodType::Bored) item->Animation.TargetState = CIVVY_STATE_WALK_FORWARD; @@ -273,11 +272,12 @@ namespace TEN::Entities::Creatures::TR3 case CIVVY_AIM0: creature->MaxTurn = CIVVY_WALK_TURN_RATE_MAX; + creature->Flags = 0; if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (AI.bite && AI.distance < CIVVY_ATTACK0_RANGE) @@ -285,16 +285,16 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = CIVVY_STATE_IDLE; - creature->Flags = 0; break; case CIVVY_AIM1: creature->MaxTurn = CIVVY_WALK_TURN_RATE_MAX; + creature->Flags = 0; if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (AI.ahead && AI.distance < CIVVY_ATTACK1_RANGE) @@ -302,7 +302,6 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = CIVVY_STATE_IDLE; - creature->Flags = 0; break; case CIVVY_AIM2: @@ -311,8 +310,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (AI.bite && AI.distance < CIVVY_ATTACK2_RANGE) @@ -327,8 +326,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (!creature->Flags && item->TestBits(JointBitType::Touch, CivvyAttackJoints)) @@ -346,8 +345,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (!creature->Flags && item->TestBits(JointBitType::Touch, CivvyAttackJoints)) @@ -368,8 +367,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (creature->Flags != 2 && item->TestBits(JointBitType::Touch, CivvyAttackJoints)) @@ -385,9 +384,9 @@ namespace TEN::Entities::Creatures::TR3 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, torsoY); - CreatureJoint(item, 1, torsoX); - CreatureJoint(item, 2, head); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); + CreatureJoint(item, 2, extraHeadRot.y); if (item->Animation.ActiveState < CIVVY_DEATH) { diff --git a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp index aaff1fb58..322e88500 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp @@ -23,7 +23,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto COBRA_AWARE_RANGE = SQUARE(SECTOR(1.5f)); constexpr auto COBRA_SLEEP_RANGE = SQUARE(SECTOR(2.5f)); - constexpr auto PLAYER_DISTURB_VELOCITY = 15; + constexpr auto COBRA_DISTURBANCE_VELOCITY = 15; constexpr auto COBRA_SLEEP_FRAME = 45; const auto CobraBite = BiteInfo(Vector3::Zero, 13); @@ -41,12 +41,17 @@ namespace TEN::Entities::Creatures::TR3 enum CobraAnim { COBRA_ANIM_IDLE = 0, - COBRA_ANIM_WAKE_UP = 1, + COBRA_ANIM_SLEEP_TO_IDLE = 1, COBRA_ANIM_IDLE_TO_SLEEP = 2, COBRA_ANIM_BITE_ATTACK = 3, COBRA_ANIM_DEATH = 4 }; + enum CobraFlags + { + COBRA_FLAG_ATTACKING = (1 << 0) + }; + void InitialiseCobra(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; @@ -83,19 +88,23 @@ namespace TEN::Entities::Creatures::TR3 GetCreatureMood(item, &AI, 1); CreatureMood(item, &AI, 1); - bool enemyMoving = false; - bool enemyVisible = false; - if (creature->Enemy && (GlobalCounter & 2)) - { - auto src = GameVector(creature->Enemy->Pose.Position, creature->Enemy->RoomNumber); - auto dest = GameVector(item->Pose.Position, item->RoomNumber); - enemyVisible = LOS(&src, &dest); + bool isEnemyMoving = false; + bool isEnemyVisible = false; - enemyMoving = creature->Enemy->Animation.Velocity.z > PLAYER_DISTURB_VELOCITY || - abs(creature->Enemy->Animation.Velocity.y) > PLAYER_DISTURB_VELOCITY; + if (creature->Enemy != nullptr && (GlobalCounter & 2)) + { + auto origin = GameVector(creature->Enemy->Pose.Position, creature->Enemy->RoomNumber); + auto target = GameVector(item->Pose.Position, item->RoomNumber); + isEnemyVisible = LOS(&origin, &target); + + if (creature->Enemy->Animation.Velocity.z > COBRA_DISTURBANCE_VELOCITY || + abs(creature->Enemy->Animation.Velocity.y) > COBRA_DISTURBANCE_VELOCITY) + { + isEnemyMoving = true; + } } - if (enemyVisible && item->Animation.ActiveState != COBRA_STATE_SLEEP) + if (isEnemyVisible && item->Animation.ActiveState != COBRA_STATE_SLEEP) { creature->Target.x = creature->Enemy->Pose.Position.x; creature->Target.z = creature->Enemy->Pose.Position.z; @@ -118,12 +127,10 @@ namespace TEN::Entities::Creatures::TR3 creature->Flags = 0; if (AI.distance > COBRA_SLEEP_RANGE) - { item->Animation.TargetState = COBRA_STATE_SLEEP; - } - else if (creature->Enemy->HitPoints > 0 && enemyVisible && - ((AI.ahead && AI.distance < COBRA_ATTACK_RANGE && AI.verticalDistance <= GetBoundsAccurate(item)->Height()) || - item->HitStatus || enemyMoving)) + else if (creature->Enemy->HitPoints > 0 && isEnemyVisible && + ((AI.ahead && AI.distance < COBRA_ATTACK_RANGE && AI.verticalDistance <= GetBoundsAccurate(item)->Height()) || + item->HitStatus || isEnemyMoving)) { item->Animation.TargetState = COBRA_STATE_ATTACK; } @@ -148,12 +155,12 @@ namespace TEN::Entities::Creatures::TR3 break; case COBRA_STATE_ATTACK: - if (creature->Flags != 1 && + if (!(creature->Flags & COBRA_FLAG_ATTACKING) && item->TestBits(JointBitType::Touch, CobraAttackJoints)) { DoDamage(creature->Enemy, COBRA_BITE_ATTACK_DAMAGE); CreatureEffect(item, CobraBite, DoBloodSplat); - creature->Flags = 1; + creature->Flags |= COBRA_FLAG_ATTACKING; if (creature->Enemy->IsLara()) GetLaraInfo(creature->Enemy)->PoisonPotency += COBRA_BITE_POISON_POTENCY; diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index 7531abd3e..98b2038f7 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -44,32 +44,27 @@ namespace TEN::Entities::Creatures::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short torsoX = 0; - short torsoY = 0; short angle = 0; short tilt = 0; - short head = 0; + auto extraHeadRot = Vector3Shrt::Zero; + auto extraTorsoRot = Vector3Shrt::Zero; auto pos = Vector3Int(FlamethrowerBite.Position); GetJointAbsPosition(item, &pos, FlamethrowerBite.meshNum); - int random = GetRandomControl(); + int randomInt = GetRandomControl(); if (item->Animation.ActiveState != 6 && item->Animation.ActiveState != 11) { - TriggerDynamicLight(pos.x, pos.y, pos.z, (random & 3) + 6, 24 - ((random / 16) & 3), 16 - ((random / 64) & 3), random & 3); + TriggerDynamicLight(pos.x, pos.y, pos.z, (randomInt & 3) + 6, 24 - ((randomInt / 16) & 3), 16 - ((randomInt / 64) & 3), randomInt & 3); TriggerPilotFlame(itemNumber, 9); } else - TriggerDynamicLight(pos.x, pos.y, pos.z, (random & 3) + 10, 31 - ((random / 16) & 3), 24 - ((random / 64) & 3), random & 7); + TriggerDynamicLight(pos.x, pos.y, pos.z, (randomInt & 3) + 10, 31 - ((randomInt / 16) & 3), 24 - ((randomInt / 64) & 3), randomInt & 7); if (item->HitPoints <= 0) { if (item->Animation.ActiveState != 7) - { - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 19; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 7; - } + SetAnimation(item, 19); } else { @@ -84,9 +79,8 @@ namespace TEN::Entities::Creatures::TR3 ItemInfo* target = nullptr; int minDistance = INT_MAX; - for (int i = 0; i < ActiveCreatures.size(); i++) + for (auto& currentCreature : ActiveCreatures) { - auto* currentCreature = ActiveCreatures[i]; if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber) continue; @@ -149,11 +143,11 @@ namespace TEN::Entities::Creatures::TR3 case 1: creature->MaxTurn = 0; creature->Flags = 0; - head = laraAI.angle; + extraHeadRot.y = laraAI.angle; if (item->AIBits & GUARD) { - head = AIGuard(creature); + extraHeadRot.y = AIGuard(creature); if (TestProbability(0.008f)) item->Animation.TargetState = 4; @@ -179,11 +173,11 @@ namespace TEN::Entities::Creatures::TR3 break; case 4: - head = laraAI.angle; + extraHeadRot.y = laraAI.angle; if (item->AIBits & GUARD) { - head = AIGuard(creature); + extraHeadRot.y = AIGuard(creature); if (TestProbability(0.008f)) item->Animation.TargetState = 1; @@ -202,17 +196,12 @@ namespace TEN::Entities::Creatures::TR3 break; case 2: - creature->Flags = 0; creature->MaxTurn = ANGLE(5.0f); - head = laraAI.angle; + creature->Flags = 0; + extraHeadRot.y = laraAI.angle; if (item->AIBits & GUARD) - { - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 12; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 1; - item->Animation.TargetState = 1; - } + SetAnimation(item, 12); else if (item->AIBits & PATROL1) item->Animation.TargetState = 2; else if (creature->Mood == MoodType::Escape) @@ -237,8 +226,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; if (Targetable(item, &AI) && AI.distance < pow(SECTOR(4), 2) && @@ -257,8 +246,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; if (Targetable(item, &AI) && AI.distance < pow(SECTOR(4), 2) && @@ -278,8 +267,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; if (Targetable(item, &AI) && AI.distance < pow(SECTOR(4), 2) && @@ -313,12 +302,12 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; if (Targetable(item, &AI) && AI.distance < pow(SECTOR(4), 2) && - (realEnemy != LaraItem || creature->HurtByLara)) + (!realEnemy->IsLara() || creature->HurtByLara)) { item->Animation.TargetState = 6; } @@ -345,9 +334,9 @@ namespace TEN::Entities::Creatures::TR3 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, torsoY); - CreatureJoint(item, 1, torsoX); - CreatureJoint(item, 2, head); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); + CreatureJoint(item, 2, extraHeadRot.y); CreatureAnimation(itemNumber, angle, 0); } From d568187ce9d885158b24769cf2fb32013cd52960 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 19:08:53 +1000 Subject: [PATCH 024/106] Cleanup --- TombEngine/Game/itemdata/creature_info.h | 71 ++++++------ .../Objects/TR3/Entity/tr3_scuba_diver.cpp | 78 ++++++------- TombEngine/Objects/TR3/Entity/tr3_shiva.cpp | 106 +++++++++--------- TombEngine/Specific/phd_global.h | 9 ++ 4 files changed, 129 insertions(+), 135 deletions(-) diff --git a/TombEngine/Game/itemdata/creature_info.h b/TombEngine/Game/itemdata/creature_info.h index 85cf640ff..32c06190b 100644 --- a/TombEngine/Game/itemdata/creature_info.h +++ b/TombEngine/Game/itemdata/creature_info.h @@ -15,7 +15,7 @@ struct BOX_NODE enum ZoneType : char { ZONE_NULL = -1, // default zone - ZONE_SKELLY = 0, + ZONE_SKELLY, ZONE_BASIC, ZONE_FLYER, ZONE_HUMAN_CLASSIC, @@ -27,8 +27,8 @@ enum ZoneType : char ZONE_HUMAN_JUMP, ZONE_SPIDER, ZONE_BLOCKABLE, // for trex, shiva, etc.. - ZONE_SOPHIALEE, // dont want sophia to go down again ! - ZONE_APE, // only 2 click climb + ZONE_SOPHIALEE, // dont want sophia to go down again. + ZONE_APE, // only half block climb ZONE_HUMAN_LONGJUMP_AND_MONKEY, }; @@ -49,18 +49,19 @@ struct LOTInfo int RequiredBox; short Fly; - bool CanJump; - bool CanMonkey; - bool IsJumping; - bool IsMonkeying; - bool IsAmphibious; + bool CanJump = false; + bool CanMonkey = false; + bool IsJumping = false; + bool IsMonkeying = false; + bool IsAmphibious = false; - Vector3Int Target; - ZoneType Zone; + Vector3Int Target = Vector3Int::Zero; + ZoneType Zone = ZoneType::ZONE_NULL; }; enum class MoodType { + None, Bored, Attack, Escape, @@ -77,38 +78,36 @@ enum class CreatureAIPriority struct CreatureInfo { - short ItemNumber; + short ItemNumber = -1; - short MaxTurn; - short JointRotation[4]; - bool HeadLeft; - bool HeadRight; + LOTInfo LOT = {}; + MoodType Mood = MoodType::None; + ItemInfo* Enemy = nullptr; + ItemInfo* AITarget = nullptr; + short AITargetNumber = -1; + Vector3Int Target = Vector3Int::Zero; - bool Patrol; // Unused? - bool Alerted; - bool Friendly; - bool HurtByLara; - bool Poisoned; - bool JumpAhead; - bool MonkeySwingAhead; - bool ReachedGoal; + short MaxTurn = 0; + short JointRotation[4] = {}; + bool HeadLeft = false; + bool HeadRight = false; + bool Patrol = false; // Unused? + bool Alerted = false; + bool Friendly = false; + bool HurtByLara = false; + bool Poisoned = false; + bool JumpAhead = false; + bool MonkeySwingAhead = false; + bool ReachedGoal = false; + + short FiredWeapon; short Tosspad; short LocationAI; - short FiredWeapon; - - LOTInfo LOT; - MoodType Mood; - ItemInfo* Enemy; - short AITargetNumber; - ItemInfo* AITarget; - short Pad; // Unused? - Vector3Int Target; + short Flags = 0; #ifdef CREATURE_AI_PRIORITY_OPTIMIZATION - CreatureAIPriority Priority; - size_t FramesSinceLOTUpdate; + CreatureAIPriority Priority = CreatureAIPriority::None; + size_t FramesSinceLOTUpdate = 0; #endif - - short Flags; }; diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp index c290527e4..095ee262e 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp @@ -60,23 +60,23 @@ namespace TEN::Entities::Creatures::TR3 static void ShootHarpoon(ItemInfo* item, Vector3Int pos, short velocity, short yRot, short roomNumber) { short harpoonItemNumber = CreateItem(); - if (harpoonItemNumber != NO_ITEM) - { - auto* harpoonItem = &g_Level.Items[harpoonItemNumber]; + if (harpoonItemNumber == NO_ITEM) + return; - harpoonItem->ObjectNumber = ID_SCUBA_HARPOON; - harpoonItem->RoomNumber = item->RoomNumber; - harpoonItem->Pose.Position = pos; + auto* harpoonItem = &g_Level.Items[harpoonItemNumber]; - InitialiseItem(harpoonItemNumber); + harpoonItem->ObjectNumber = ID_SCUBA_HARPOON; + harpoonItem->RoomNumber = item->RoomNumber; + harpoonItem->Pose.Position = pos; - harpoonItem->Animation.Velocity.z = 150; - harpoonItem->Pose.Orientation.x = 0; - harpoonItem->Pose.Orientation.y = yRot; + InitialiseItem(harpoonItemNumber); - AddActiveItem(harpoonItemNumber); - harpoonItem->Status = ITEM_ACTIVE; - } + harpoonItem->Animation.Velocity.z = 150.0f; + harpoonItem->Pose.Orientation.x = 0; + harpoonItem->Pose.Orientation.y = yRot; + + AddActiveItem(harpoonItemNumber); + harpoonItem->Status = ITEM_ACTIVE; } void ScubaHarpoonControl(short itemNumber) @@ -91,14 +91,7 @@ namespace TEN::Entities::Creatures::TR3 } else { - int ox = item->Pose.Position.x; - int oz = item->Pose.Position.z; - - int velocity = item->Animation.Velocity.z * phd_cos(item->Pose.Orientation.x); - - item->Pose.Position.z += velocity * phd_cos(item->Pose.Orientation.y); - item->Pose.Position.x += velocity * phd_sin(item->Pose.Orientation.y); - item->Pose.Position.y += -item->Animation.Velocity.z * phd_sin(item->Pose.Orientation.x); + TranslateItem(item, item->Pose.Orientation, item->Animation.Velocity.z); auto probe = GetCollision(item); @@ -123,7 +116,8 @@ namespace TEN::Entities::Creatures::TR3 short head = 0; short neck = 0; - int waterHeight; + int waterHeight = 0; + if (item->HitPoints <= 0) { if (item->Animation.ActiveState != SDIVER_STATE_DEATH) @@ -140,22 +134,23 @@ namespace TEN::Entities::Creatures::TR3 GetCreatureMood(item, &AI, false); CreatureMood(item, &AI, false); - GameVector origin; - GameVector target; bool shoot = false; - if (Lara.Control.WaterStatus == WaterStatus::Dry) { - origin.x = item->Pose.Position.x; - origin.y = item->Pose.Position.y - CLICK(1); - origin.z = item->Pose.Position.z; - origin.roomNumber = item->RoomNumber; - - target.x = LaraItem->Pose.Position.x; - target.y = LaraItem->Pose.Position.y - (LARA_HEIGHT - 150); - target.z = LaraItem->Pose.Position.z; + auto origin = GameVector( + item->Pose.Position.x, + item->Pose.Position.y - CLICK(1), + item->Pose.Position.z, + item->RoomNumber + ); + auto target = GameVector( + LaraItem->Pose.Position.x, + LaraItem->Pose.Position.y - (LARA_HEIGHT - 150), + LaraItem->Pose.Position.z + ); shoot = LOS(&origin, &target); + if (shoot) creature->Target = LaraItem->Pose.Position; @@ -164,19 +159,11 @@ namespace TEN::Entities::Creatures::TR3 } else if (AI.angle > -ANGLE(45.0f) && AI.angle < ANGLE(45.0f)) { - origin.x = item->Pose.Position.x; - origin.y = item->Pose.Position.y; - origin.z = item->Pose.Position.z; - origin.roomNumber = item->RoomNumber; - - target.x = LaraItem->Pose.Position.x; - target.y = LaraItem->Pose.Position.y; - target.z = LaraItem->Pose.Position.z; - + auto origin = GameVector(item->Pose.Position, item->RoomNumber); + auto target = GameVector(LaraItem->Pose.Position); + shoot = LOS(&origin, &target); } - else - shoot = false; angle = CreatureTurn(item, creature->MaxTurn); waterHeight = GetWaterSurface(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber) + SECTOR(0.5f); @@ -202,7 +189,7 @@ namespace TEN::Entities::Creatures::TR3 break; case SDIVER_STATE_SWIM_AIM: - creature->Flags = NULL; + creature->Flags = 0; if (shoot) neck = -AI.angle; @@ -270,7 +257,6 @@ namespace TEN::Entities::Creatures::TR3 } break; - } } diff --git a/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp b/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp index b5fd5f8cb..0db04d15f 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_shiva.cpp @@ -208,15 +208,15 @@ namespace TEN::Entities::Creatures::TR3 return; auto* item = &g_Level.Items[itemNumber]; - auto* shiva = GetCreatureInfo(item); + auto* creature = GetCreatureInfo(item); - auto pos = Vector3Int(0, 0, 256); - bool laraAlive = LaraItem->HitPoints > 0; + auto pos = Vector3Int(0, 0, CLICK(1)); + bool isLaraAlive = LaraItem->HitPoints > 0; - Vector3Shrt extraHeadRot; - Vector3Shrt extraTorsoRot; short angle = 0; short tilt = 0; + Vector3Shrt extraHeadRot = Vector3Shrt::Zero; + Vector3Shrt extraTorsoRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { @@ -235,13 +235,13 @@ namespace TEN::Entities::Creatures::TR3 GetCreatureMood(item, &AI, true); CreatureMood(item, &AI, true); - if (shiva->Mood == MoodType::Escape) + if (creature->Mood == MoodType::Escape) { - shiva->Target.x = LaraItem->Pose.Position.x; - shiva->Target.z = LaraItem->Pose.Position.z; + creature->Target.x = LaraItem->Pose.Position.x; + creature->Target.z = LaraItem->Pose.Position.z; } - angle = CreatureTurn(item, shiva->MaxTurn); + angle = CreatureTurn(item, creature->MaxTurn); if (item->Animation.ActiveState != SHIVA_STATE_INACTIVE) item->MeshBits = ALL_JOINT_BITS; @@ -251,15 +251,15 @@ namespace TEN::Entities::Creatures::TR3 switch (item->Animation.ActiveState) { case SHIVA_STATE_INACTIVE: - shiva->MaxTurn = 0; + creature->MaxTurn = 0; - if (!shiva->Flags) + if (!creature->Flags) { if (!item->MeshBits) effectMesh = 0; item->MeshBits = (item->MeshBits * 2) + 1; - shiva->Flags = 1; + creature->Flags = 1; GetJointAbsPosition(item, &pos, effectMesh++); TriggerExplosionSparks(pos.x, pos.y, pos.z, 2, 0, 0, item->RoomNumber); @@ -267,45 +267,45 @@ namespace TEN::Entities::Creatures::TR3 } else - shiva->Flags--; + creature->Flags--; if (item->MeshBits == 0x7FFFFFFF) { item->Animation.TargetState = SHIVA_STATE_IDLE; - shiva->Flags = -45; + creature->Flags = -45; effectMesh = 0; } break; case SHIVA_STATE_IDLE: - shiva->MaxTurn = 0; + creature->MaxTurn = 0; if (AI.ahead) extraHeadRot.y = AI.angle; - if (shiva->Flags < 0) + if (creature->Flags < 0) { - shiva->Flags++; + creature->Flags++; TriggerShivaSmoke(item->Pose.Position.x + (GetRandomControl() & 0x5FF) - 0x300, pos.y - (GetRandomControl() & 0x5FF), item->Pose.Position.z + (GetRandomControl() & 0x5FF) - 0x300, 1); break; } - if (shiva->Flags == 1) - shiva->Flags = 0; + if (creature->Flags == 1) + creature->Flags = 0; - if (shiva->Mood == MoodType::Escape) + if (creature->Mood == MoodType::Escape) { int x = item->Pose.Position.x + SECTOR(1) * phd_sin(item->Pose.Orientation.y + ANGLE(180.0f)); int z = item->Pose.Position.z + SECTOR(1) * phd_cos(item->Pose.Orientation.y + ANGLE(180.0f)); auto box = GetCollision(x, item->Pose.Position.y, z, item->RoomNumber).BottomBlock->Box; - if (box != NO_BOX && !(g_Level.Boxes[box].flags & BLOCKABLE) && !shiva->Flags) + if (box != NO_BOX && !(g_Level.Boxes[box].flags & BLOCKABLE) && !creature->Flags) item->Animation.TargetState = SHIVA_STATE_WALK_BACK; else item->Animation.TargetState = SHIVA_STATE_GUARD_IDLE; } - else if (shiva->Mood == MoodType::Bored) + else if (creature->Mood == MoodType::Bored) { if (TestProbability(0.0325f)) item->Animation.TargetState = SHIVA_STATE_WALK_FORWARD; @@ -313,17 +313,17 @@ namespace TEN::Entities::Creatures::TR3 else if (AI.bite && AI.distance < pow(SECTOR(1.25f), 2)) { item->Animation.TargetState = SHIVA_STATE_GRAB_ATTACK; - shiva->Flags = 0; + creature->Flags = 0; } else if (AI.bite && AI.distance < pow(SECTOR(4) / 3, 2)) { item->Animation.TargetState = SHIVA_STATE_DOWNWARD_ATTACK; - shiva->Flags = 0; + creature->Flags = 0; } else if (item->HitStatus && AI.ahead) { item->Animation.TargetState = SHIVA_STATE_GUARD_IDLE; - shiva->Flags = 4; + creature->Flags = 4; } else item->Animation.TargetState = SHIVA_STATE_WALK_FORWARD; @@ -331,103 +331,103 @@ namespace TEN::Entities::Creatures::TR3 break; case SHIVA_STATE_GUARD_IDLE: - shiva->MaxTurn = 0; + creature->MaxTurn = 0; if (AI.ahead) extraHeadRot.y = AI.angle; - if (item->HitStatus || shiva->Mood == MoodType::Escape) - shiva->Flags = 4; + if (item->HitStatus || creature->Mood == MoodType::Escape) + creature->Flags = 4; if (AI.bite && AI.distance < pow(SECTOR(4) / 3, 2) || (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase && - !shiva->Flags) || + !creature->Flags) || !AI.ahead) { item->Animation.TargetState = SHIVA_STATE_IDLE; - shiva->Flags = 0; + creature->Flags = 0; } - else if (shiva->Flags) + else if (creature->Flags) item->Animation.TargetState = SHIVA_STATE_GUARD_IDLE; if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase && - shiva->Flags > 1) + creature->Flags > 1) { - shiva->Flags -= 2; + creature->Flags -= 2; } break; case SHIVA_STATE_WALK_FORWARD: - shiva->MaxTurn = SHIVA_WALK_TURN_RATE_MAX; + creature->MaxTurn = SHIVA_WALK_TURN_RATE_MAX; if (AI.ahead) extraHeadRot.y = AI.angle; - if (shiva->Mood == MoodType::Escape) + if (creature->Mood == MoodType::Escape) item->Animation.TargetState = SHIVA_STATE_IDLE; - else if (shiva->Mood == MoodType::Bored) + else if (creature->Mood == MoodType::Bored) item->Animation.TargetState = SHIVA_STATE_IDLE; else if (AI.bite && AI.distance < pow(SECTOR(4) / 3, 2)) { item->Animation.TargetState = SHIVA_STATE_IDLE; - shiva->Flags = 0; + creature->Flags = 0; } else if (item->HitStatus) { item->Animation.TargetState = SHIVA_STATE_WALK_FORWARD_GUARDING; - shiva->Flags = 4; + creature->Flags = 4; } break; case SHIVA_STATE_WALK_FORWARD_GUARDING: - shiva->MaxTurn = SHIVA_WALK_TURN_RATE_MAX; + creature->MaxTurn = SHIVA_WALK_TURN_RATE_MAX; if (AI.ahead) extraHeadRot.y = AI.angle; if (item->HitStatus) - shiva->Flags = 4; + creature->Flags = 4; if (AI.bite && AI.distance < pow(SECTOR(1.25f), 2) || (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase && - !shiva->Flags)) + !creature->Flags)) { item->Animation.TargetState = SHIVA_STATE_WALK_FORWARD; - shiva->Flags = 0; + creature->Flags = 0; } - else if (shiva->Flags) + else if (creature->Flags) item->Animation.TargetState = SHIVA_STATE_WALK_FORWARD_GUARDING; if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase) - shiva->Flags = 0; + creature->Flags = 0; break; case SHIVA_STATE_WALK_BACK: - shiva->MaxTurn = SHIVA_WALK_TURN_RATE_MAX; + creature->MaxTurn = SHIVA_WALK_TURN_RATE_MAX; if (AI.ahead) extraHeadRot.y = AI.angle; if (AI.ahead && AI.distance < pow(SECTOR(4) / 3, 2) || (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase && - !shiva->Flags)) + !creature->Flags)) { item->Animation.TargetState = SHIVA_STATE_IDLE; } else if (item->HitStatus) { item->Animation.TargetState = SHIVA_STATE_IDLE; - shiva->Flags = 4; + creature->Flags = 4; } break; case SHIVA_STATE_GRAB_ATTACK: - shiva->MaxTurn = SHIVA_ATTACK_TURN_RATE_MAX; + creature->MaxTurn = SHIVA_ATTACK_TURN_RATE_MAX; if (AI.ahead) { @@ -435,22 +435,22 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot = Vector3Shrt(AI.xAngle, AI.angle, 0); } - ShivaDamage(item, shiva, SHIVA_GRAB_ATTACK_DAMAGE); + ShivaDamage(item, creature, SHIVA_GRAB_ATTACK_DAMAGE); break; case SHIVA_STATE_DOWNWARD_ATTACK: - shiva->MaxTurn = SHIVA_ATTACK_TURN_RATE_MAX; + creature->MaxTurn = SHIVA_ATTACK_TURN_RATE_MAX; extraHeadRot.y = AI.angle; extraTorsoRot.y = AI.angle; if (AI.xAngle > 0) extraTorsoRot.x = AI.xAngle; - ShivaDamage(item, shiva, SHIVA_DOWNWARD_ATTACK_DAMAGE); + ShivaDamage(item, creature, SHIVA_DOWNWARD_ATTACK_DAMAGE); break; case SHIVA_STATE_KILL: - shiva->MaxTurn = 0; + creature->MaxTurn = 0; extraHeadRot = Vector3Shrt::Zero; extraTorsoRot = Vector3Shrt::Zero; @@ -467,7 +467,7 @@ namespace TEN::Entities::Creatures::TR3 } // Dispatch kill animation. - if (laraAlive && LaraItem->HitPoints <= 0) + if (isLaraAlive && LaraItem->HitPoints <= 0) { item->Animation.TargetState = SHIVA_STATE_KILL; diff --git a/TombEngine/Specific/phd_global.h b/TombEngine/Specific/phd_global.h index 2deef2cef..44b22b53c 100644 --- a/TombEngine/Specific/phd_global.h +++ b/TombEngine/Specific/phd_global.h @@ -356,6 +356,15 @@ struct GameVector this->boxNumber = boxNumber; } + GameVector(Vector3Int& pos) + { + this->x = pos.x; + this->y = pos.y; + this->z = pos.z; + this->roomNumber = 0; + this->boxNumber = 0; + } + GameVector(Vector3Int& pos, short roomNumber) { this->x = pos.x; From c714716f8d356fedeb6f705e7112c7e67dc1c65b Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 20:06:32 +1000 Subject: [PATCH 025/106] Convert ZoneType enum to enum class --- TombEngine/Game/control/box.cpp | 16 +-- TombEngine/Game/control/lot.cpp | 109 +++++++++--------- TombEngine/Game/itemdata/creature_info.h | 56 ++++----- TombEngine/Game/people.cpp | 36 +++--- TombEngine/Objects/TR1/tr1_objects.cpp | 8 +- .../Objects/TR2/Entity/tr2_sword_guardian.cpp | 4 +- TombEngine/Objects/TR2/tr2_objects.cpp | 10 +- TombEngine/Objects/TR3/tr3_objects.cpp | 6 +- TombEngine/Objects/TR4/tr4_objects.cpp | 76 ++++++------ TombEngine/Objects/TR5/tr5_objects.cpp | 56 ++++----- TombEngine/Specific/setup.cpp | 2 +- TombEngine/Specific/setup.h | 10 +- 12 files changed, 195 insertions(+), 194 deletions(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 8e7e99e0e..0b6c24a1a 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -157,7 +157,7 @@ void CreatureYRot2(PHD_3DPOS* srcPos, short angle, short angleAdd) bool SameZone(CreatureInfo* creature, ItemInfo* target) { - int* zone = g_Level.Zones[creature->LOT.Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)(int)creature->LOT.Zone][FlipStatus].data(); auto* item = &g_Level.Items[creature->ItemNumber]; auto* room = &g_Level.Rooms[item->RoomNumber]; @@ -455,7 +455,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) auto* creature = GetCreatureInfo(item); auto* LOT = &creature->LOT; - int* zone = g_Level.Zones[LOT->Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)LOT->Zone][FlipStatus].data(); int boxHeight; if (item->BoxNumber != NO_BOX) @@ -884,7 +884,7 @@ int ValidBox(ItemInfo* item, short zoneNumber, short boxNumber) return false; auto* creature = GetCreatureInfo(item); - int* zone = g_Level.Zones[creature->LOT.Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)creature->LOT.Zone][FlipStatus].data(); if (creature->LOT.Fly == NO_FLYING && zone[boxNumber] != zoneNumber) return false; @@ -970,7 +970,7 @@ int UpdateLOT(LOTInfo* LOT, int depth) int SearchLOT(LOTInfo* LOT, int depth) { - int* zone = g_Level.Zones[LOT->Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)LOT->Zone][FlipStatus].data(); int searchZone = zone[LOT->Head]; if (depth <= 0) @@ -1375,7 +1375,7 @@ void FindAITargetObject(CreatureInfo* creature, short objectNumber) if (aiObject->objectNumber == objectNumber && aiObject->triggerFlags == item->ItemFlags[3] && aiObject->roomNumber != NO_ROOM) { - int* zone = g_Level.Zones[creature->LOT.Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)creature->LOT.Zone][FlipStatus].data(); auto* room = &g_Level.Rooms[item->RoomNumber]; item->BoxNumber = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z)->Box; @@ -1435,7 +1435,7 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI) creature->Enemy = LaraItem; } - int* zone = g_Level.Zones[creature->LOT.Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)creature->LOT.Zone][FlipStatus].data(); auto* room = &g_Level.Rooms[item->RoomNumber]; item->BoxNumber = NO_BOX; @@ -1457,8 +1457,8 @@ void CreatureAIInfo(ItemInfo* item, AI_INFO* AI) // This prevents enemies from running to Lara and attacking nothing when she is hanging or shimmying. -- Lwmte, 27.06.22 bool reachable = false; - if (object->zoneType == ZoneType::ZONE_FLYER || - (object->zoneType == ZoneType::ZONE_WATER && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item->RoomNumber))) + if (object->ZoneType == ZoneType::Flyer || + (object->ZoneType == ZoneType::Water && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, item->RoomNumber))) { reachable = true; // If NPC is flying or swimming in water, always reach Lara } diff --git a/TombEngine/Game/control/lot.cpp b/TombEngine/Game/control/lot.cpp index 712558575..83cf70a2d 100644 --- a/TombEngine/Game/control/lot.cpp +++ b/TombEngine/Game/control/lot.cpp @@ -112,15 +112,15 @@ void DisableEntityAI(short itemNumber) item->Data = nullptr; } -void InitialiseSlot(short itemNum, short slot, bool makeTarget) +void InitialiseSlot(short itemNumber, short slot, bool makeTarget) { - auto* item = &g_Level.Items[itemNum]; - auto* obj = &Objects[item->ObjectNumber]; - + auto* item = &g_Level.Items[itemNumber]; + auto* object = &Objects[item->ObjectNumber]; item->Data = CreatureInfo(); auto* creature = GetCreatureInfo(item); - InitialiseLOTarray(itemNum); - creature->ItemNumber = itemNum; + + InitialiseLOTarray(itemNumber); + creature->ItemNumber = itemNumber; creature->Mood = MoodType::Bored; creature->JointRotation[0] = 0; creature->JointRotation[1] = 0; @@ -136,12 +136,12 @@ void InitialiseSlot(short itemNum, short slot, bool makeTarget) creature->MonkeySwingAhead = false; creature->LOT.CanJump = false; creature->LOT.CanMonkey = false; - creature->LOT.IsAmphibious = false; // only the crocodile can go water and land. (default: true) + creature->LOT.IsAmphibious = false; // True for crocodile by default as the only the crocodile that can move in water and on land. creature->LOT.IsJumping = false; creature->LOT.IsMonkeying = false; creature->MaxTurn = ANGLE(1); creature->Flags = 0; - creature->Enemy = NULL; + creature->Enemy = nullptr; creature->LOT.Fly = NO_FLYING; creature->LOT.BlockMask = BLOCKED; @@ -155,117 +155,116 @@ void InitialiseSlot(short itemNum, short slot, bool makeTarget) else creature->AITarget = nullptr; - switch (obj->zoneType) + switch (object->ZoneType) { default: - case ZONE_NULL: + case ZoneType::None: creature->LOT.Step = CLICK(1); creature->LOT.Drop = -CLICK(1); - obj->zoneType = ZONE_BASIC; // only entity that use CreatureActive() will reach InitialiseSlot() ! + object->ZoneType = ZoneType::Basic; // Only entities that use CreatureActive() will reach InitialiseSlot(). break; - case ZONE_SKELLY: - // Can jump + // Can jump. + case ZoneType::Skeleton: creature->LOT.Step = CLICK(1); creature->LOT.Drop = -CLICK(1); creature->LOT.CanJump = true; - creature->LOT.Zone = ZONE_SKELLY; + creature->LOT.Zone = ZoneType::Skeleton; break; - case ZONE_BASIC: + case ZoneType::Basic: creature->LOT.Step = CLICK(1); creature->LOT.Drop = -CLICK(1); - creature->LOT.Zone = ZONE_BASIC; + creature->LOT.Zone = ZoneType::Basic; break; - case ZONE_FLYER: - // Can fly + // Can fly. + case ZoneType::Flyer: creature->LOT.Step = SECTOR(20); creature->LOT.Drop = -SECTOR(20); creature->LOT.Fly = DEFAULT_FLY_UPDOWN_SPEED; - creature->LOT.Zone = ZONE_FLYER; + creature->LOT.Zone = ZoneType::Flyer; break; - case ZONE_WATER: - // Can swim + // Can swim. + case ZoneType::Water: creature->LOT.Step = SECTOR(20); creature->LOT.Drop = -SECTOR(20); - creature->LOT.Zone = ZONE_WATER; + creature->LOT.Zone = ZoneType::Water; if (item->ObjectNumber == ID_CROCODILE) { - creature->LOT.Fly = DEFAULT_SWIM_UPDOWN_SPEED / 2; // is more slow than the other underwater entity - creature->LOT.IsAmphibious = true; // crocodile can walk and swim. + creature->LOT.Fly = DEFAULT_SWIM_UPDOWN_SPEED / 2; // Slower than the other underwater creatures. + creature->LOT.IsAmphibious = true; // Can walk and swim. } else if (item->ObjectNumber == ID_BIG_RAT) { - creature->LOT.Fly = NO_FLYING; // dont want the bigrat to be able to go in water (just the surface !) - creature->LOT.IsAmphibious = true; // bigrat can walk and swim. + creature->LOT.Fly = NO_FLYING; // Can't swim underwater, only on the surface. + creature->LOT.IsAmphibious = true; // Can walk and swim. } else - { creature->LOT.Fly = DEFAULT_SWIM_UPDOWN_SPEED; - } + break; - case ZONE_HUMAN_CLASSIC: - // Can climb + // Can climb. + case ZoneType::HumanClassic: creature->LOT.Step = SECTOR(1); creature->LOT.Drop = -SECTOR(1); - creature->LOT.Zone = ZONE_HUMAN_CLASSIC; + creature->LOT.Zone = ZoneType::HumanClassic; break; - case ZONE_HUMAN_JUMP: - // Can climb and jump + // Can climb and jump. + case ZoneType::HumanJump: creature->LOT.Step = SECTOR(1); creature->LOT.Drop = -SECTOR(1); creature->LOT.CanJump = true; - creature->LOT.Zone = ZONE_HUMAN_CLASSIC; + creature->LOT.Zone = ZoneType::HumanClassic; break; - case ZONE_HUMAN_JUMP_AND_MONKEY: - // Can climb, jump, monkey + // Can climb, jump, monkeyswing. + case ZoneType::HumanJumpAndMonkey: creature->LOT.Step = SECTOR(1); creature->LOT.Drop = -SECTOR(1); creature->LOT.CanJump = true; creature->LOT.CanMonkey = true; - creature->LOT.Zone = ZONE_HUMAN_CLASSIC; + creature->LOT.Zone = ZoneType::HumanClassic; break; - case ZONE_HUMAN_LONGJUMP_AND_MONKEY: - // Can climb, jump, monkey, long jump + // Can climb, jump, monkey swing, long jump. + case ZoneType::HumanLongJumpAndMonkey: creature->LOT.Step = SECTOR(1) + CLICK(3); creature->LOT.Drop = -(SECTOR(1) + CLICK(3)); creature->LOT.CanJump = true; creature->LOT.CanMonkey = true; - creature->LOT.Zone = ZONE_VON_CROY; + creature->LOT.Zone = ZoneType::VonCroy; break; - case ZONE_SPIDER: + case ZoneType::Spider: creature->LOT.Step = SECTOR(1) - CLICK(2); creature->LOT.Drop = -(SECTOR(1) - CLICK(2)); - creature->LOT.Zone = ZONE_HUMAN_CLASSIC; + creature->LOT.Zone = ZoneType::HumanClassic; break; - case ZONE_BLOCKABLE: + case ZoneType::Blockable: creature->LOT.BlockMask = BLOCKABLE; - creature->LOT.Zone = ZONE_BASIC; + creature->LOT.Zone = ZoneType::Basic; break; - case ZONE_APE: + case ZoneType::Ape: creature->LOT.Step = CLICK(2); creature->LOT.Drop = -SECTOR(1); break; - case ZONE_SOPHIALEE: + case ZoneType::SophiaLee: creature->LOT.Step = SECTOR(1); creature->LOT.Drop = -CLICK(3); - creature->LOT.Zone = ZONE_HUMAN_CLASSIC; + creature->LOT.Zone = ZoneType::HumanClassic; break; } ClearLOT(&creature->LOT); - if (itemNum != Lara.ItemNumber) + if (itemNumber != Lara.ItemNumber) CreateZone(item); SlotsUsed++; @@ -304,16 +303,16 @@ void ClearLOT(LOTInfo* LOT) void CreateZone(ItemInfo* item) { auto* creature = GetCreatureInfo(item); - auto* r = &g_Level.Rooms[item->RoomNumber]; + auto* room = &g_Level.Rooms[item->RoomNumber]; - item->BoxNumber = GetSector(r, item->Pose.Position.x - r->x, item->Pose.Position.z - r->z)->Box; + item->BoxNumber = GetSector(room, item->Pose.Position.x - room->x, item->Pose.Position.z - room->z)->Box; if (creature->LOT.Fly) { - BOX_NODE* node = creature->LOT.Node.data(); + auto* node = creature->LOT.Node.data(); creature->LOT.ZoneCount = 0; - for (int i = 0; i < g_Level.Boxes.size(); i++) + for (size_t i = 0; i < g_Level.Boxes.size(); i++) { node->boxNumber = i; node++; @@ -322,8 +321,8 @@ void CreateZone(ItemInfo* item) } else { - int* zone = g_Level.Zones[creature->LOT.Zone][0].data(); - int* flippedZone = g_Level.Zones[creature->LOT.Zone][1].data(); + int* zone = g_Level.Zones[(int)creature->LOT.Zone][0].data(); + int* flippedZone = g_Level.Zones[(int)creature->LOT.Zone][1].data(); int zoneNumber = zone[item->BoxNumber]; int flippedZoneNumber = flippedZone[item->BoxNumber]; @@ -331,7 +330,7 @@ void CreateZone(ItemInfo* item) auto* node = creature->LOT.Node.data(); creature->LOT.ZoneCount = 0; - for (int i = 0; i < g_Level.Boxes.size(); i++) + for (size_t i = 0; i < g_Level.Boxes.size(); i++) { if (*zone == zoneNumber || *flippedZone == flippedZoneNumber) { diff --git a/TombEngine/Game/itemdata/creature_info.h b/TombEngine/Game/itemdata/creature_info.h index 32c06190b..c76d9bc4e 100644 --- a/TombEngine/Game/itemdata/creature_info.h +++ b/TombEngine/Game/itemdata/creature_info.h @@ -1,7 +1,8 @@ #pragma once -#include #include "Specific/phd_global.h" +using std::vector; + struct ItemInfo; struct BOX_NODE @@ -12,34 +13,37 @@ struct BOX_NODE int boxNumber; }; -enum ZoneType : char +enum class ZoneType { - ZONE_NULL = -1, // default zone - ZONE_SKELLY, - ZONE_BASIC, - ZONE_FLYER, - ZONE_HUMAN_CLASSIC, - ZONE_VON_CROY, - ZONE_WATER, - ZONE_MAX, - /// custom zone (using zone above for LOT.zone): - ZONE_HUMAN_JUMP_AND_MONKEY, - ZONE_HUMAN_JUMP, - ZONE_SPIDER, - ZONE_BLOCKABLE, // for trex, shiva, etc.. - ZONE_SOPHIALEE, // dont want sophia to go down again. - ZONE_APE, // only half block climb - ZONE_HUMAN_LONGJUMP_AND_MONKEY, + None = -1, + Skeleton, + Basic, + Flyer, + HumanClassic, + VonCroy, + Water, + Max, + + // Custom zones (above zones are used for LOT.zone): + HumanJumpAndMonkey, + HumanJump, + Spider, + Blockable, // For large creatures such as trex and shiva. + SophiaLee, // Prevents Sophia from going to lower levels again. + Ape, // Only 0.5 block climb. + HumanLongJumpAndMonkey, }; struct LOTInfo { bool Initialised; - std::vector Node; + vector Node; int Head; int Tail; + ZoneType Zone = ZoneType::None; + Vector3Int Target = Vector3Int::Zero; int SearchNumber; int BlockMask; short Step; @@ -49,14 +53,12 @@ struct LOTInfo int RequiredBox; short Fly; - bool CanJump = false; - bool CanMonkey = false; - bool IsJumping = false; - bool IsMonkeying = false; + bool CanJump = false; + bool CanMonkey = false; + bool IsJumping = false; + bool IsMonkeying = false; bool IsAmphibious = false; - Vector3Int Target = Vector3Int::Zero; - ZoneType Zone = ZoneType::ZONE_NULL; }; enum class MoodType @@ -71,9 +73,9 @@ enum class MoodType enum class CreatureAIPriority { None, - High, + Low, Medium, - Low + High }; struct CreatureInfo diff --git a/TombEngine/Game/people.cpp b/TombEngine/Game/people.cpp index d0d4ee188..688ca2fc5 100644 --- a/TombEngine/Game/people.cpp +++ b/TombEngine/Game/people.cpp @@ -145,32 +145,32 @@ bool TargetVisible(ItemInfo* item, AI_INFO* AI, float maxAngle) return false; // Check just in case. - auto* creatureInfo = GetCreatureInfo(item); - if (creatureInfo == nullptr) + auto* creature = GetCreatureInfo(item); + if (creature == nullptr) return false; - auto* enemy = creatureInfo->Enemy; + auto* enemy = creature->Enemy; if (enemy == nullptr || enemy->HitPoints == 0) return false; - short angle = AI->angle - creatureInfo->JointRotation[2]; - if (angle > -ANGLE(maxAngle) && angle < ANGLE(maxAngle)) + short angle = AI->angle - creature->JointRotation[2]; + if (angle > ANGLE(-maxAngle) && angle < ANGLE(maxAngle)) { - GameVector start; - GameVector target; auto& bounds = GetBestFrame(enemy)->boundingBox; - start.x = item->Pose.Position.x; - start.y = item->Pose.Position.y - CLICK(3); - start.z = item->Pose.Position.z; - start.roomNumber = item->RoomNumber; - - target.x = enemy->Pose.Position.x; - target.y = enemy->Pose.Position.y + ((((bounds.Y1 * 2) + bounds.Y1) + bounds.Y2) / 4); - target.z = enemy->Pose.Position.z; - target.roomNumber = enemy->RoomNumber; // TODO: Check why this line didn't exist before. -- TokyoSU, 10/8/2022 - - return LOS(&start, &target); + auto origin = GameVector( + item->Pose.Position.x, + item->Pose.Position.y - CLICK(3), + item->Pose.Position.z, + item->RoomNumber + ); + auto target = GameVector( + enemy->Pose.Position.x, + enemy->Pose.Position.y + ((((bounds.Y1 * 2) + bounds.Y1) + bounds.Y2) / 4), + enemy->Pose.Position.z, + enemy->RoomNumber // TODO: Check why this line didn't exist before. -- TokyoSU, 10/8/2022 + ); + return LOS(&origin, &target); } return false; diff --git a/TombEngine/Objects/TR1/tr1_objects.cpp b/TombEngine/Objects/TR1/tr1_objects.cpp index 942ca6f0f..7a8b0c68f 100644 --- a/TombEngine/Objects/TR1/tr1_objects.cpp +++ b/TombEngine/Objects/TR1/tr1_objects.cpp @@ -77,7 +77,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_APE; + obj->ZoneType = ZoneType::Ape; } obj = &Objects[ID_BIG_RAT]; @@ -97,7 +97,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveAnim = true; obj->saveFlags = true; obj->waterCreature = true; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; obj->SetBoneRotation(1, ROT_Y); // head } @@ -173,7 +173,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_BLOCKABLE; + obj->ZoneType = ZoneType::Blockable; obj->SetBoneRotation(10, ROT_X | ROT_Y); } @@ -193,7 +193,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; obj->SetBoneRotation(1, ROT_Y); // torso obj->SetBoneRotation(2, ROT_Y); // head } diff --git a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp index 062eb22e9..699280d38 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp @@ -68,7 +68,7 @@ namespace TEN::Entities::Creatures::TR2 creature->LOT.Step = STEP_SIZE; creature->LOT.Drop = -STEP_SIZE; creature->LOT.Fly = NO_FLYING; - creature->LOT.Zone = ZONE_BASIC; + creature->LOT.Zone = ZoneType::Basic; AI_INFO AI; CreatureAIInfo(item, &AI); @@ -80,7 +80,7 @@ namespace TEN::Entities::Creatures::TR2 creature->LOT.Step = WALL_SIZE * 20; creature->LOT.Drop = -WALL_SIZE * 20; creature->LOT.Fly = STEP_SIZE / 4; - creature->LOT.Zone = ZONE_FLYER; + creature->LOT.Zone = ZoneType::Flyer; CreatureAIInfo(item, &AI); } } diff --git a/TombEngine/Objects/TR2/tr2_objects.cpp b/TombEngine/Objects/TR2/tr2_objects.cpp index 599a45b7d..33375d613 100644 --- a/TombEngine/Objects/TR2/tr2_objects.cpp +++ b/TombEngine/Objects/TR2/tr2_objects.cpp @@ -57,7 +57,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; g_Level.Bones[obj->boneIndex + 9 * 4] |= ROT_Y; } @@ -78,7 +78,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; } @@ -99,7 +99,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveAnim = true; obj->saveFlags = true; obj->pivotLength = 0; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; } obj = &Objects[ID_CROW]; @@ -118,7 +118,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveAnim = true; obj->saveFlags = true; obj->pivotLength = 0; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; } obj = &Objects[ID_RAT]; @@ -154,7 +154,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= (ROT_Y); g_Level.Bones[obj->boneIndex + 14 * 4] |= (ROT_Y); } diff --git a/TombEngine/Objects/TR3/tr3_objects.cpp b/TombEngine/Objects/TR3/tr3_objects.cpp index 4cd5a68ec..4a0503d97 100644 --- a/TombEngine/Objects/TR3/tr3_objects.cpp +++ b/TombEngine/Objects/TR3/tr3_objects.cpp @@ -7,7 +7,7 @@ #include "Specific/level.h" #include "Specific/setup.h" -// Entities +// Creatures #include "Objects/TR3/Entity/tr3_civvy.h" // OK #include "Objects/TR3/Entity/tr3_cobra.h" // OK #include "Objects/TR3/Entity/tr3_fish_emitter.h" // OK @@ -198,7 +198,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveAnim = true; obj->saveFlags = true; obj->pivotLength = 50; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; g_Level.Bones[obj->boneIndex + 10 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 14 * 4] |= ROT_Z; @@ -293,7 +293,7 @@ static void StartEntity(ObjectInfo* obj) obj->saveAnim = true; obj->saveFlags = true; obj->pivotLength = 0; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; diff --git a/TombEngine/Objects/TR4/tr4_objects.cpp b/TombEngine/Objects/TR4/tr4_objects.cpp index 5116b5006..4e3b03ff3 100644 --- a/TombEngine/Objects/TR4/tr4_objects.cpp +++ b/TombEngine/Objects/TR4/tr4_objects.cpp @@ -9,7 +9,7 @@ #include "Specific/setup.h" #include "Specific/level.h" -// Entities +// Creatures #include "tr4_enemy_jeep.h" #include "tr4_ahmet.h" // OK #include "tr4_baddy.h" // OK @@ -100,7 +100,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_BIG_SCORPION]; @@ -119,7 +119,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveFlags = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_HAMMERHEAD]; @@ -139,7 +139,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->waterCreature = true; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; } obj = &Objects[ID_WILD_BOAR]; @@ -158,7 +158,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 48 * 4] |= ROT_Z; g_Level.Bones[obj->boneIndex + 48 * 4] |= ROT_Y; @@ -182,7 +182,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 19 * 4] |= ROT_Y; } @@ -202,7 +202,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; } obj = &Objects[ID_AHMET]; @@ -221,7 +221,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 9 * 4] |= ROT_Y; } @@ -244,7 +244,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->meshSwapSlot = ID_MESHSWAP_BADDY1; - obj->zoneType = ZONE_HUMAN_JUMP_AND_MONKEY; + obj->ZoneType = ZoneType::HumanJumpAndMonkey; g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_X; @@ -270,7 +270,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->meshSwapSlot = ID_MESHSWAP_BADDY2; - obj->zoneType = ZONE_HUMAN_JUMP_AND_MONKEY; + obj->ZoneType = ZoneType::HumanJumpAndMonkey; g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 28 * 4] |= ROT_X; @@ -295,7 +295,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex] |= ROT_Y; g_Level.Bones[obj->boneIndex] |= ROT_X; @@ -319,7 +319,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->undead = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_X; @@ -344,7 +344,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->undead = true; - obj->zoneType = ZONE_SKELLY; + obj->ZoneType = ZoneType::Skeleton; } obj = &Objects[ID_KNIGHT_TEMPLAR]; @@ -363,7 +363,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveFlags = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X | ROT_Y; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y; @@ -386,7 +386,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->savePosition = true; obj->undead = false; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; } obj = &Objects[ID_SETHA]; @@ -406,7 +406,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveAnim = true; obj->undead = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_DEMIGOD1]; @@ -426,7 +426,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveAnim = true; obj->undead = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_X | ROT_Y | ROT_Z; g_Level.Bones[obj->boneIndex + 5 * 4] |= ROT_Y; @@ -448,7 +448,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveFlags = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_X | ROT_Y | ROT_Z; g_Level.Bones[obj->boneIndex + 5 * 4] |= ROT_Y; } @@ -469,7 +469,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveFlags = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_X | ROT_Y | ROT_Z; g_Level.Bones[obj->boneIndex + 5 * 4] |= ROT_Y; } @@ -483,7 +483,7 @@ namespace TEN::Entities obj->hitEffect = HIT_BLOOD; obj->nonLot = true; obj->savePosition = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_TROOPS]; @@ -502,7 +502,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex] |= ROT_X | ROT_Y; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_X | ROT_Y; @@ -525,7 +525,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->explodableMeshbits = 64; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 0] |= ROT_Y; g_Level.Bones[obj->boneIndex + 1 * 4] |= ROT_X; @@ -548,7 +548,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; } obj = &Objects[ID_GUIDE]; @@ -567,7 +567,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->meshSwapSlot = ID_MESHSWAP2; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X | ROT_Y; g_Level.Bones[obj->boneIndex + 20 * 4] |= ROT_X | ROT_Y; @@ -589,7 +589,7 @@ namespace TEN::Entities obj->saveAnim = true; obj->saveFlags = true; obj->waterCreature = true; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; g_Level.Bones[obj->boneIndex] |= ROT_Y; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y; @@ -612,7 +612,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveAnim = true; obj->saveFlags = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_HORSE]; @@ -642,7 +642,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->savePosition = true; obj->saveMesh = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_BABOON_NORMAL]; @@ -661,7 +661,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_BABOON_INV]; @@ -680,7 +680,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; if (Objects[ID_BABOON_NORMAL].loaded) Objects[ID_BABOON_INV].animIndex = Objects[ID_BABOON_NORMAL].animIndex; @@ -702,7 +702,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; if (Objects[ID_BABOON_NORMAL].loaded) Objects[ID_BABOON_SILENT].animIndex = Objects[ID_BABOON_NORMAL].animIndex; @@ -725,7 +725,7 @@ namespace TEN::Entities obj->saveMesh = true; obj->savePosition = true; obj->undead = true; - obj->zoneType = ZONE_WATER; + obj->ZoneType = ZoneType::Water; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y | ROT_X; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y | ROT_X; } @@ -737,7 +737,7 @@ namespace TEN::Entities obj->control = TEN::Entities::TR4::LocustControl; obj->drawRoutine = NULL; obj->saveFlags = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_WRAITH1]; @@ -780,7 +780,7 @@ namespace TEN::Entities obj->control = TEN::Entities::TR4::BeetleSwarmControl; obj->drawRoutine = NULL; obj->saveFlags = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_SAS_DYING]; @@ -793,7 +793,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->savePosition = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_SAS_DRAG_BLOKE]; @@ -805,7 +805,7 @@ namespace TEN::Entities obj->saveFlags = true; obj->savePosition = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_ENEMY_JEEP]; @@ -823,7 +823,7 @@ namespace TEN::Entities obj->shadowType = ShadowMode::All; obj->radius = 512; obj->HitPoints = 40; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 4 * 8] |= ROT_X; g_Level.Bones[obj->boneIndex + 4 * 9] |= ROT_X; @@ -847,7 +847,7 @@ namespace TEN::Entities obj->savePosition = true; obj->saveHitpoints = true; obj->saveMesh = true; - obj->zoneType = ZONE_HUMAN_LONGJUMP_AND_MONKEY; + obj->ZoneType = ZoneType::HumanLongJumpAndMonkey; g_Level.Bones[obj->boneIndex + 4 * 6] |= ROT_X; g_Level.Bones[obj->boneIndex + 4 * 6] |= ROT_Y; @@ -1176,7 +1176,7 @@ namespace TEN::Entities obj->saveHitpoints = true; obj->saveFlags = true; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; } obj = &Objects[ID_TEETH_SPIKES]; diff --git a/TombEngine/Objects/TR5/tr5_objects.cpp b/TombEngine/Objects/TR5/tr5_objects.cpp index aa98ec944..5c7b5261f 100644 --- a/TombEngine/Objects/TR5/tr5_objects.cpp +++ b/TombEngine/Objects/TR5/tr5_objects.cpp @@ -105,7 +105,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -130,7 +130,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -157,7 +157,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -187,7 +187,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -218,7 +218,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -247,7 +247,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[Objects[69].boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[Objects[69].boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[Objects[69].boneIndex + 13 * 4] |= ROT_Y; @@ -278,7 +278,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -310,7 +310,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -334,7 +334,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveHitpoints = true; obj->savePosition = true; obj->waterCreature = true; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; obj->undead = true; g_Level.Bones[obj->boneIndex] |= ROT_X; g_Level.Bones[obj->boneIndex + 4] |= ROT_X; @@ -357,7 +357,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 4 * 6] |= ROT_Y; g_Level.Bones[obj->boneIndex + 4 * 6] |= ROT_X; @@ -381,7 +381,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 19 * 4] |= ROT_Y; } @@ -402,7 +402,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 19 * 4] |= ROT_Y; } @@ -422,7 +422,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 19 * 4] |= ROT_Y; } @@ -443,7 +443,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveHitpoints = true; obj->savePosition = true; obj->waterCreature = true; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; } obj = &Objects[ID_MAFIA2]; @@ -464,7 +464,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; obj->meshSwapSlot = ID_MESHSWAP_MAFIA2; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; @@ -490,7 +490,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y; @@ -514,7 +514,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 7 * 4] |= ROT_Y; @@ -539,7 +539,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveAnim = true; obj->saveHitpoints = true; obj->undead = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; obj->meshSwapSlot = ID_MESHSWAP_HITMAN; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; @@ -591,7 +591,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveAnim = true; obj->saveHitpoints = true; obj->undead = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex] |= ROT_Y; g_Level.Bones[obj->boneIndex] |= ROT_X; g_Level.Bones[obj->boneIndex + 4] |= ROT_Y; @@ -616,7 +616,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveAnim = true; obj->saveHitpoints = true; obj->undead = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 0] |= ROT_Y; g_Level.Bones[obj->boneIndex + 8 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 8 * 4] |= ROT_X; @@ -641,7 +641,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveAnim = true; obj->saveHitpoints = true; obj->meshSwapSlot = ID_MESHSWAP_IMP; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->meshIndex + 4 * 4] |= ROT_Z; g_Level.Bones[obj->meshIndex + 4 * 4] |= ROT_X; @@ -665,7 +665,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_FLYER; + obj->ZoneType = ZoneType::Flyer; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_Z; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 9 * 4] |= ROT_Z; @@ -689,7 +689,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveHitpoints = true; obj->savePosition = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_Z; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 9 * 4] |= ROT_Z; @@ -714,7 +714,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveHitpoints = true; obj->savePosition = true; obj->waterCreature = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_Z; g_Level.Bones[obj->boneIndex + 4 * 4] |= ROT_X; @@ -739,7 +739,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 8 * 4] |= ROT_Y; @@ -790,7 +790,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveFlags = true; obj->saveAnim = true; obj->saveHitpoints = true; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_Y; g_Level.Bones[obj->boneIndex + 6 * 4] |= ROT_X; g_Level.Bones[obj->boneIndex + 13 * 4] |= ROT_Y; @@ -817,7 +817,7 @@ static void StartEntity(ObjectInfo *obj) obj->saveAnim = true; obj->saveHitpoints = true; obj->meshSwapSlot = ID_MESHSWAP_ROMAN_GOD1 + i; - obj->zoneType = ZONE_HUMAN_CLASSIC; + obj->ZoneType = ZoneType::HumanClassic; g_Level.Bones[obj->boneIndex + 24] |= ROT_Y; g_Level.Bones[obj->boneIndex + 24] |= ROT_X; @@ -876,7 +876,7 @@ static void StartEntity(ObjectInfo *obj) obj->initialise = InitialiseSubmarine; obj->control = SubmarineControl; obj->saveAnim = true; - obj->zoneType = ZONE_BASIC; + obj->ZoneType = ZoneType::Basic; obj->hitEffect = HIT_RICOCHET; obj->shadowType = ShadowMode::All; obj->HitPoints = 100; diff --git a/TombEngine/Specific/setup.cpp b/TombEngine/Specific/setup.cpp index d30ba5659..d56cd088d 100644 --- a/TombEngine/Specific/setup.cpp +++ b/TombEngine/Specific/setup.cpp @@ -408,7 +408,7 @@ void InitialiseObjects() obj->usingDrawAnimatingItem = true; obj->semiTransparent = false; obj->undead = false; - obj->zoneType = ZONE_NULL; + obj->ZoneType = ZoneType::None; obj->biteOffset = -1; obj->meshSwapSlot = NO_ITEM; obj->isPickup = false; diff --git a/TombEngine/Specific/setup.h b/TombEngine/Specific/setup.h index 550ebf858..d8fa8efe3 100644 --- a/TombEngine/Specific/setup.h +++ b/TombEngine/Specific/setup.h @@ -1,12 +1,12 @@ #pragma once #include "Objects/objectslist.h" -#include "Specific/phd_global.h" -#include "Specific/level.h" #include "Renderer/Renderer11Enums.h" +#include "Specific/level.h" +#include "Specific/phd_global.h" -struct ItemInfo; +enum class ZoneType; struct CollisionInfo; -enum ZoneType : char; +struct ItemInfo; constexpr auto DEFAULT_RADIUS = 10; constexpr auto ROT_X = 0x0004; @@ -44,7 +44,7 @@ struct ObjectInfo std::function ceilingBorder; std::function drawRoutine; std::function collision; - ZoneType zoneType; + ZoneType ZoneType; int animIndex; short HitPoints; short pivotLength; From 6c7a856522600162f0b20ce1f2d361ef2f6b0d2e Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 21:54:59 +1000 Subject: [PATCH 026/106] Minor cleanup --- TombEngine/Game/itemdata/creature_info.h | 1 - TombEngine/Objects/TR3/Entity/tr3_trex.cpp | 5 +- .../Objects/TR3/Entity/tr3_tribesman.cpp | 52 +++++++++---------- 3 files changed, 28 insertions(+), 30 deletions(-) diff --git a/TombEngine/Game/itemdata/creature_info.h b/TombEngine/Game/itemdata/creature_info.h index c76d9bc4e..fd8c710e7 100644 --- a/TombEngine/Game/itemdata/creature_info.h +++ b/TombEngine/Game/itemdata/creature_info.h @@ -58,7 +58,6 @@ struct LOTInfo bool IsJumping = false; bool IsMonkeying = false; bool IsAmphibious = false; - }; enum class MoodType diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp index c96d26d90..137deb7af 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp @@ -17,8 +17,9 @@ using std::vector; namespace TEN::Entities::Creatures::TR3 { + constexpr auto TREX_CONTACT_DAMAGE = 1; + constexpr auto TREX_RUN_CONTACT_DAMAGE = 10; constexpr auto TREX_ROAR_CHANCE = 0.015f; - constexpr auto LARA_ANIM_TREX_DEATH_ANIM = 4; const vector TRexAttackJoints = { 12, 13 }; @@ -114,7 +115,7 @@ namespace TEN::Entities::Creatures::TR3 angle = CreatureTurn(item, creature->MaxTurn); if (item->TouchBits) - DoDamage(LaraItem, (item->Animation.ActiveState == TREX_STATE_RUN_FORWARD) ? 10 : 1); + DoDamage(LaraItem, (item->Animation.ActiveState == TREX_STATE_RUN_FORWARD) ? TREX_RUN_CONTACT_DAMAGE : TREX_CONTACT_DAMAGE); creature->Flags = (creature->Mood != MoodType::Escape && !AI.ahead && AI.enemyFacing > -FRONT_ARC && AI.enemyFacing < FRONT_ARC); diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index 68f121572..4ff0ae04c 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -105,9 +105,9 @@ namespace TEN::Entities::Creatures::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; short tilt = 0; + short head = 0; if (item->HitPoints <= 0) { @@ -217,9 +217,9 @@ namespace TEN::Entities::Creatures::TR3 break; case TRIBESMAN_STATE_WALK_FORWARD: - tilt = angle / 8; creature->MaxTurn = ANGLE(9.0f); creature->Flags = 0; + tilt = angle / 8; if (creature->Mood == MoodType::Bored) { @@ -248,9 +248,9 @@ namespace TEN::Entities::Creatures::TR3 break; case TRIBESMAN_STATE_RUN_FORWARD: - tilt = angle / 4; creature->MaxTurn = ANGLE(6.0f); creature->Flags = 0; + tilt = angle / 4; if (creature->Mood == MoodType::Bored) { @@ -312,7 +312,7 @@ namespace TEN::Entities::Creatures::TR3 } else { - if (creature->Enemy) + if (creature->Enemy != nullptr) { auto direction = creature->Enemy->Pose.Position - item->Pose.Position; if (abs(direction.x) < SECTOR(0.5f) && @@ -387,10 +387,8 @@ namespace TEN::Entities::Creatures::TR3 short angle = 0; short tilt = 0; - short headX = 0; - short headY = 0; - short torsoX = 0; - short torsoY = 0; + auto extraHeadRot = Vector3Shrt::Zero; + auto extraTorsoRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { @@ -423,8 +421,8 @@ namespace TEN::Entities::Creatures::TR3 angle = CreatureTurn(item, creature->Mood == MoodType::Bored ? ANGLE(2.0f) : creature->MaxTurn); if (AI.ahead) { - headY = AI.angle / 2; - torsoY = AI.angle / 2; + extraHeadRot.y = AI.angle / 2; + extraTorsoRot.y = AI.angle / 2; } if (item->HitStatus || @@ -442,16 +440,16 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoY = AI.angle; - torsoX = AI.xAngle / 2; + extraTorsoRot.x = AI.xAngle / 2; + extraTorsoRot.y = AI.angle; } if (item->AIBits & GUARD) { creature->MaxTurn = 0; - headY = AIGuard(creature); - torsoX = 0; - torsoY = 0; + extraHeadRot.y = AIGuard(creature); + extraTorsoRot.x = 0; + extraTorsoRot.y = 0; if (TestProbability(0.004f)) item->Animation.TargetState = TRIBESMAN_STATE_IDLE; @@ -483,16 +481,16 @@ namespace TEN::Entities::Creatures::TR3 break; - case 11: + case TRIBESMAN_STATE_IDLE: creature->MaxTurn = ANGLE(2.0f); creature->Flags &= 0x0FFF; if (item->AIBits & GUARD) { creature->MaxTurn = 0; - headY = AIGuard(creature); - torsoX = 0; - torsoY = 0; + extraHeadRot.y = AIGuard(creature); + extraTorsoRot.x = 0; + extraTorsoRot.y = 0; if (TestProbability(0.004f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; @@ -544,7 +542,7 @@ namespace TEN::Entities::Creatures::TR3 break; - case 3: + case TRIBESMAN_STATE_RUN_FORWARD: creature->MaxTurn = ANGLE(6.0f); creature->Flags &= 0x0FFF; tilt = angle / 4; @@ -576,8 +574,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (abs(AI.angle) < ANGLE(2.0f)) @@ -628,12 +626,12 @@ namespace TEN::Entities::Creatures::TR3 CreatureTilt(item, tilt); - headY -= torsoY; + extraHeadRot.y -= extraTorsoRot.y; - CreatureJoint(item, 0, torsoY); - CreatureJoint(item, 1, torsoX); - CreatureJoint(item, 2, headY); - CreatureJoint(item, 3, headX); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); + CreatureJoint(item, 2, extraHeadRot.y); + CreatureJoint(item, 3, extraHeadRot.x); CreatureAnimation(itemNumber, angle, 0); } From 10d3e3c253558166c6c55ef15262d7348f558e6d Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 21 Aug 2022 22:18:53 +1000 Subject: [PATCH 027/106] Fix double cast --- TombEngine/Game/control/box.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index 0b6c24a1a..e18fe2f3b 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -157,7 +157,7 @@ void CreatureYRot2(PHD_3DPOS* srcPos, short angle, short angleAdd) bool SameZone(CreatureInfo* creature, ItemInfo* target) { - int* zone = g_Level.Zones[(int)(int)creature->LOT.Zone][FlipStatus].data(); + int* zone = g_Level.Zones[(int)creature->LOT.Zone][FlipStatus].data(); auto* item = &g_Level.Items[creature->ItemNumber]; auto* room = &g_Level.Rooms[item->RoomNumber]; From 28a39efe95d67cb87ace96d6625d4f8abe822ade Mon Sep 17 00:00:00 2001 From: hispidence Date: Mon, 22 Aug 2022 13:44:44 +0100 Subject: [PATCH 028/106] Fix #689 --- TombEngine/Game/Lara/lara_fire.cpp | 6 ++- TombEngine/Game/Lara/lara_one_gun.cpp | 6 ++- TombEngine/Game/Lara/lara_struct.h | 2 +- TombEngine/Game/Lara/lara_two_guns.cpp | 11 +++- TombEngine/Game/pickup/pickup_weapon.cpp | 64 +++++++++++++++++++----- 5 files changed, 71 insertions(+), 18 deletions(-) diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp index f6049ea56..6d1f1de0b 100644 --- a/TombEngine/Game/Lara/lara_fire.cpp +++ b/TombEngine/Game/Lara/lara_fire.cpp @@ -571,7 +571,9 @@ void LaraGun(ItemInfo* laraItem) { if (!GetAmmo(laraItem, lara->Control.Weapon.GunType)) { - lara->Control.Weapon.RequestGunType = Objects[ID_PISTOLS_ITEM].loaded ? LaraWeaponType::Pistol : LaraWeaponType::None; + bool hasPistols = lara->Weapons[(int)LaraWeaponType::Pistol].Present && Objects[ID_PISTOLS_ITEM].loaded; + + lara->Control.Weapon.RequestGunType = hasPistols ? LaraWeaponType::Pistol : LaraWeaponType::None; return; } } @@ -1184,7 +1186,7 @@ HolsterSlot HolsterSlotForWeapon(LaraWeaponType weaponType) return HolsterSlot::Harpoon; case LaraWeaponType::Crossbow: - return HolsterSlot::Crowssbow; + return HolsterSlot::Crossbow; case LaraWeaponType::GrenadeLauncher: return HolsterSlot::GrenadeLauncher; diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index c09b63b63..6d84bd9fe 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -434,8 +434,12 @@ void UndrawShotgunMeshes(ItemInfo* laraItem, LaraWeaponType weaponType) { auto* lara = GetLaraInfo(laraItem); - lara->Control.Weapon.HolsterInfo.BackHolster = HolsterSlotForWeapon(weaponType); lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND; + + if (lara->Weapons[(int)weaponType].Present) + lara->Control.Weapon.HolsterInfo.BackHolster = HolsterSlotForWeapon(weaponType); + else + lara->Control.Weapon.HolsterInfo.BackHolster = HolsterSlot::Empty; } void FireHarpoon(ItemInfo* laraItem) diff --git a/TombEngine/Game/Lara/lara_struct.h b/TombEngine/Game/Lara/lara_struct.h index e47d6fa3a..f0d276613 100644 --- a/TombEngine/Game/Lara/lara_struct.h +++ b/TombEngine/Game/Lara/lara_struct.h @@ -887,7 +887,7 @@ enum class HolsterSlot Shotgun = ID_SHOTGUN_ANIM, HK = ID_HK_ANIM, Harpoon = ID_HARPOON_ANIM, - Crowssbow = ID_CROSSBOW_ANIM, + Crossbow = ID_CROSSBOW_ANIM, GrenadeLauncher = ID_GRENADE_ANIM, RocketLauncher = ID_ROCKET_ANIM }; diff --git a/TombEngine/Game/Lara/lara_two_guns.cpp b/TombEngine/Game/Lara/lara_two_guns.cpp index 2bc720fde..4b93d3add 100644 --- a/TombEngine/Game/Lara/lara_two_guns.cpp +++ b/TombEngine/Game/Lara/lara_two_guns.cpp @@ -490,7 +490,10 @@ void UndrawPistolMeshRight(ItemInfo* laraItem, LaraWeaponType weaponType) auto* lara = GetLaraInfo(laraItem); lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND; - lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlotForWeapon(weaponType); + if (lara->Weapons[(int)weaponType].Present) + lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlotForWeapon(weaponType); + else + lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlot::Empty; } void UndrawPistolMeshLeft(ItemInfo* laraItem, LaraWeaponType weaponType) @@ -500,6 +503,10 @@ void UndrawPistolMeshLeft(ItemInfo* laraItem, LaraWeaponType weaponType) if (weaponType != LaraWeaponType::Revolver) { lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND; - lara->Control.Weapon.HolsterInfo.LeftHolster = HolsterSlotForWeapon(weaponType); + + if (lara->Weapons[(int)weaponType].Present) + lara->Control.Weapon.HolsterInfo.LeftHolster = HolsterSlotForWeapon(weaponType); + else + lara->Control.Weapon.HolsterInfo.LeftHolster = HolsterSlot::Empty; } } diff --git a/TombEngine/Game/pickup/pickup_weapon.cpp b/TombEngine/Game/pickup/pickup_weapon.cpp index a99f065a6..d61b4f884 100644 --- a/TombEngine/Game/pickup/pickup_weapon.cpp +++ b/TombEngine/Game/pickup/pickup_weapon.cpp @@ -2,30 +2,39 @@ #include "Game/pickup/pickup_weapon.h" #include + +#include "lara_fire.h" #include "Game/Lara/lara_struct.h" #include "Game/pickup/pickuputil.h" #include "Game/pickup/pickup_ammo.h" #include "Objects/objectslist.h" +enum class HolsterType +{ + Hips, + Back +}; + struct WeaponPickupInfo { GAME_OBJECT_ID ObjectID; GAME_OBJECT_ID AmmoID; // When the player picks up a weapon, they get one clip's worth of this ammo. LaraWeaponType LaraWeaponType; + HolsterType Holster; }; static constexpr std::array kWeapons { { - { ID_PISTOLS_ITEM, ID_PISTOLS_AMMO_ITEM, LaraWeaponType::Pistol }, - { ID_UZI_ITEM, ID_UZI_AMMO_ITEM, LaraWeaponType::Uzi }, - { ID_SHOTGUN_ITEM, ID_SHOTGUN_AMMO1_ITEM, LaraWeaponType::Shotgun }, - { ID_CROSSBOW_ITEM, ID_CROSSBOW_AMMO1_ITEM, LaraWeaponType::Crossbow }, - { ID_REVOLVER_ITEM, ID_REVOLVER_AMMO_ITEM, LaraWeaponType::Revolver }, - { ID_HK_ITEM, ID_HK_AMMO_ITEM, LaraWeaponType::HK }, - { ID_GRENADE_GUN_ITEM, ID_GRENADE_AMMO1_ITEM, LaraWeaponType::GrenadeLauncher }, - { ID_ROCKET_LAUNCHER_ITEM, ID_ROCKET_LAUNCHER_AMMO_ITEM, LaraWeaponType::RocketLauncher }, - { ID_HARPOON_ITEM, ID_HARPOON_AMMO_ITEM, LaraWeaponType::HarpoonGun } + { ID_PISTOLS_ITEM, ID_PISTOLS_AMMO_ITEM, LaraWeaponType::Pistol, HolsterType::Hips }, + { ID_UZI_ITEM, ID_UZI_AMMO_ITEM, LaraWeaponType::Uzi, HolsterType::Hips}, + { ID_SHOTGUN_ITEM, ID_SHOTGUN_AMMO1_ITEM, LaraWeaponType::Shotgun, HolsterType::Back }, + { ID_CROSSBOW_ITEM, ID_CROSSBOW_AMMO1_ITEM, LaraWeaponType::Crossbow, HolsterType::Back}, + { ID_REVOLVER_ITEM, ID_REVOLVER_AMMO_ITEM, LaraWeaponType::Revolver, HolsterType::Back}, + { ID_HK_ITEM, ID_HK_AMMO_ITEM, LaraWeaponType::HK, HolsterType::Back}, + { ID_GRENADE_GUN_ITEM, ID_GRENADE_AMMO1_ITEM, LaraWeaponType::GrenadeLauncher, HolsterType::Back }, + { ID_ROCKET_LAUNCHER_ITEM, ID_ROCKET_LAUNCHER_AMMO_ITEM, LaraWeaponType::RocketLauncher, HolsterType::Back }, + { ID_HARPOON_ITEM, ID_HARPOON_AMMO_ITEM, LaraWeaponType::HarpoonGun, HolsterType::Back } } }; @@ -50,10 +59,41 @@ static bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int ammoAmo // Set the SelectedAmmo type to WeaponAmmoType::Ammo1 (0) if adding the weapon for the first time. // Note that this refers to the index of the weapon's ammo array, and not the weapon's actual ammunition count. - if (!lara.Weapons[(int)info.LaraWeaponType].Present) - lara.Weapons[(int)info.LaraWeaponType].SelectedAmmo = WeaponAmmoType::Ammo1; + auto& currWeapon = lara.Weapons[(int)info.LaraWeaponType]; + + if (!currWeapon.Present) + currWeapon.SelectedAmmo = WeaponAmmoType::Ammo1; - lara.Weapons[(int)info.LaraWeaponType].Present = add; + currWeapon.Present = add; + if(!add) + { + if (info.LaraWeaponType == lara.Control.Weapon.GunType) + { + lara.Control.Weapon.RequestGunType = LaraWeaponType::None; + + // If Lara has pistols and it's not the pistols we're removing, set them + // as the "next weapon" so that Lara equips them next. + if (LaraWeaponType::Pistol == info.LaraWeaponType || !lara.Weapons[(int)LaraWeaponType::Pistol].Present) + { + lara.Control.Weapon.LastGunType = LaraWeaponType::None; + } + else + { + lara.Control.Weapon.LastGunType = LaraWeaponType::Pistol; + } + } + + if (HolsterType::Hips == info.Holster && lara.Control.Weapon.HolsterInfo.LeftHolster == HolsterSlotForWeapon(info.LaraWeaponType)) + { + lara.Control.Weapon.HolsterInfo.LeftHolster = HolsterSlot::Empty; + lara.Control.Weapon.HolsterInfo.RightHolster = HolsterSlot::Empty; + } + else if (HolsterType::Back == info.Holster && lara.Control.Weapon.HolsterInfo.BackHolster == HolsterSlotForWeapon(info.LaraWeaponType)) + { + lara.Control.Weapon.HolsterInfo.BackHolster = HolsterSlot::Empty; + } + } + auto ammoID = info.AmmoID; return add ? TryAddingAmmo(lara, ammoID, ammoAmount) : TryRemovingAmmo(lara, ammoID, ammoAmount); } From 4e4ec4bb0b10a21c7f37ddf76198f5632aa07d36 Mon Sep 17 00:00:00 2001 From: hispidence Date: Mon, 22 Aug 2022 14:03:18 +0100 Subject: [PATCH 029/106] Fix #689 in other situations --- TombEngine/Game/pickup/pickup_weapon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Game/pickup/pickup_weapon.cpp b/TombEngine/Game/pickup/pickup_weapon.cpp index d61b4f884..9fc1f4b0d 100644 --- a/TombEngine/Game/pickup/pickup_weapon.cpp +++ b/TombEngine/Game/pickup/pickup_weapon.cpp @@ -67,7 +67,7 @@ static bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int ammoAmo currWeapon.Present = add; if(!add) { - if (info.LaraWeaponType == lara.Control.Weapon.GunType) + if (info.LaraWeaponType == lara.Control.Weapon.GunType || info.LaraWeaponType == lara.Control.Weapon.LastGunType) { lara.Control.Weapon.RequestGunType = LaraWeaponType::None; From 221c89bb59b9257a75020e50878926cc00977a1c Mon Sep 17 00:00:00 2001 From: hispidence Date: Mon, 22 Aug 2022 21:50:11 +0100 Subject: [PATCH 030/106] Revolver is a hips weapon --- TombEngine/Game/pickup/pickup_weapon.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Game/pickup/pickup_weapon.cpp b/TombEngine/Game/pickup/pickup_weapon.cpp index 9fc1f4b0d..4e03ac4ea 100644 --- a/TombEngine/Game/pickup/pickup_weapon.cpp +++ b/TombEngine/Game/pickup/pickup_weapon.cpp @@ -30,7 +30,7 @@ static constexpr std::array kWeapons { ID_UZI_ITEM, ID_UZI_AMMO_ITEM, LaraWeaponType::Uzi, HolsterType::Hips}, { ID_SHOTGUN_ITEM, ID_SHOTGUN_AMMO1_ITEM, LaraWeaponType::Shotgun, HolsterType::Back }, { ID_CROSSBOW_ITEM, ID_CROSSBOW_AMMO1_ITEM, LaraWeaponType::Crossbow, HolsterType::Back}, - { ID_REVOLVER_ITEM, ID_REVOLVER_AMMO_ITEM, LaraWeaponType::Revolver, HolsterType::Back}, + { ID_REVOLVER_ITEM, ID_REVOLVER_AMMO_ITEM, LaraWeaponType::Revolver, HolsterType::Hips}, { ID_HK_ITEM, ID_HK_AMMO_ITEM, LaraWeaponType::HK, HolsterType::Back}, { ID_GRENADE_GUN_ITEM, ID_GRENADE_AMMO1_ITEM, LaraWeaponType::GrenadeLauncher, HolsterType::Back }, { ID_ROCKET_LAUNCHER_ITEM, ID_ROCKET_LAUNCHER_AMMO_ITEM, LaraWeaponType::RocketLauncher, HolsterType::Back }, From d186b15b98935e8716b064083059f124b0e3bad7 Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 23 Aug 2022 13:45:10 +1000 Subject: [PATCH 031/106] Fix horseman axe attacks --- TombEngine/Objects/TR4/Entity/tr4_horseman.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp index 55d173b21..fb1daf7fb 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp @@ -655,7 +655,7 @@ namespace TEN::Entities::TR4 if (!creature->Flags) { - if (item->TouchBits & 0x4000) + if (item->TouchBits & 0x60) { DoDamage(creature->Enemy, 100); CreatureEffect2(item, HorsemanBite2, 3, item->Pose.Orientation.y, DoBloodSplat); From 633ada9413ffe781e4a03ed2cf148fefbf4b410c Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 23 Aug 2022 14:00:34 +1000 Subject: [PATCH 032/106] Demagic horseman TouchBits --- TombEngine/Objects/TR4/Entity/tr4_horseman.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp index fb1daf7fb..fb40ecc75 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_horseman.cpp @@ -18,12 +18,17 @@ #include "Specific/trmath.h" using namespace TEN::Math::Random; +using std::vector; namespace TEN::Entities::TR4 { const auto HorsemanBite1 = BiteInfo(Vector3::Zero, 6); const auto HorsemanBite2 = BiteInfo(Vector3::Zero, 14); const auto HorsemanBite3 = BiteInfo(Vector3::Zero, 10); + const vector HorsemanAxeAttackJoints = { 5, 6 }; + const vector HorsemanKickAttackJoints = { 14 }; + const vector HorsemanMountedAttackJoints = { 5, 6, 10 }; + const vector HorsemanShieldAttackJoints = { 10 }; const auto HorseBite1 = BiteInfo(Vector3::Zero, 13); const auto HorseBite2 = BiteInfo(Vector3::Zero, 17); @@ -550,7 +555,7 @@ namespace TEN::Entities::TR4 case HORSEMAN_STATE_MOUNTED_ATTACK_RIGHT: if (!creature->Flags) { - if (item->TouchBits & 0x60) + if (item->TestBits(JointBitType::Touch, HorsemanAxeAttackJoints)) { DoDamage(creature->Enemy, 250); CreatureEffect2(item, HorsemanBite1, 10, item->Pose.Orientation.y, DoBloodSplat); @@ -566,7 +571,7 @@ namespace TEN::Entities::TR4 case HORSEMAN_STATE_MOUNTED_ATTACK_LEFT: if (!creature->Flags) { - if (item->TouchBits & 0x4000) + if (item->TestBits(JointBitType::Touch, HorsemanKickAttackJoints)) { DoDamage(creature->Enemy, 100); CreatureEffect2(item, HorsemanBite2, 3, item->Pose.Orientation.y, DoBloodSplat); @@ -655,7 +660,7 @@ namespace TEN::Entities::TR4 if (!creature->Flags) { - if (item->TouchBits & 0x60) + if (item->TestBits(JointBitType::Touch, HorsemanAxeAttackJoints)) { DoDamage(creature->Enemy, 100); CreatureEffect2(item, HorsemanBite2, 3, item->Pose.Orientation.y, DoBloodSplat); @@ -696,16 +701,16 @@ namespace TEN::Entities::TR4 if (!creature->Flags) { - if (item->TouchBits & 0x460) + if (item->TestBits(JointBitType::Touch, HorsemanMountedAttackJoints)) { LaraItem->HitStatus = true; - if (item->TouchBits & 0x60) + if (item->TestBits(JointBitType::Touch, HorsemanAxeAttackJoints)) { DoDamage(creature->Enemy, 250); CreatureEffect2(horseItem, HorsemanBite1, 20, -1, DoBloodSplat); } - else if (item->TouchBits & 0x400) + else if (item->TestBits(JointBitType::Touch, HorsemanShieldAttackJoints)) { DoDamage(creature->Enemy, 150); CreatureEffect2(horseItem, HorsemanBite3, 10, -1, DoBloodSplat); From 7ce086c0cbe25aa2a0f036a995946f43244633ca Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 23 Aug 2022 15:01:02 +1000 Subject: [PATCH 033/106] Demagic brown beast TouchBits --- .../Objects/TR5/Entity/tr5_brownbeast.cpp | 28 +++++++++---------- TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 12 +++----- 2 files changed, 18 insertions(+), 22 deletions(-) diff --git a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp index 5fffd2aa9..d71b9241b 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_brownbeast.cpp @@ -14,6 +14,7 @@ #include "Specific/level.h" using namespace TEN::Math::Random; +using std::vector; namespace TEN::Entities::Creatures::TR5 { @@ -21,6 +22,8 @@ namespace TEN::Entities::Creatures::TR5 const auto BrownBeastBite1 = BiteInfo(Vector3::Zero, 16); const auto BrownBeastBite2 = BiteInfo(Vector3::Zero, 22); + const vector BrownBeastAttackJoints1 = { 14, 15, 16, 17 }; + const vector BrownBeastAttackJoints2 = { 20, 21, 22, 23 }; // TODO enum BrownBeastState @@ -39,11 +42,7 @@ namespace TEN::Entities::Creatures::TR5 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.TargetState = 1; - item->Animation.ActiveState = 1; + SetAnimation(item, 0); } void ControlBrowsBeast(short itemNumber) @@ -99,6 +98,7 @@ namespace TEN::Entities::Creatures::TR5 { case 1: creature->Flags = 0; + if (creature->Mood == MoodType::Attack) { if (distance <= pow(SECTOR(1), 2)) @@ -143,7 +143,7 @@ namespace TEN::Entities::Creatures::TR5 if (creature->Flags) break; - if (item->TouchBits & 0x3C000) + if (item->TestBits(JointBitType::Touch, BrownBeastAttackJoints1)) { if (item->Animation.AnimNumber == Objects[ID_BROWN_BEAST].animIndex + 8) { @@ -157,7 +157,7 @@ namespace TEN::Entities::Creatures::TR5 } } - if (item->Animation.AnimNumber == Objects[ID_BROWN_BEAST].animIndex + 2) + if (item->Animation.AnimNumber == (Objects[ID_BROWN_BEAST].animIndex + 2)) { if (item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 6 && item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 16) @@ -170,13 +170,13 @@ namespace TEN::Entities::Creatures::TR5 } } - if (!(item->TouchBits & 0xF00000)) + if (!item->TestBits(JointBitType::Touch, BrownBeastAttackJoints2)) break; - if (item->Animation.AnimNumber == Objects[ID_BROWN_BEAST].animIndex + 8) + if (item->Animation.AnimNumber == (Objects[ID_BROWN_BEAST].animIndex + 8)) { - if (item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 13 && - item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 20) + if (item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 13) && + item->Animation.FrameNumber < (g_Level.Anims[item->Animation.AnimNumber].frameBase + 20)) { DoDamage(creature->Enemy, BROWN_BEAST_ATTACK_DAMAGE); CreatureEffect2(item, BrownBeastBite2, 20, item->Pose.Orientation.y, DoBloodSplat); @@ -185,10 +185,10 @@ namespace TEN::Entities::Creatures::TR5 } } - if (item->Animation.AnimNumber == Objects[ID_BROWN_BEAST].animIndex + 2) + if (item->Animation.AnimNumber == (Objects[ID_BROWN_BEAST].animIndex + 2)) { - if (item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 33 && - item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 43) + if (item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 33) && + item->Animation.FrameNumber < (g_Level.Anims[item->Animation.AnimNumber].frameBase + 43)) { DoDamage(creature->Enemy, BROWN_BEAST_ATTACK_DAMAGE); CreatureEffect2(item, BrownBeastBite2, 20, item->Pose.Orientation.y, DoBloodSplat); diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp index c0ab19da9..0c543d0d9 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp @@ -124,11 +124,7 @@ namespace TEN::Entities::Creatures::TR5 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 4; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.TargetState = CYBORG_STATE_IDLE; - item->Animation.ActiveState = CYBORG_STATE_IDLE; + SetAnimation(item, CYBORG_ANIM_IDLE); } static void TriggerHitmanSparks(int x, int y, int z, short xv, short yv, short zv) @@ -174,13 +170,13 @@ namespace TEN::Entities::Creatures::TR5 if (CreatureActive(itemNumber)) { auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); auto* object = &Objects[item->ObjectNumber]; + auto* creature = GetCreatureInfo(item); short angle = 0; - short joint2 = 0; - short joint1 = 0; short joint0 = 0; + short joint1 = 0; + short joint2 = 0; int x = item->Pose.Position.x; int z = item->Pose.Position.z; From d4af4eedbdffc234378556bf3c9a0ebf9d7390ea Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 23 Aug 2022 16:16:18 +1000 Subject: [PATCH 034/106] Organise --- TombEngine/Objects/TR2/Entity/tr2_shark.cpp | 40 +++-- .../Objects/TR2/Entity/tr2_silencer.cpp | 119 +++++++------ .../Objects/TR4/Entity/tr4_hammerhead.cpp | 163 +++++++++--------- TombEngine/Objects/TR4/Entity/tr4_harpy.cpp | 61 ++++--- .../Objects/TR4/Entity/tr4_knight_templar.cpp | 19 +- TombEngine/Objects/TR4/Entity/tr4_mummy.cpp | 33 ++-- 6 files changed, 207 insertions(+), 228 deletions(-) diff --git a/TombEngine/Objects/TR2/Entity/tr2_shark.cpp b/TombEngine/Objects/TR2/Entity/tr2_shark.cpp index 2f1ef3ae8..ba8a93458 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_shark.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_shark.cpp @@ -11,9 +11,14 @@ #include "Specific/level.h" #include "Specific/setup.h" +using std::vector; + namespace TEN::Entities::Creatures::TR2 { + constexpr auto SHARK_BITE_ATTACK_DAMAGE = 400; + const auto SharkBite = BiteInfo(Vector3(17.0f, -22.0f, 344.0f), 12); + const vector SharkBiteAttackJoints = { 10, 12, 13 }; void SharkControl(short itemNumber) { @@ -21,7 +26,7 @@ namespace TEN::Entities::Creatures::TR2 return; auto* item = &g_Level.Items[itemNumber]; - auto* info = GetCreatureInfo(item); + auto* creature = GetCreatureInfo(item); short angle = 0; short head = 0; @@ -29,11 +34,7 @@ namespace TEN::Entities::Creatures::TR2 if (item->HitPoints <= 0) { if (item->Animation.ActiveState != 5) - { - item->Animation.AnimNumber = Objects[ID_SHARK].animIndex + 4; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 5; - } + SetAnimation(item, 4); CreatureFloat(itemNumber); return; @@ -46,39 +47,40 @@ namespace TEN::Entities::Creatures::TR2 GetCreatureMood(item, &AI, true); CreatureMood(item, &AI, true); - angle = CreatureTurn(item, info->MaxTurn); + angle = CreatureTurn(item, creature->MaxTurn); switch (item->Animation.ActiveState) { case 0: - info->Flags = 0; - info->MaxTurn = 0; + creature->MaxTurn = 0; + creature->Flags = 0; if (AI.ahead && AI.distance < pow(SECTOR(0.75f), 2) && AI.zoneNumber == AI.enemyZone) item->Animation.TargetState = 3; else item->Animation.TargetState = 1; + break; case 1: - info->MaxTurn = ANGLE(0.5f); + creature->MaxTurn = ANGLE(0.5f); - if (info->Mood == MoodType::Bored) + if (creature->Mood == MoodType::Bored) break; else if (AI.ahead && AI.distance < pow(SECTOR(0.75f), 2)) item->Animation.TargetState = 0; - else if (info->Mood == MoodType::Escape || AI.distance > pow(SECTOR(3), 2) || !AI.ahead) + else if (creature->Mood == MoodType::Escape || AI.distance > pow(SECTOR(3), 2) || !AI.ahead) item->Animation.TargetState = 2; break; case 2: - info->MaxTurn = ANGLE(2.0f); - info->Flags = 0; + creature->MaxTurn = ANGLE(2.0f); + creature->Flags = 0; - if (info->Mood == MoodType::Bored) + if (creature->Mood == MoodType::Bored) item->Animation.TargetState = 1; - else if (info->Mood == MoodType::Escape) + else if (creature->Mood == MoodType::Escape) break; else if (AI.ahead && AI.distance < pow(1365, 2) && AI.zoneNumber == AI.enemyZone) { @@ -95,11 +97,11 @@ namespace TEN::Entities::Creatures::TR2 if (AI.ahead) head = AI.angle; - if (!info->Flags && item->TouchBits & 0x3400) + if (!creature->Flags && item->TestBits(JointBitType::Touch, SharkBiteAttackJoints)) { + DoDamage(creature->Enemy, SHARK_BITE_ATTACK_DAMAGE); CreatureEffect(item, SharkBite, DoBloodSplat); - DoDamage(info->Enemy, 400); - info->Flags = 1; + creature->Flags = 1; } break; diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index 6261b52d3..442333b9f 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -32,22 +32,17 @@ namespace TEN::Entities::Creatures::TR2 return; auto* item = &g_Level.Items[itemNumber]; - auto* info = GetCreatureInfo(item); + auto* creature = GetCreatureInfo(item); short angle = 0; - short torsoX = 0; - short torsoY = 0; - short head = 0; short tilt = 0; + Vector3Shrt extraHeadRot = Vector3Shrt::Zero; + Vector3Shrt extraTorsoRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { if (item->Animation.ActiveState != 12 && item->Animation.ActiveState != 13) - { - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 20; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 13; - } + SetAnimation(item, 20); } else { @@ -57,14 +52,15 @@ namespace TEN::Entities::Creatures::TR2 GetCreatureMood(item, &AI, true); CreatureMood(item, &AI, true); - angle = CreatureTurn(item, info->MaxTurn); + angle = CreatureTurn(item, creature->MaxTurn); switch (item->Animation.ActiveState) { case 3: + creature->MaxTurn = 0; + if (AI.ahead) - head = AI.angle; - info->MaxTurn = 0; + extraHeadRot.y = AI.angle; if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; @@ -72,34 +68,35 @@ namespace TEN::Entities::Creatures::TR2 break; case 4: - if (AI.ahead) - head = AI.angle; - info->MaxTurn = 0; + creature->MaxTurn = 0; - if (info->Mood == MoodType::Escape) + if (AI.ahead) + extraHeadRot.y = AI.angle; + + if (creature->Mood == MoodType::Escape) { - item->Animation.RequiredState = 2; item->Animation.TargetState = 3; + item->Animation.RequiredState = 2; } else { if (Targetable(item, &AI)) { - item->Animation.RequiredState = (GetRandomControl() >= 0x4000 ? 10 : 6); item->Animation.TargetState = 3; + item->Animation.RequiredState = (GetRandomControl() >= 0x4000 ? 10 : 6); } - if (info->Mood == MoodType::Attack || !AI.ahead) + if (creature->Mood == MoodType::Attack || !AI.ahead) { if (AI.distance >= pow(SECTOR(2), 2)) { - item->Animation.RequiredState = 2; item->Animation.TargetState = 3; + item->Animation.RequiredState = 2; } else { - item->Animation.RequiredState = 1; item->Animation.TargetState = 3; + item->Animation.RequiredState = 1; } } else @@ -108,14 +105,14 @@ namespace TEN::Entities::Creatures::TR2 { if (GetRandomControl() < 2560) { - item->Animation.RequiredState = 1; item->Animation.TargetState = 3; + item->Animation.RequiredState = 1; } } else { - item->Animation.RequiredState = 5; item->Animation.TargetState = 3; + item->Animation.RequiredState = 5; } } } @@ -124,36 +121,36 @@ namespace TEN::Entities::Creatures::TR2 case 1: if (AI.ahead) - head = AI.angle; + extraHeadRot.y = AI.angle; - info->MaxTurn = 910; + creature->MaxTurn = 910; - if (info->Mood == MoodType::Escape) + if (creature->Mood == MoodType::Escape) item->Animation.TargetState = 2; else if (Targetable(item, &AI)) { - item->Animation.RequiredState = (GetRandomControl() >= 0x4000 ? 10 : 6); item->Animation.TargetState = 3; + item->Animation.RequiredState = (GetRandomControl() >= 0x4000 ? 10 : 6); } else { if (AI.distance > pow(SECTOR(2), 2) || !AI.ahead) item->Animation.TargetState = 2; - if (info->Mood == MoodType::Bored && GetRandomControl() < 0x300) + if (creature->Mood == MoodType::Bored && GetRandomControl() < 0x300) item->Animation.TargetState = 3; } break; case 2: - if (AI.ahead) - head = AI.angle; - - info->MaxTurn = ANGLE(5.0f); - info->Flags = 0; + creature->MaxTurn = ANGLE(5.0f); + creature->Flags = 0; tilt = angle / 4; - if (info->Mood == MoodType::Escape) + if (AI.ahead) + extraHeadRot.y = AI.angle; + + if (creature->Mood == MoodType::Escape) { if (Targetable(item, &AI)) item->Animation.TargetState = 9; @@ -169,7 +166,7 @@ namespace TEN::Entities::Creatures::TR2 break; } - else if (info->Mood == MoodType::Attack) + else if (creature->Mood == MoodType::Attack) item->Animation.TargetState = (GetRandomControl() >= 0x4000) ? 3 : 2; else item->Animation.TargetState = 3; @@ -177,19 +174,19 @@ namespace TEN::Entities::Creatures::TR2 break; case 5: - if (AI.ahead) - head = AI.angle; + creature->MaxTurn = 0; - info->MaxTurn = 0; + if (AI.ahead) + extraHeadRot.y = AI.angle; if (Targetable(item, &AI)) { - item->Animation.RequiredState = 6; item->Animation.TargetState = 3; + item->Animation.RequiredState = 6; } else { - if (info->Mood == MoodType::Attack || GetRandomControl() < 0x100) + if (creature->Mood == MoodType::Attack || GetRandomControl() < 0x100) item->Animation.TargetState = 3; if (!AI.ahead) item->Animation.TargetState = 3; @@ -199,18 +196,18 @@ namespace TEN::Entities::Creatures::TR2 case 6: case 10: - info->MaxTurn = 0; - info->Flags = 0; + creature->MaxTurn = 0; + creature->Flags = 0; if (AI.ahead) { - torsoY = AI.angle; - torsoX = AI.xAngle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } else - head = AI.angle; + extraHeadRot.y = AI.angle; - if (info->Mood == MoodType::Escape) + if (creature->Mood == MoodType::Escape) item->Animation.TargetState = 3; else if (Targetable(item, &AI)) item->Animation.TargetState = item->Animation.ActiveState != 6 ? 11 : 7; @@ -221,38 +218,38 @@ namespace TEN::Entities::Creatures::TR2 case 7: case 11: - info->MaxTurn = 0; + creature->MaxTurn = 0; if (AI.ahead) { - torsoY = AI.angle; - torsoX = AI.xAngle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } else - head = AI.angle; + extraHeadRot.y = AI.angle; - if (!info->Flags) + if (!creature->Flags) { - ShotLara(item, &AI, SilencerGunBite, torsoY, 50); - info->Flags = 1; + ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, 50); + creature->Flags = 1; } break; case 9: - info->MaxTurn = ANGLE(5.0f); + creature->MaxTurn = ANGLE(5.0f); if (AI.ahead) { - torsoY = AI.angle; - torsoX = AI.xAngle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } else - head = AI.angle; + extraHeadRot.y = AI.angle; if (!item->Animation.RequiredState) { - if (!ShotLara(item, &AI, SilencerGunBite, torsoY, 50)) + if (!ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, 50)) item->Animation.TargetState = 2; item->Animation.RequiredState = 9; @@ -263,9 +260,9 @@ namespace TEN::Entities::Creatures::TR2 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, torsoY); - CreatureJoint(item, 1, torsoX); - CreatureJoint(item, 2, head); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); + CreatureJoint(item, 2, extraHeadRot.y); CreatureAnimation(itemNumber, angle, tilt); } } diff --git a/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp b/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp index 53c67e5b3..6533c94e1 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp @@ -60,109 +60,100 @@ namespace TEN::Entities::TR4 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + HAMMERHEAD_ANIM_IDLE; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = HAMMERHEAD_STATE_IDLE; - item->Animation.TargetState = HAMMERHEAD_STATE_IDLE; + SetAnimation(item, HAMMERHEAD_ANIM_IDLE); } void HammerheadControl(short itemNumber) { - if (CreatureActive(itemNumber)) + if (!CreatureActive(itemNumber)) + return; + + auto* item = &g_Level.Items[itemNumber]; + auto* creature = GetCreatureInfo(item); + + if (item->HitPoints <= 0) { - auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); + if (item->Animation.ActiveState != HAMMERHEAD_STATE_DEATH) + SetAnimation(item, HAMMERHEAD_ANIM_DEATH_START); - if (item->HitPoints > 0) + item->HitPoints = 0; + CreatureFloat(itemNumber); + } + else + { + if (item->AIBits) + GetAITarget(creature); + else if (creature->HurtByLara) + creature->Enemy = LaraItem; + + AI_INFO AI; + CreatureAIInfo(item, &AI); + + if (!creature->Enemy->IsLara()) + phd_atan(LaraItem->Pose.Position.z - item->Pose.Position.z, LaraItem->Pose.Position.x - item->Pose.Position.x); + + GetCreatureMood(item, &AI, true); + CreatureMood(item, &AI, true); + + short angle = CreatureTurn(item, creature->MaxTurn); + + switch (item->Animation.ActiveState) { - if (item->AIBits) - GetAITarget(creature); - else if (creature->HurtByLara) - creature->Enemy = LaraItem; + case HAMMERHEAD_STATE_IDLE: + item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_SLOW; + creature->Flags = 0; + break; - AI_INFO AI; - CreatureAIInfo(item, &AI); + case HAMMERHEAD_STATE_SWIM_SLOW: + creature->MaxTurn = ANGLE(7.0f); - if (creature->Enemy != LaraItem) - phd_atan(LaraItem->Pose.Position.z - item->Pose.Position.z, LaraItem->Pose.Position.x - item->Pose.Position.x); - - GetCreatureMood(item, &AI, true); - CreatureMood(item, &AI, true); - - short angle = CreatureTurn(item, creature->MaxTurn); - - switch (item->Animation.ActiveState) + if (AI.distance <= pow(SECTOR(1), 2)) { - case HAMMERHEAD_STATE_IDLE: - item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_SLOW; - creature->Flags = 0; - break; - - case HAMMERHEAD_STATE_SWIM_SLOW: - creature->MaxTurn = ANGLE(7.0f); - - if (AI.distance <= pow(SECTOR(1), 2)) - { - if (AI.distance < pow(682, 2)) - item->Animation.TargetState = HAMMERHEAD_STATE_IDLE_BITE_ATTACK; - } - else - item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_FAST; - - break; - - case HAMMERHEAD_STATE_SWIM_FAST: - if (AI.distance < pow(SECTOR(1), 2)) - item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_SLOW; - - break; - - case HAMMERHEAD_STATE_IDLE_BITE_ATTACK: - if (!creature->Flags) - { - if (item->TestBits(JointBitType::Touch, HammerheadBiteAttackJoints)) - { - DoDamage(creature->Enemy, HAMMERHEAD_BITE_ATTACK_DAMAGE); - CreatureEffect(item, HammerheadBite, DoBloodSplat); - creature->Flags = 1; - } - } - - break; - - default: - break; + if (AI.distance < pow(682, 2)) + item->Animation.TargetState = HAMMERHEAD_STATE_IDLE_BITE_ATTACK; } - - CreatureTilt(item, 0); - CreatureJoint(item, 0, angle * -2); - CreatureJoint(item, 1, angle * -2); - CreatureJoint(item, 2, angle * -2); - CreatureJoint(item, 3, angle * 2); - - // NOTE: in TR2 shark there was a call to CreatureKill with special kill anim - // Hammerhead seems to not have it in original code but this check is still there as a leftover - if (item->Animation.ActiveState == HAMMERHEAD_STATE_KILL) - AnimateItem(item); else + item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_FAST; + + break; + + case HAMMERHEAD_STATE_SWIM_FAST: + if (AI.distance < pow(SECTOR(1), 2)) + item->Animation.TargetState = HAMMERHEAD_STATE_SWIM_SLOW; + + break; + + case HAMMERHEAD_STATE_IDLE_BITE_ATTACK: + if (!creature->Flags) { - CreatureAnimation(itemNumber, angle, 0); - CreatureUnderwater(item, 341); + if (item->TestBits(JointBitType::Touch, HammerheadBiteAttackJoints)) + { + DoDamage(creature->Enemy, HAMMERHEAD_BITE_ATTACK_DAMAGE); + CreatureEffect(item, HammerheadBite, DoBloodSplat); + creature->Flags = 1; + } } + + break; + + default: + break; } + + CreatureTilt(item, 0); + CreatureJoint(item, 0, angle * -2); + CreatureJoint(item, 1, angle * -2); + CreatureJoint(item, 2, angle * -2); + CreatureJoint(item, 3, angle * 2); + + // NOTE: in TR2 shark there was a call to CreatureKill with special kill anim + // Hammerhead seems to not have it in original code but this check is still there as a leftover + if (item->Animation.ActiveState == HAMMERHEAD_STATE_KILL) + AnimateItem(item); else { - item->HitPoints = 0; - - if (item->Animation.ActiveState != HAMMERHEAD_STATE_DEATH) - { - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + HAMMERHEAD_ANIM_DEATH_START; - item->Animation.ActiveState = HAMMERHEAD_STATE_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.FrameNumber].frameBase; - } - - CreatureFloat(itemNumber); + CreatureAnimation(itemNumber, angle, 0); + CreatureUnderwater(item, 341); } } } diff --git a/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp b/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp index ee80886b1..f23c2476a 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_harpy.cpp @@ -75,31 +75,32 @@ namespace TEN::Entities::TR4 HARPY_ANIM_GLIDE = 18 }; - static void TriggerHarpyMissile(PHD_3DPOS* pose, short roomNumber, short mesh) + void TriggerHarpyMissile(PHD_3DPOS* pose, short roomNumber, short mesh) { short fxNumber = CreateNewEffect(roomNumber); - if (fxNumber != -1) - { - auto* fx = &EffectList[fxNumber]; + if (fxNumber == -1) + return; - fx->pos.Position.x = pose->Position.x; - fx->pos.Position.y = pose->Position.y - (GetRandomControl() & 0x3F) - 32; - fx->pos.Position.z = pose->Position.z; - fx->pos.Orientation.x = pose->Orientation.x; - fx->pos.Orientation.y = pose->Orientation.y; - fx->pos.Orientation.z = 0; - fx->roomNumber = roomNumber; - fx->counter = short(2 * GetRandomControl() + 0x8000); - fx->objectNumber = ID_ENERGY_BUBBLES; - fx->speed = (GetRandomControl() & 0x1F) + 96; - fx->flag1 = mesh; - fx->frameNumber = Objects[fx->objectNumber].meshIndex + mesh * 2; - } + auto* fx = &EffectList[fxNumber]; + + fx->pos.Position.x = pose->Position.x; + fx->pos.Position.y = pose->Position.y - (GetRandomControl() & 0x3F) - 32; + fx->pos.Position.z = pose->Position.z; + fx->pos.Orientation.x = pose->Orientation.x; + fx->pos.Orientation.y = pose->Orientation.y; + fx->pos.Orientation.z = 0; + fx->roomNumber = roomNumber; + fx->counter = short(2 * GetRandomControl() + 0x8000); + fx->objectNumber = ID_ENERGY_BUBBLES; + fx->speed = (GetRandomControl() & 0x1F) + 96; + fx->flag1 = mesh; + fx->frameNumber = Objects[fx->objectNumber].meshIndex + mesh * 2; } - static void TriggerHarpyFlame(short itemNumber, ItemInfo* target, byte nodeNumber, short size) + void TriggerHarpyFlame(short itemNumber, ItemInfo* target, byte nodeNumber, short size) { auto* item = &g_Level.Items[itemNumber]; + int dx = target->Pose.Position.x - item->Pose.Position.x; int dz = target->Pose.Position.z - item->Pose.Position.z; @@ -143,7 +144,7 @@ namespace TEN::Entities::TR4 } } - static void TriggerHarpySparks(ItemInfo* target, int x, int y, int z, short xv, short yv, short zv) + void TriggerHarpySparks(ItemInfo* target, int x, int y, int z, short xv, short yv, short zv) { int dx = target->Pose.Position.x - x; int dz = target->Pose.Position.z - z; @@ -180,12 +181,13 @@ namespace TEN::Entities::TR4 } } - static void DoHarpyEffects(ItemInfo* item, CreatureInfo* creature, short itemNumber) + void DoHarpyEffects(ItemInfo* item, CreatureInfo* creature, short itemNumber) { item->ItemFlags[0]++; auto rh = Vector3Int(HarpyAttack1.Position); GetJointAbsPosition(item, &rh, HarpyAttack1.meshNum); + auto lr = Vector3Int(HarpyAttack2.Position); GetJointAbsPosition(item, &lr, HarpyAttack2.meshNum); @@ -269,9 +271,9 @@ namespace TEN::Entities::TR4 if (item->HitPoints <= 0) { - int state = item->Animation.ActiveState - 9; item->HitPoints = 0; + int state = item->Animation.ActiveState - 9; if (state) { state--; @@ -307,7 +309,7 @@ namespace TEN::Entities::TR4 { item->Animation.TargetState = HARPY_STATE_DEATH_END; item->Animation.IsAirborne = false; - item->Animation.Velocity.y = 0; + item->Animation.Velocity.y = 0.0f; item->Pose.Position.y = item->Floor; } @@ -322,10 +324,8 @@ namespace TEN::Entities::TR4 creature->Enemy = nullptr; - for (int i = 0; i < ActiveCreatures.size(); i++) + for (auto& currentCreature : ActiveCreatures) { - auto* currentCreature = ActiveCreatures[i]; - if (currentCreature->ItemNumber == NO_ITEM || currentCreature->ItemNumber == itemNumber) continue; @@ -348,7 +348,7 @@ namespace TEN::Entities::TR4 AI_INFO AI; CreatureAIInfo(item, &AI); - if (creature->Enemy != LaraItem) + if (!creature->Enemy->IsLara()) phd_atan(LaraItem->Pose.Position.z - item->Pose.Position.z, LaraItem->Pose.Position.x - item->Pose.Position.x); GetCreatureMood(item, &AI, true); @@ -437,10 +437,9 @@ namespace TEN::Entities::TR4 { if (AI.distance >= pow(341, 2)) { - if (AI.ahead && + if (AI.ahead && TestProbability(0.5f) && AI.distance >= pow(SECTOR(2), 2) && - AI.distance > pow(SECTOR(3.5f), 2) && - TestProbability(0.5f)) + AI.distance > pow(SECTOR(3.5f), 2)) { item->Animation.TargetState = HARPY_STATE_FLAME_ATTACK; item->ItemFlags[0] = 0; @@ -507,7 +506,7 @@ namespace TEN::Entities::TR4 creature->MaxTurn = ANGLE(2.0f); if (item->TestBits(JointBitType::Touch, HarpySwoopAttackJoints) || - creature->Enemy && !creature->Enemy->IsLara() && + creature->Enemy != nullptr && !creature->Enemy->IsLara() && abs(creature->Enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(1) && AI.distance < pow(SECTOR(2), 2)) { @@ -526,7 +525,7 @@ namespace TEN::Entities::TR4 if (creature->Flags == 0 && (item->TestBits(JointBitType::Touch, HarpyStingerAttackJoints) || - creature->Enemy && !creature->Enemy->IsLara() && + creature->Enemy != nullptr && !creature->Enemy->IsLara() && abs(creature->Enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(1) && AI.distance < pow(SECTOR(2), 2))) { diff --git a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp index f211923c9..60185d1f0 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp @@ -62,10 +62,7 @@ namespace TEN::Entities::TR4 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - item->Animation.AnimNumber = Objects[ID_KNIGHT_TEMPLAR].animIndex + KTEMPLAR_ANIM_IDLE; - item->Animation.TargetState = KTEMPLAR_STATE_IDLE; - item->Animation.ActiveState = KTEMPLAR_STATE_IDLE; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + SetAnimation(item, KTEMPLAR_ANIM_IDLE); item->MeshBits &= 0xF7FF; } @@ -75,8 +72,14 @@ namespace TEN::Entities::TR4 return; auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); auto* object = &Objects[item->ObjectNumber]; + auto* creature = GetCreatureInfo(item); + + short angle = 0; + short tilt = 0; + short joint0 = 0; + short joint1 = 0; + short joint2 = 0; if (item->Animation.AnimNumber == object->animIndex || (item->Animation.AnimNumber - object->animIndex) == KTEMPLAR_ANIM_WALK_FORWARD_RIGHT_1 || @@ -92,12 +95,6 @@ namespace TEN::Entities::TR4 } } - short tilt = 0; - short angle = 0; - short joint0 = 0; - short joint1 = 0; - short joint2 = 0; - // Knight is immortal. if (item->HitPoints < object->HitPoints) item->HitPoints = object->HitPoints; diff --git a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp index bd09df3ed..bbcf21b34 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp @@ -17,7 +17,7 @@ using std::vector; namespace TEN::Entities::TR4 { - constexpr auto MUMMY_ATTACK_DAMAGE = 100; + constexpr auto MUMMY_SWIPE_ATTACK_DAMAGE = 100; constexpr auto MUMMY_IDLE_SWIPE_ATTACK_RANGE = SQUARE(SECTOR(0.5f)); constexpr auto MUMMY_WALK_SWIPE_ATTACK_RANGE = SQUARE(SECTOR(0.67f)); @@ -26,11 +26,12 @@ namespace TEN::Entities::TR4 constexpr auto MUMMY_ARMS_UP_RANGE = SQUARE(SECTOR(3)); constexpr auto MUMMY_AWARE_RANGE = SQUARE(SECTOR(7)); - #define MUMMY_WALK_TURN_ANGLE ANGLE(7.0f) + #define MUMMY_WALK_TURN_RATE_MAX ANGLE(7.0f) + #define MUMMY_ATTACK_TURN_RATE_MAX ANGLE(7.0f) const auto MummyBite1 = BiteInfo(Vector3::Zero, 11); const auto MummyBite2 = BiteInfo(Vector3::Zero, 14); - const vector MummyAttackJoints { 11, 14 }; + const vector MummySwipeAttackJoints { 11, 14 }; enum MummyState { @@ -81,16 +82,10 @@ namespace TEN::Entities::TR4 if (item->TriggerFlags == 2) { SetAnimation(item, MUMMY_ANIM_COLLAPSE_END); - item->Animation.TargetState = MUMMY_STATE_INACTIVE_LYING_DOWN; // TODO: Check if needed. -- Sezz - item->Animation.ActiveState = MUMMY_STATE_INACTIVE_LYING_DOWN; item->Status -= ITEM_INVISIBLE; } else - { SetAnimation(item, MUMMY_ANIM_ARMS_CROSSED); - item->Animation.TargetState = MUMMY_STATE_INACTIVE_ARMS_CROSSED; // TODO: Check if needed. -- Sezz - item->Animation.ActiveState = MUMMY_STATE_INACTIVE_ARMS_CROSSED; - } } void MummyControl(short itemNumber) @@ -101,8 +96,8 @@ namespace TEN::Entities::TR4 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short tilt = 0; short angle = 0; + short tilt = 0; short joint0 = 0; short joint1 = 0; short joint2 = 0; @@ -209,7 +204,7 @@ namespace TEN::Entities::TR4 } else { - creature->MaxTurn = MUMMY_WALK_TURN_ANGLE; + creature->MaxTurn = MUMMY_WALK_TURN_RATE_MAX; if (AI.distance >= MUMMY_ARMS_UP_RANGE) { @@ -223,7 +218,7 @@ namespace TEN::Entities::TR4 break; case MUMMY_STATE_WALK_FORWARD_ARMS_UP: - creature->MaxTurn = MUMMY_WALK_TURN_ANGLE; + creature->MaxTurn = MUMMY_WALK_TURN_RATE_MAX; creature->Flags = 0; if (AI.distance < MUMMY_IDLE_SWIPE_ATTACK_RANGE) @@ -272,26 +267,26 @@ namespace TEN::Entities::TR4 case MUMMY_STATE_IDLE_SWIPE_ATTACK: creature->MaxTurn = 0; - if (abs(AI.angle) >= ANGLE(7.0f)) + if (abs(AI.angle) >= MUMMY_ATTACK_TURN_RATE_MAX) { if (AI.angle >= 0) - item->Pose.Orientation.y += ANGLE(7.0f); + item->Pose.Orientation.y += MUMMY_ATTACK_TURN_RATE_MAX; else - item->Pose.Orientation.y -= ANGLE(7.0f); + item->Pose.Orientation.y -= MUMMY_ATTACK_TURN_RATE_MAX; } else item->Pose.Orientation.y += AI.angle; if (!creature->Flags) { - if (item->TestBits(JointBitType::Touch, MummyAttackJoints)) + if (item->TestBits(JointBitType::Touch, MummySwipeAttackJoints)) { if (item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase && item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameEnd) { - DoDamage(creature->Enemy, MUMMY_ATTACK_DAMAGE); + DoDamage(creature->Enemy, MUMMY_SWIPE_ATTACK_DAMAGE); - if (item->Animation.AnimNumber == Objects[item->ObjectNumber].animIndex + MUMMY_ANIM_IDLE_SWIPE_ATTACK_LEFT) + if (item->Animation.AnimNumber == (Objects[item->ObjectNumber].animIndex + MUMMY_ANIM_IDLE_SWIPE_ATTACK_LEFT)) CreatureEffect2(item, MummyBite1, 5, -1, DoBloodSplat); else CreatureEffect2(item, MummyBite2, 5, -1, DoBloodSplat); @@ -309,11 +304,9 @@ namespace TEN::Entities::TR4 } CreatureTilt(item, 0); - CreatureJoint(item, 0, joint0); CreatureJoint(item, 1, joint1); CreatureJoint(item, 2, joint2); - CreatureAnimation(itemNumber, angle, 0); } } From c10b783bcbb1e36dc4d74283ffa5997f3cff71ce Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 23 Aug 2022 17:01:09 +1000 Subject: [PATCH 035/106] Organise --- TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 24 ++++++++---------- TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp | 9 ++++--- TombEngine/Objects/TR1/Entity/tr1_centaur.cpp | 17 ++++++------- .../Objects/TR1/Entity/tr1_doppelganger.cpp | 16 ++++++------ .../Objects/TR1/Entity/tr1_giant_mutant.cpp | 25 ++++++------------- 5 files changed, 38 insertions(+), 53 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp index e84b60561..709fc0a7f 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp @@ -83,8 +83,8 @@ namespace TEN::Entities::Creatures::TR1 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; + short head = 0; if (item->HitPoints <= 0) { @@ -119,8 +119,8 @@ namespace TEN::Entities::Creatures::TR1 { if (creature->Flags && item->TestBits(JointBitType::Touch, BearAttackJoints)) { - creature->Flags = 0; DoDamage(creature->Enemy, BEAR_SLAM_DAMAGE); + creature->Flags = 0; } break; @@ -143,12 +143,12 @@ namespace TEN::Entities::Creatures::TR1 if (item->HitStatus) creature->Flags = 1; - const bool laraDead = LaraItem->HitPoints <= 0; + bool isLaraDead = LaraItem->HitPoints <= 0; switch (item->Animation.ActiveState) { case BEAR_STATE_IDLE: - if (laraDead) + if (isLaraDead) { if (AI.bite && AI.distance < pow(BEAR_EAT_RANGE, 2)) item->Animation.TargetState = BEAR_STATE_EAT; @@ -167,7 +167,7 @@ namespace TEN::Entities::Creatures::TR1 case BEAR_STATE_STROLL: creature->MaxTurn = BEAR_WALK_TURN_RATE_MAX; - if (laraDead && item->TestBits(JointBitType::Touch, BearAttackJoints) && AI.ahead) + if (isLaraDead && item->TestBits(JointBitType::Touch, BearAttackJoints) && AI.ahead) item->Animation.TargetState = BEAR_STATE_IDLE; else if (creature->Mood != MoodType::Bored) { @@ -178,8 +178,8 @@ namespace TEN::Entities::Creatures::TR1 } else if (TestProbability(BEAR_ROAR_CHANCE)) { - item->Animation.RequiredState = BEAR_STATE_ROAR; item->Animation.TargetState = BEAR_STATE_IDLE; + item->Animation.RequiredState = BEAR_STATE_ROAR; } break; @@ -188,11 +188,9 @@ namespace TEN::Entities::Creatures::TR1 creature->MaxTurn = BEAR_RUN_TURN_RATE_MAX; if (item->TestBits(JointBitType::Touch, BearAttackJoints)) - { DoDamage(creature->Enemy, BEAR_RUN_DAMAGE); - } - if (creature->Mood == MoodType::Bored || laraDead) + if (creature->Mood == MoodType::Bored || isLaraDead) item->Animation.TargetState = BEAR_STATE_IDLE; else if (AI.ahead && !item->Animation.RequiredState) { @@ -229,8 +227,8 @@ namespace TEN::Entities::Creatures::TR1 case BEAR_STATE_WALK_FORWARD: if (creature->Flags) { - item->Animation.RequiredState = BEAR_STATE_STROLL; item->Animation.TargetState = BEAR_STATE_REAR; + item->Animation.RequiredState = BEAR_STATE_STROLL; } else if (AI.ahead && item->TestBits(JointBitType::Touch, BearAttackJoints)) item->Animation.TargetState = BEAR_STATE_REAR; @@ -241,13 +239,13 @@ namespace TEN::Entities::Creatures::TR1 } else if (creature->Mood == MoodType::Bored || TestProbability(BEAR_ROAR_CHANCE)) { - item->Animation.RequiredState = BEAR_STATE_ROAR; item->Animation.TargetState = BEAR_STATE_REAR; + item->Animation.RequiredState = BEAR_STATE_ROAR; } else if (AI.distance > pow(BEAR_REAR_RANGE, 2) || TestProbability(BEAR_DROP_CHANCE)) { - item->Animation.RequiredState = BEAR_STATE_IDLE; item->Animation.TargetState = BEAR_STATE_REAR; + item->Animation.RequiredState = BEAR_STATE_IDLE; } break; @@ -266,8 +264,8 @@ namespace TEN::Entities::Creatures::TR1 if (!item->Animation.RequiredState && item->TestBits(JointBitType::Touch, BearAttackJoints)) { - CreatureEffect(item, BearBite, DoBloodSplat); DoDamage(creature->Enemy, BEAR_ATTACK_DAMAGE); + CreatureEffect(item, BearBite, DoBloodSplat); item->Animation.RequiredState = BEAR_STATE_IDLE; } diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp index 219a35439..649050997 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp @@ -115,10 +115,11 @@ namespace TEN::Entities::Creatures::TR1 auto* creature = GetCreatureInfo(item); int waterHeight = GetRatWaterHeight(item); - short head = 0; - short angle = 0; bool isOnWater = waterHeight != NO_HEIGHT; + short angle = 0; + short head = 0; + if (item->HitPoints <= 0) { if (item->Animation.ActiveState != BIG_RAT_STATE_LAND_DEATH && @@ -183,9 +184,9 @@ namespace TEN::Entities::Creatures::TR1 if (!item->Animation.RequiredState && AI.ahead && item->TestBits(JointBitType::Touch, BigRatBite.meshNum)) { - item->Animation.RequiredState = BIG_RAT_STATE_IDLE; DoDamage(creature->Enemy, BIG_RAT_BITE_ATTACK_DAMAGE); CreatureEffect(item, BigRatBite, DoBloodSplat); + item->Animation.RequiredState = BIG_RAT_STATE_IDLE; } break; @@ -194,9 +195,9 @@ namespace TEN::Entities::Creatures::TR1 if (!item->Animation.RequiredState && AI.ahead && item->TestBits(JointBitType::Touch, BigRatBite.meshNum)) { - item->Animation.RequiredState = BIG_RAT_STATE_RUN_FORWARD; DoDamage(creature->Enemy, BIG_RAT_POUNCE_ATTACK_DAMAGE); CreatureEffect(item, BigRatBite, DoBloodSplat); + item->Animation.RequiredState = BIG_RAT_STATE_RUN_FORWARD; } break; diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp index ffe8549a5..5bf82d856 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp @@ -23,15 +23,15 @@ using std::vector; namespace TEN::Entities::Creatures::TR1 { - constexpr auto CENTAUR_REAR_DAMAGE = 200; - constexpr auto CENTAUR_REAR_RANGE = SECTOR(1.5f); - constexpr auto CENTAUR_REAR_CHANCE = 0.003f; + constexpr auto CENTAUR_REAR_DAMAGE = 200; + constexpr auto CENTAUR_REAR_RANGE = SECTOR(1.5f); + constexpr auto CENTAUR_REAR_CHANCE = 0.003f; constexpr auto CENTAUR_BOMB_VELOCITY = 20; #define CENTAUR_TURN_RATE_MAX ANGLE(4.0f) const auto CentaurRocketBite = BiteInfo(Vector3(11.0f, 415.0f, 41.0f), 13); - const auto CentaurRearBite = BiteInfo(Vector3(50.0f, 30.0f, 0.0f), 5); + const auto CentaurRearBite = BiteInfo(Vector3(50.0f, 30.0f, 0.0f), 5); const vector CentaurAttackJoints = { 0, 3, 4, 7, 8, 16, 17 }; enum CentaurState @@ -58,17 +58,14 @@ namespace TEN::Entities::Creatures::TR1 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; + short angle = 0; + short head = 0; if (item->HitPoints <= 0) { if (item->Animation.ActiveState != CENTAUR_STATE_DEATH) - { - item->Animation.AnimNumber = Objects[ID_CENTAUR_MUTANT].animIndex + CENTAUR_ANIM_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = CENTAUR_STATE_DEATH; - } + SetAnimation(item, CENTAUR_ANIM_DEATH); } else { diff --git a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp index 7c9c06de0..29e45ce8e 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_doppelganger.cpp @@ -80,26 +80,24 @@ namespace TEN::Entities::Creatures::TR1 int laraFloorHeight = GetCollision(LaraItem).Position.Floor; // Animate bacon Lara, mirroring Lara's position. - item->Animation.FrameNumber = LaraItem->Animation.FrameNumber; item->Animation.AnimNumber = LaraItem->Animation.AnimNumber; - item->Pose.Position.x = pos.x; - item->Pose.Position.y = pos.y; - item->Pose.Position.z = pos.z; + 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; ItemNewRoom(itemNumber, LaraItem->RoomNumber); // Compare floor heights. - if (item->Floor >= laraFloorHeight + SECTOR(1) + 1 && // Add 1 to avoid bacon Lara dying when exiting water. + if (item->Floor >= (laraFloorHeight + SECTOR(1) + 1) && // Add 1 to avoid bacon Lara dying when exiting water. !LaraItem->Animation.IsAirborne) { SetAnimation(item, LA_JUMP_WALL_SMASH_START); - item->Animation.Velocity.z = 0; - item->Animation.Velocity.y = 0; item->Animation.IsAirborne = true; - item->Data = -1; + item->Animation.Velocity.y = 0.0f; + item->Animation.Velocity.z = 0.0f; item->Pose.Position.y += 50; + item->Data = -1; } } @@ -114,8 +112,8 @@ namespace TEN::Entities::Creatures::TR1 item->Pose.Position.y = item->Floor; TestTriggers(item, true); - item->Animation.Velocity.y = 0; item->Animation.IsAirborne = false; + item->Animation.Velocity.y = 0.0f; item->Animation.TargetState = LS_DEATH; item->Animation.RequiredState = LS_DEATH; } diff --git a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp index 9d9f200f7..e15d5e498 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp @@ -69,17 +69,13 @@ namespace TEN::Entities::Creatures::TR1 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; + short head = 0; if (item->HitPoints <= 0) { if (item->Animation.ActiveState != MUTANT_STATE_DEATH) - { - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + MUTANT_ANIM_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = MUTANT_STATE_DEATH; - } + SetAnimation(item, MUTANT_ANIM_DEATH); } else { @@ -95,9 +91,7 @@ namespace TEN::Entities::Creatures::TR1 angle = (short)phd_atan(creature->Target.z - item->Pose.Position.z, creature->Target.x - item->Pose.Position.x) - item->Pose.Orientation.y; if (item->TouchBits) - { DoDamage(creature->Enemy, MUTANT_CONTACT_DAMAGE); - } switch (item->Animation.ActiveState) { @@ -181,8 +175,8 @@ namespace TEN::Entities::Creatures::TR1 case MUTANT_STATE_ATTACK_1: if (!creature->Flags && item->TestBits(JointBitType::Touch, MutantAttackRightJoints)) { - creature->Flags = 1; DoDamage(creature->Enemy, MUTANT_ATTACK_DAMAGE); + creature->Flags = 1; } break; @@ -190,8 +184,8 @@ namespace TEN::Entities::Creatures::TR1 case MUTANT_STATE_ATTACK_2: if (!creature->Flags && item->TestBits(JointBitType::Touch, MutantAttackJoints)) { - creature->Flags = 1; DoDamage(creature->Enemy, MUTANT_ATTACK_DAMAGE); + creature->Flags = 1; } break; @@ -205,14 +199,11 @@ namespace TEN::Entities::Creatures::TR1 LaraItem->Animation.AnimNumber = Objects[ID_LARA_EXTRA_ANIMS].animIndex + LARA_GIANT_MUTANT_DEATH; LaraItem->Animation.FrameNumber = g_Level.Anims[LaraItem->Animation.AnimNumber].frameBase; - LaraItem->Animation.ActiveState = LaraItem->Animation.TargetState = 46; - LaraItem->RoomNumber = item->RoomNumber; - LaraItem->Pose.Position.x = item->Pose.Position.x; - LaraItem->Pose.Position.y = item->Pose.Position.y; - LaraItem->Pose.Position.z = item->Pose.Position.z; - LaraItem->Pose.Orientation.y = item->Pose.Orientation.y; - LaraItem->Pose.Orientation.x = LaraItem->Pose.Orientation.z = 0; + LaraItem->Animation.ActiveState = 46; + LaraItem->Animation.TargetState = 46; LaraItem->Animation.IsAirborne = false; + LaraItem->Pose = PHD_3DPOS(item->Pose.Position, 0, item->Pose.Orientation.y, 0); + LaraItem->RoomNumber = item->RoomNumber; LaraItem->HitPoints = -1; Lara.Air = -1; Lara.Control.HandStatus = HandStatus::Busy; From abeb0920fda9833f83f98509fd880f8a6ede77f8 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 23 Aug 2022 22:08:46 +0100 Subject: [PATCH 036/106] First stage of attempt to defuck inventory code and allow to set/unset infinite ammo/consumables --- TombEngine/Game/health.cpp | 2 +- TombEngine/Game/pickup/pickup.cpp | 22 +++++++++-- TombEngine/Game/pickup/pickup.h | 5 ++- TombEngine/Game/pickup/pickup_ammo.cpp | 39 +++++++++++++------ TombEngine/Game/pickup/pickup_ammo.h | 6 ++- TombEngine/Game/pickup/pickup_consumable.cpp | 32 ++++++++++----- TombEngine/Game/pickup/pickup_consumable.h | 6 ++- TombEngine/Game/pickup/pickup_key_items.cpp | 31 ++++++++++----- TombEngine/Game/pickup/pickup_key_items.h | 6 ++- TombEngine/Game/pickup/pickup_misc_items.cpp | 10 +++-- TombEngine/Game/pickup/pickup_misc_items.h | 2 + TombEngine/Game/pickup/pickup_weapon.cpp | 22 +++++------ TombEngine/Game/pickup/pickup_weapon.h | 6 ++- TombEngine/Game/pickup/pickuputil.h | 7 ++++ .../Objects/TR4/Object/tr4_sarcophagus.cpp | 2 +- .../TEN/Inventory/InventoryHandler.cpp | 21 ++++++---- 16 files changed, 150 insertions(+), 69 deletions(-) diff --git a/TombEngine/Game/health.cpp b/TombEngine/Game/health.cpp index a106b100d..c3ab89b71 100644 --- a/TombEngine/Game/health.cpp +++ b/TombEngine/Game/health.cpp @@ -265,7 +265,7 @@ void AddDisplayPickup(GAME_OBJECT_ID objectNumber) } // No free slot found; pickup the object without displaying it. - PickedUpObject(objectNumber, 0); + PickedUpObject(objectNumber, std::nullopt); } void InitialisePickupDisplay() diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp index 67ab19a4e..93d778391 100644 --- a/TombEngine/Game/pickup/pickup.cpp +++ b/TombEngine/Game/pickup/pickup.cpp @@ -1,6 +1,7 @@ #include "framework.h" #include "Game/pickup/pickup.h" +#include "pickuputil.h" #include "Game/animation.h" #include "Game/camera.h" #include "Game/collision/collide_item.h" @@ -128,10 +129,23 @@ short RPickups[16]; short getThisItemPlease = NO_ITEM; Vector3Int OldPickupPos; -void PickedUpObject(GAME_OBJECT_ID objectID, int count) +bool SetInventoryCount(GAME_OBJECT_ID objectID, int count) +{ + if (!TryModifyWeapon(Lara, objectID, count, ModificationType::Set) && + !TryModifyingAmmo(Lara, objectID, count, ModificationType::Set) && + !TryModifyingKeyItem(Lara, objectID, count, ModificationType::Set) && + !TryModifyingConsumable(Lara, objectID, count, ModificationType::Set) && + !TryModifyMiscCount(Lara, objectID, count, ModificationType::Set)) + { + return false; + } + return true; +} + +void PickedUpObject(GAME_OBJECT_ID objectID, std::optional count) { // see if the items fit into one of these easy groups - if (!TryAddingWeapon(Lara, objectID, count) && + if (!TryAddingWeapon(Lara, objectID) && !TryAddingAmmo(Lara, objectID, count) && !TryAddingKeyItem(Lara, objectID, count) && !TryAddingConsumable(Lara, objectID, count) && @@ -166,10 +180,10 @@ int GetInventoryCount(GAME_OBJECT_ID objectID) return 0; } -void RemoveObjectFromInventory(GAME_OBJECT_ID objectID, int count) +void RemoveObjectFromInventory(GAME_OBJECT_ID objectID, std::optional count) { // see if the items fit into one of these easy groups - if (!TryRemovingWeapon(Lara, objectID, count) && + if (!TryRemovingWeapon(Lara, objectID) && !TryRemovingAmmo(Lara, objectID, count) && !TryRemovingKeyItem(Lara, objectID, count) && !TryRemovingConsumable(Lara, objectID, count) && diff --git a/TombEngine/Game/pickup/pickup.h b/TombEngine/Game/pickup/pickup.h index 6167b7fb4..e7fd887ec 100644 --- a/TombEngine/Game/pickup/pickup.h +++ b/TombEngine/Game/pickup/pickup.h @@ -11,8 +11,9 @@ extern short RPickups[16]; extern Vector3Int OldPickupPos; void InitialisePickup(short itemNumber); -void PickedUpObject(GAME_OBJECT_ID objectID, int count); -void RemoveObjectFromInventory(GAME_OBJECT_ID objectID, int count); +void PickedUpObject(GAME_OBJECT_ID objectID, std::optional count = std::nullopt); +bool SetInventoryCount(GAME_OBJECT_ID objectID, int count); +void RemoveObjectFromInventory(GAME_OBJECT_ID objectID, std::optional count = std::nullopt); int GetInventoryCount(GAME_OBJECT_ID objectID); void CollectCarriedItems(ItemInfo* item); void PickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); diff --git a/TombEngine/Game/pickup/pickup_ammo.cpp b/TombEngine/Game/pickup/pickup_ammo.cpp index 18eda360c..c994be5cf 100644 --- a/TombEngine/Game/pickup/pickup_ammo.cpp +++ b/TombEngine/Game/pickup/pickup_ammo.cpp @@ -34,7 +34,7 @@ static constexpr std::array kAmmo } }; -static bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount, bool add) +bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType) { int arrayPos = GetArraySlot(kAmmo, objectID); if (-1 == arrayPos) @@ -42,26 +42,41 @@ static bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount AmmoPickupInfo info = kAmmo[arrayPos]; - auto currentAmmo = lara.Weapons[(int)info.LaraWeaponType].Ammo[(int)info.AmmoType]; - if (!currentAmmo.hasInfinite()) + auto & currentWeapon = lara.Weapons[(int)info.LaraWeaponType]; + auto & currentAmmo = currentWeapon.Ammo[(int)info.AmmoType]; + + switch(modType) { - int defaultModify = add ? info.Amount : -info.Amount; - int newVal = int{ currentAmmo.getCount() } + (amount ? amount : defaultModify); - lara.Weapons[(int)info.LaraWeaponType].Ammo[(int)info.AmmoType] = std::max(0, newVal); - } + case ModificationType::Set: + currentAmmo = amount.value(); + currentAmmo.setInfinite(amount == -1); + + break; + + default: + if (!currentAmmo.hasInfinite()) + { + int defaultModify = modType == ModificationType::Add ? info.Amount : -info.Amount; + int newVal = int{ currentAmmo.getCount() } + (amount.has_value() ? amount.value() : defaultModify); + currentAmmo = std::max(0, newVal); + } + break; + }; return true; } -// We need the extra bool because amount might be zero to signify the default amount. -bool TryAddingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount) +bool TryAddingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount) { - return TryModifyingAmmo(lara, objectID, amount, true); + return TryModifyingAmmo(lara, objectID, amount, ModificationType::Add); } -bool TryRemovingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount) +bool TryRemovingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount) { - return TryModifyingAmmo(lara, objectID, -amount, false); + if (amount.has_value()) + return TryModifyingAmmo(lara, objectID, -amount.value(), ModificationType::Remove); + else + return TryModifyingAmmo(lara, objectID, amount, ModificationType::Remove); } std::optional GetAmmoCount(LaraInfo& lara, GAME_OBJECT_ID objectID) diff --git a/TombEngine/Game/pickup/pickup_ammo.h b/TombEngine/Game/pickup/pickup_ammo.h index 83e685fed..4a05e92b2 100644 --- a/TombEngine/Game/pickup/pickup_ammo.h +++ b/TombEngine/Game/pickup/pickup_ammo.h @@ -1,8 +1,10 @@ #pragma once +enum class ModificationType; enum GAME_OBJECT_ID : short; struct LaraInfo; -bool TryAddingAmmo(LaraInfo&, GAME_OBJECT_ID objectID, int amount = 0); -bool TryRemovingAmmo(LaraInfo&, GAME_OBJECT_ID objectID, int amount = 0); +bool TryAddingAmmo(LaraInfo&, GAME_OBJECT_ID objectID, std::optional amount = std::nullopt); +bool TryRemovingAmmo(LaraInfo&, GAME_OBJECT_ID objectID, std::optional amount = std::nullopt); +bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType); std::optional GetAmmoCount(LaraInfo&, GAME_OBJECT_ID objectID); diff --git a/TombEngine/Game/pickup/pickup_consumable.cpp b/TombEngine/Game/pickup/pickup_consumable.cpp index 29b7d1123..6ce0859c5 100644 --- a/TombEngine/Game/pickup/pickup_consumable.cpp +++ b/TombEngine/Game/pickup/pickup_consumable.cpp @@ -25,32 +25,44 @@ static constexpr std::array kConsumables = } }; -static bool TryModifyingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount, bool add) +bool TryModifyingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType) { int arrayPos = GetArraySlot(kConsumables, objectID); if (-1 == arrayPos) return false; ConsumablePickupInfo info = kConsumables[arrayPos]; - - if (lara.Inventory.*(info.Count) != -1) + auto & currentAmt = lara.Inventory.*(info.Count); + switch (modType) { - int defaultModify = add ? info.Amount : -info.Amount; - int newVal = lara.Inventory.*(info.Count) + (amount ? amount : defaultModify); - lara.Inventory.*(info.Count) = std::max(0, newVal); + case ModificationType::Set: + currentAmt = amount.value(); + break; + + default: + if (currentAmt != -1) + { + int defaultModify = ModificationType::Add == modType ? info.Amount : -info.Amount; + int newVal = currentAmt + (amount.has_value() ? amount.value() : defaultModify); + currentAmt = std::max(0, newVal); + } + break; } return true; } -bool TryAddingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount) +bool TryAddingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount) { - return TryModifyingConsumable(lara, objectID, amount, true); + return TryModifyingConsumable(lara, objectID, amount, ModificationType::Add); } -bool TryRemovingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount) +bool TryRemovingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount) { - return TryModifyingConsumable(lara, objectID, -amount, false); + if (amount.has_value()) + return TryModifyingConsumable(lara, objectID, -amount.value(), ModificationType::Remove); + else + return TryModifyingConsumable(lara, objectID, amount, ModificationType::Remove); } std::optional GetConsumableCount(LaraInfo& lara, GAME_OBJECT_ID objectID) diff --git a/TombEngine/Game/pickup/pickup_consumable.h b/TombEngine/Game/pickup/pickup_consumable.h index e2c2d56d9..fcf3acf5b 100644 --- a/TombEngine/Game/pickup/pickup_consumable.h +++ b/TombEngine/Game/pickup/pickup_consumable.h @@ -1,8 +1,10 @@ #pragma once +enum class ModificationType; enum GAME_OBJECT_ID : short; struct LaraInfo; -bool TryAddingConsumable(LaraInfo&, GAME_OBJECT_ID objectID, int amount = 0); -bool TryRemovingConsumable(LaraInfo&, GAME_OBJECT_ID objectID, int amount = 0); +bool TryAddingConsumable(LaraInfo&, GAME_OBJECT_ID objectID, std::optional amount = 0); +bool TryRemovingConsumable(LaraInfo&, GAME_OBJECT_ID objectID, std::optional amount = 0); +bool TryModifyingConsumable(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType); std::optional GetConsumableCount(LaraInfo&, GAME_OBJECT_ID objectID); diff --git a/TombEngine/Game/pickup/pickup_key_items.cpp b/TombEngine/Game/pickup/pickup_key_items.cpp index aa2a16572..0d1ca734e 100644 --- a/TombEngine/Game/pickup/pickup_key_items.cpp +++ b/TombEngine/Game/pickup/pickup_key_items.cpp @@ -2,7 +2,7 @@ #include "Game/pickup/pickup_key_items.h" #include "Game/Lara/lara_struct.h" -#include "Game/pickup/pickup_misc_items.h" +#include "Game/pickup/pickuputil.h" #include "Objects/objectslist.h" template struct KeyPickupInfo @@ -64,29 +64,42 @@ template<> static std::pair GetArrayInternal<0>(LaraInfo& lara, GA return TestAgainstRange<0>(lara, objectID); } -static bool TryModifyingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount, bool add) +bool TryModifyingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType) { // kick off the recursion starting at the last element auto result = GetArrayInternal(lara, objectID); + if (result.first) { - int defaultModify = add ? kDefaultPickupAmount : -kDefaultPickupAmount; - int newVal = int{result.first[result.second]} + (amount ? amount : defaultModify); - result.first[result.second] = std::max(0, newVal); + auto& amt = result.first[result.second]; + switch (modType) + { + case ModificationType::Set: + // infinite key items not yet implemented + amt = amount.value(); + break; + default: + int defaultModify = modType == ModificationType::Add ? kDefaultPickupAmount : -kDefaultPickupAmount; + int newVal = int{ result.first[result.second] } + (amount.has_value() ? amount.value() : defaultModify); + result.first[result.second] = std::max(0, newVal); + } return true; } return false; } -bool TryAddingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, int count) +bool TryAddingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount) { - return TryModifyingKeyItem(lara, objectID, count, true); + return TryModifyingKeyItem(lara, objectID, amount, ModificationType::Add); } -bool TryRemovingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, int count) +bool TryRemovingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount) { - return TryModifyingKeyItem(lara, objectID, -count, false); + if(amount.has_value()) + return TryModifyingKeyItem(lara, objectID, -amount.value(), ModificationType::Remove); + else + return TryModifyingKeyItem(lara, objectID, amount, ModificationType::Remove); } std::optional GetKeyItemCount(LaraInfo& lara, GAME_OBJECT_ID objectID) diff --git a/TombEngine/Game/pickup/pickup_key_items.h b/TombEngine/Game/pickup/pickup_key_items.h index 5160d0c96..4b17fe653 100644 --- a/TombEngine/Game/pickup/pickup_key_items.h +++ b/TombEngine/Game/pickup/pickup_key_items.h @@ -1,8 +1,10 @@ #pragma once +enum class ModificationType; enum GAME_OBJECT_ID : short; struct LaraInfo; -bool TryAddingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, int count); -bool TryRemovingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, int count); +bool TryAddingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount = std::nullopt); +bool TryRemovingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount = std::nullopt); +bool TryModifyingKeyItem(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType); std::optional GetKeyItemCount(LaraInfo& lara, GAME_OBJECT_ID objectID); diff --git a/TombEngine/Game/pickup/pickup_misc_items.cpp b/TombEngine/Game/pickup/pickup_misc_items.cpp index afc74a7ee..347c6e408 100644 --- a/TombEngine/Game/pickup/pickup_misc_items.cpp +++ b/TombEngine/Game/pickup/pickup_misc_items.cpp @@ -1,7 +1,6 @@ #include "framework.h" #include "Game/pickup/pickup_misc_items.h" -#include #include "Game/Lara/lara_struct.h" #include "Game/pickup/pickuputil.h" #include "Objects/objectslist.h" @@ -33,11 +32,14 @@ auto LaserSightIsEquipped(LaraInfo& lara) return false; }; -static bool TryModifyMiscCount(LaraInfo & lara, GAME_OBJECT_ID objectID, bool add) +bool TryModifyMiscCount(LaraInfo & lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType) { // If adding, replace the small/large waterskin with one of the requested // capacity. If removing, only remove the waterskin if it contains the given // capacity. + + bool add = ModificationType::Add == modType || ((ModificationType::Set == modType) && amount != 0); + auto modifyWaterSkinAmount = [&](byte& currentFlag, byte newFlag) { if (add) @@ -140,12 +142,12 @@ static bool TryModifyMiscCount(LaraInfo & lara, GAME_OBJECT_ID objectID, bool ad bool TryAddMiscItem(LaraInfo & lara, GAME_OBJECT_ID objectID) { - return TryModifyMiscCount(lara, objectID, true); + return TryModifyMiscCount(lara, objectID, std::nullopt, ModificationType::Add); } bool TryRemoveMiscItem(LaraInfo & lara, GAME_OBJECT_ID objectID) { - return TryModifyMiscCount(lara, objectID, false); + return TryModifyMiscCount(lara, objectID, std::nullopt, ModificationType::Remove); } std::optional HasMiscItem(LaraInfo& lara, GAME_OBJECT_ID objectID) diff --git a/TombEngine/Game/pickup/pickup_misc_items.h b/TombEngine/Game/pickup/pickup_misc_items.h index 9b1784418..6d03ef06b 100644 --- a/TombEngine/Game/pickup/pickup_misc_items.h +++ b/TombEngine/Game/pickup/pickup_misc_items.h @@ -1,8 +1,10 @@ #pragma once +enum class ModificationType; enum GAME_OBJECT_ID : short; struct LaraInfo; bool TryAddMiscItem(LaraInfo& lara, GAME_OBJECT_ID objectID); bool TryRemoveMiscItem(LaraInfo& lara, GAME_OBJECT_ID objectID); +bool TryModifyMiscCount(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType); std::optional HasMiscItem(LaraInfo& lara, GAME_OBJECT_ID objectID); diff --git a/TombEngine/Game/pickup/pickup_weapon.cpp b/TombEngine/Game/pickup/pickup_weapon.cpp index 4e03ac4ea..d2141b934 100644 --- a/TombEngine/Game/pickup/pickup_weapon.cpp +++ b/TombEngine/Game/pickup/pickup_weapon.cpp @@ -49,7 +49,7 @@ static int GetWeapon(GAME_OBJECT_ID objectID) return -1; } -static bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int ammoAmount, bool add) +bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional count, ModificationType type) { int arrayPos = GetArraySlot(kWeapons, objectID); if (-1 == arrayPos) @@ -63,8 +63,10 @@ static bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int ammoAmo if (!currWeapon.Present) currWeapon.SelectedAmmo = WeaponAmmoType::Ammo1; - + + bool add = ModificationType::Add == type || ((ModificationType::Set == type) && count != 0); currWeapon.Present = add; + if(!add) { if (info.LaraWeaponType == lara.Control.Weapon.GunType || info.LaraWeaponType == lara.Control.Weapon.LastGunType) @@ -94,21 +96,19 @@ static bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int ammoAmo } } - auto ammoID = info.AmmoID; - return add ? TryAddingAmmo(lara, ammoID, ammoAmount) : TryRemovingAmmo(lara, ammoID, ammoAmount); + return true; } -// Adding a weapon will either give the player the weapon + an amount of ammo, or, -// if they already have the weapon, simply the ammo. -bool TryAddingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount) +// Adding a weapon will not give the player any ammo even if they already have the weapon +bool TryAddingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID) { - return TryModifyWeapon(lara, objectID, amount, true); + return TryModifyWeapon(lara, objectID, 1, ModificationType::Add); } -// Removing a weapon is the reverse of the above; it will remove the weapon (if it's there) and the amount of ammo. -bool TryRemovingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount) +// Removing a weapon is the reverse of the above; it will remove the weapon (if it's there). +bool TryRemovingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID) { - return TryModifyWeapon(lara, objectID, amount, false); + return TryModifyWeapon(lara, objectID, 1, ModificationType::Remove); } std::optional HasWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID) diff --git a/TombEngine/Game/pickup/pickup_weapon.h b/TombEngine/Game/pickup/pickup_weapon.h index d61f86dd9..7ae6ace52 100644 --- a/TombEngine/Game/pickup/pickup_weapon.h +++ b/TombEngine/Game/pickup/pickup_weapon.h @@ -1,8 +1,10 @@ #pragma once +enum class ModificationType; enum GAME_OBJECT_ID : short; struct LaraInfo; -bool TryAddingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount = 0); -bool TryRemovingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, int amount = 0); +bool TryAddingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID); +bool TryRemovingWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID); +bool TryModifyWeapon(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional count, ModificationType type); std::optional HasWeapon(LaraInfo&, GAME_OBJECT_ID objectID); diff --git a/TombEngine/Game/pickup/pickuputil.h b/TombEngine/Game/pickup/pickuputil.h index 6904d15f5..9f1217459 100644 --- a/TombEngine/Game/pickup/pickuputil.h +++ b/TombEngine/Game/pickup/pickuputil.h @@ -2,6 +2,13 @@ enum GAME_OBJECT_ID : short; +enum class ModificationType +{ + Add, + Remove, + Set +}; + // Given an array and an Object ID, iterate through the array until we find // an ID that matches the ID we've passed in. template int GetArraySlot(std::array const& arr, GAME_OBJECT_ID objectID) diff --git a/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp b/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp index de7c8f3ae..62a14b29f 100644 --- a/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp +++ b/TombEngine/Objects/TR4/Object/tr4_sarcophagus.cpp @@ -86,7 +86,7 @@ void SarcophagusCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* c { if (Objects[currentItem->ObjectNumber].isPickup) { - PickedUpObject(static_cast(currentItem->ObjectNumber), 0); + PickedUpObject(currentItem->ObjectNumber); currentItem->Status = ITEM_ACTIVE; currentItem->ItemFlags[3] = 1; AddDisplayPickup(currentItem->ObjectNumber); diff --git a/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp b/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp index 33e4f699b..3af82d1a1 100644 --- a/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Inventory/InventoryHandler.cpp @@ -11,20 +11,29 @@ Inventory manipulation @pragma nostrip */ + namespace InventoryHandler { static void InventoryAdd(ItemEnumPair slot, sol::optional count) { - // If 0 is passed in, then the amount added will be the default amount + // If nil is passed in, then the amount added will be the default amount // for that pickup - i.e. the amount you would get from picking up the // item in-game (e.g. 1 for medipacks, 12 for flares). - PickedUpObject(slot.m_pair.first, count.value_or(0)); + + //can't use value_or(std::nullopt) here because nullopt isn't an int + if (count.has_value()) + PickedUpObject(slot.m_pair.first, count.value()); + else + PickedUpObject(slot.m_pair.first, std::nullopt); } static void InventoryRemove(ItemEnumPair slot, sol::optional count) { - // 0 is default for the same reason as in InventoryAdd. - RemoveObjectFromInventory(slot.m_pair.first, count.value_or(0)); + //can't use value_or(std::nullopt) here because nullopt isn't an int + if (count.has_value()) + RemoveObjectFromInventory(slot.m_pair.first, count.value()); + else + RemoveObjectFromInventory(slot.m_pair.first, std::nullopt); } static int InventoryGetCount(ItemEnumPair slot) @@ -34,9 +43,7 @@ namespace InventoryHandler static void InventorySetCount(ItemEnumPair slot, int count) { - // add the amount we'd need to add to get to count - int currAmt = GetInventoryCount(slot.m_pair.first); - InventoryAdd(slot, count - currAmt); + SetInventoryCount(slot.m_pair.first, count); } static void InventoryCombine(int slot1, int slot2) From 93a0539fcb9db912c3841f60016f8650c505a692 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 23 Aug 2022 22:09:13 +0100 Subject: [PATCH 037/106] Cleanup --- TombEngine/Game/health.cpp | 2 +- TombEngine/Game/pickup/pickup.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/TombEngine/Game/health.cpp b/TombEngine/Game/health.cpp index c3ab89b71..c955d436a 100644 --- a/TombEngine/Game/health.cpp +++ b/TombEngine/Game/health.cpp @@ -265,7 +265,7 @@ void AddDisplayPickup(GAME_OBJECT_ID objectNumber) } // No free slot found; pickup the object without displaying it. - PickedUpObject(objectNumber, std::nullopt); + PickedUpObject(objectNumber); } void InitialisePickupDisplay() diff --git a/TombEngine/Game/pickup/pickup.h b/TombEngine/Game/pickup/pickup.h index e7fd887ec..cc55419e7 100644 --- a/TombEngine/Game/pickup/pickup.h +++ b/TombEngine/Game/pickup/pickup.h @@ -11,8 +11,8 @@ extern short RPickups[16]; extern Vector3Int OldPickupPos; void InitialisePickup(short itemNumber); -void PickedUpObject(GAME_OBJECT_ID objectID, std::optional count = std::nullopt); bool SetInventoryCount(GAME_OBJECT_ID objectID, int count); +void PickedUpObject(GAME_OBJECT_ID objectID, std::optional count = std::nullopt); void RemoveObjectFromInventory(GAME_OBJECT_ID objectID, std::optional count = std::nullopt); int GetInventoryCount(GAME_OBJECT_ID objectID); void CollectCarriedItems(ItemInfo* item); From 269104a41c8c7bfa301edb0a189cd33f56c45bfb Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 24 Aug 2022 15:00:56 +0100 Subject: [PATCH 038/106] Fix shotgun count and add documentation for new inventory functions. --- TombEngine/Game/pickup/pickup_ammo.cpp | 5 +- .../TEN/Inventory/InventoryHandler.cpp | 55 +++++++++---------- 2 files changed, 27 insertions(+), 33 deletions(-) diff --git a/TombEngine/Game/pickup/pickup_ammo.cpp b/TombEngine/Game/pickup/pickup_ammo.cpp index c994be5cf..b41cfc6d7 100644 --- a/TombEngine/Game/pickup/pickup_ammo.cpp +++ b/TombEngine/Game/pickup/pickup_ammo.cpp @@ -19,8 +19,8 @@ static constexpr std::array kAmmo { { ID_PISTOLS_AMMO_ITEM, LaraWeaponType::Pistol, WeaponAmmoType::Ammo1, 0 }, { ID_UZI_AMMO_ITEM, LaraWeaponType::Uzi, WeaponAmmoType::Ammo1, 30 }, - { ID_SHOTGUN_AMMO1_ITEM, LaraWeaponType::Shotgun, WeaponAmmoType::Ammo1, 36 }, - { ID_SHOTGUN_AMMO2_ITEM, LaraWeaponType::Shotgun, WeaponAmmoType::Ammo2, 36 }, + { ID_SHOTGUN_AMMO1_ITEM, LaraWeaponType::Shotgun, WeaponAmmoType::Ammo1, 6 }, + { ID_SHOTGUN_AMMO2_ITEM, LaraWeaponType::Shotgun, WeaponAmmoType::Ammo2, 6 }, { ID_CROSSBOW_AMMO1_ITEM, LaraWeaponType::Crossbow, WeaponAmmoType::Ammo1, 10 }, { ID_CROSSBOW_AMMO2_ITEM, LaraWeaponType::Crossbow, WeaponAmmoType::Ammo2, 10 }, { ID_CROSSBOW_AMMO3_ITEM, LaraWeaponType::Crossbow, WeaponAmmoType::Ammo3, 10 }, @@ -50,7 +50,6 @@ bool TryModifyingAmmo(LaraInfo& lara, GAME_OBJECT_ID objectID, std::optional count) { // If nil is passed in, then the amount added will be the default amount // for that pickup - i.e. the amount you would get from picking up the // item in-game (e.g. 1 for medipacks, 12 for flares). - //can't use value_or(std::nullopt) here because nullopt isn't an int + // can't use value_or(std::nullopt) here because nullopt isn't an int if (count.has_value()) PickedUpObject(slot.m_pair.first, count.value()); else PickedUpObject(slot.m_pair.first, std::nullopt); } + ///Remove x of a certain item from the inventory. + //As in @{GiveItem}, omitting the count will remove the "default" amount of that item. + //Has no effect if the player has an infinite number of the item. + //@function TakeItem + //@tparam InvID item the item to be removed + //@int[opt] count the number of items to remove (default: the amount you would get from a pickup) static void InventoryRemove(ItemEnumPair slot, sol::optional count) { //can't use value_or(std::nullopt) here because nullopt isn't an int @@ -36,11 +50,20 @@ namespace InventoryHandler RemoveObjectFromInventory(slot.m_pair.first, std::nullopt); } + ///Set the amount of a certain item the player has in the inventory. + //Similar to @{GiveItem} but replaces with the new amount instead of adding it. + //@function SetItemCount + //@tparam InvID item the ID of the item to be set. + //@tparam int count the number of items the player will have. A value of -1 will give an infinite amount of that item. static int InventoryGetCount(ItemEnumPair slot) { return GetInventoryCount(slot.m_pair.first); } + ///Get the amount the player holds of an item. + //@function GetItemCount + //@tparam InvID item the ID item to check + //@treturn int the amount of the item the player has in the inventory. -1 indicates an infinite amount of that item. static void InventorySetCount(ItemEnumPair slot, int count) { SetInventoryCount(slot.m_pair.first, count); @@ -61,37 +84,9 @@ namespace InventoryHandler sol::table table_inventory{ state->lua_state(), sol::create }; parent.set(ScriptReserved_Inventory, table_inventory); - ///Add x of an item to the inventory. - //A count of 0 will add the "default" amount of that item - //(i.e. the amount the player would get from a pickup of that type). - //For example, giving "zero" crossbow ammo would give the player - //10 instead, whereas giving "zero" medkits would give the player 1 medkit. - //@function GiveItem - //@tparam InvID item the item to be added - //@tparam int count the number of items to add (default: 0) table_inventory.set_function(ScriptReserved_GiveInvItem, &InventoryAdd); - - - //Remove x of a certain item from the inventory. - //As in @{GiveItem}, a count of 0 will remove the "default" amount of that item. - //@function TakeItem - //@tparam InvID item the item to be removed - //@tparam int count the number of items to remove (default: 0) table_inventory.set_function(ScriptReserved_TakeInvItem, &InventoryRemove); - - - ///Get the amount the player holds of an item. - //@function GetItemCount - //@tparam InvID item the ID item to check - //@treturn int the amount of the item the player has in the inventory table_inventory.set_function(ScriptReserved_GetInvItemCount, &InventoryGetCount); - - - ///Set the amount of a certain item the player has in the inventory. - //Similar to @{GiveItem} but replaces with the new amount instead of adding it. - //@function SetItemCount - //@tparam @{InvID} item the ID of the item to be set - //@tparam int count the number of items the player will have table_inventory.set_function(ScriptReserved_SetInvItemCount, &InventorySetCount); } } From ec7ef1aa4aacacb9f742695d37fb51114b1c1719 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 24 Aug 2022 15:01:46 +0100 Subject: [PATCH 039/106] Update docs --- Documentation/doc/1 modules/Inventory.html | 105 ++++++++++++------ Documentation/doc/2 classes/Flow.Fog.html | 8 +- Documentation/doc/2 classes/Flow.Level.html | 8 +- .../doc/2 classes/Flow.Settings.html | 10 +- .../doc/2 classes/Flow.SkyLayer.html | 8 +- .../Scripting/Internal/TEN/Flow/Fog/Fog.cpp | 2 +- .../Internal/TEN/Flow/Level/FlowLevel.cpp | 2 +- .../Internal/TEN/Flow/Settings/Settings.cpp | 9 +- .../Internal/TEN/Flow/SkyLayer/SkyLayer.cpp | 2 +- 9 files changed, 95 insertions(+), 59 deletions(-) diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index 2b13b1af3..d1f5c39fe 100644 --- a/Documentation/doc/1 modules/Inventory.html +++ b/Documentation/doc/1 modules/Inventory.html @@ -96,17 +96,21 @@

Functions

Get a timer by its name.
UpdateAll(dt)Update all active timers.
myTimer:SetFunction(func[, ...]) Give the timer a new function and args
- + - - + + + + + +
GiveItem(item, count)GiveItem(item[, count]) Add x of an item to the inventory.
GetItemCount(item)Get the amount the player holds of an item.TakeItem(item[, count])Remove x of a certain item from the inventory.
SetItemCount(item, count) Set the amount of a certain item the player has in the inventory.
GetItemCount(item)Get the amount the player holds of an item.

@@ -118,14 +122,15 @@
- GiveItem(item, count) + GiveItem(item[, count])
Add x of an item to the inventory. -A count of 0 will add the "default" amount of that item +Omitting the second argument will give the "default" amount of the item (i.e. the amount the player would get from a pickup of that type). -For example, giving "zero" crossbow ammo would give the player -10 instead, whereas giving "zero" medkits would give the player 1 medkit. +For example, giving crossbow ammo without specifying the number would give the player +10 instead. +Has no effect if the player has an infinite number of that item.

Parameters:

@@ -136,7 +141,62 @@ For example, giving "zero" crossbow ammo would give the player
  • count int - the number of items to add (default: 0) + the number of items to add (default: the amount you would get from a pickup) + (optional) +
  • + + + + + + +
    +
    + + TakeItem(item[, count]) +
    +
    + Remove x of a certain item from the inventory. +As in GiveItem, omitting the count will remove the "default" amount of that item. +Has no effect if the player has an infinite number of the item. + + +

    Parameters:

    +
      +
    • item + InvID + the item to be removed +
    • +
    • count + int + the number of items to remove (default: the amount you would get from a pickup) + (optional) +
    • +
    + + + + + +
    +
    + + SetItemCount(item, count) +
    +
    + Set the amount of a certain item the player has in the inventory. +Similar to GiveItem but replaces with the new amount instead of adding it. + + +

    Parameters:

    +
      +
    • item + InvID + the ID of the item to be set. +
    • +
    • count + int + the number of items the player will have. A value of -1 will give an infinite amount of that item.
    @@ -165,37 +225,12 @@ For example, giving "zero" crossbow ammo would give the player
      int - the amount of the item the player has in the inventory + the amount of the item the player has in the inventory. -1 indicates an infinite amount of that item.
    -
    -
    - - SetItemCount(item, count) -
    -
    - Set the amount of a certain item the player has in the inventory. -Similar to GiveItem but replaces with the new amount instead of adding it. - - -

    Parameters:

    -
      -
    • item - the ID of the item to be set -
    • -
    • count - int - the number of items the player will have -
    • -
    - - - - -
    @@ -204,7 +239,7 @@ Similar to GiveItem but repla
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-08-24 15:00:16
    diff --git a/Documentation/doc/2 classes/Flow.Fog.html b/Documentation/doc/2 classes/Flow.Fog.html index 912f3ea19..f64efa973 100644 --- a/Documentation/doc/2 classes/Flow.Fog.html +++ b/Documentation/doc/2 classes/Flow.Fog.html @@ -112,7 +112,7 @@

    Functions

    - + @@ -185,8 +185,8 @@
    - - Fog.new(color, Min, Max) + + Fog(color, Min, Max)
    @@ -227,7 +227,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-08-24 15:00:16
    diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html index 4e29132bb..4a604d46c 100644 --- a/Documentation/doc/2 classes/Flow.Level.html +++ b/Documentation/doc/2 classes/Flow.Level.html @@ -170,7 +170,7 @@

    Functions

    Fog.new(color, Min, Max)Fog(color, Min, Max)
    - +
    Level.new()Level() Make a new Level object.
    @@ -471,8 +471,8 @@ Must be at least 4.

    - - Level.new() + + Level()
    Make a new Level object. @@ -496,7 +496,7 @@ Must be at least 4.

    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-08-24 15:00:16
    diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index 95edfc4f5..6214d9b3c 100644 --- a/Documentation/doc/2 classes/Flow.Settings.html +++ b/Documentation/doc/2 classes/Flow.Settings.html @@ -115,19 +115,19 @@
    How should the application respond to script errors? Must be one of the following: -ErrorMode.TERMINATE - print to the log file and terminate the application when any script error is hit. +ErrorMode.TERMINATE - print to the log file and return to the title level when any script error is hit. This is the one you will want to go for if you want to know IMMEDIATELY if something has gone wrong.

    ErrorMode.WARN - print to the log file and continue running the application when a recoverable script error is hit. -Choose this one if terminating the application is too much for you. Note that unrecoverable errors will still terminate -the application.

    +Choose this one if booting to the title level is too much for you.

    ErrorMode.SILENT - do nothing when a recoverable script error is hit. Think very carefully before using this setting. These error modes are here to help you to keep your scripts working properly, but if you opt to ignore errors, you won't be alerted if you've misused a function or passed an invalid argument.

    -

    As with ErrorMode.WARN, unrecoverable errors will still terminate the application. +

    In all of these modes, an unrecoverable error will boot you to the title level. If the title level itself +has an unrecoverable error, the game will close. @@ -143,7 +143,7 @@ an invalid argument.

    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-08-24 15:00:16
    diff --git a/Documentation/doc/2 classes/Flow.SkyLayer.html b/Documentation/doc/2 classes/Flow.SkyLayer.html index 7fea04f07..bb74f9213 100644 --- a/Documentation/doc/2 classes/Flow.SkyLayer.html +++ b/Documentation/doc/2 classes/Flow.SkyLayer.html @@ -106,7 +106,7 @@

    Functions

    - + @@ -161,8 +161,8 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
    - - SkyLayer.new(color, speed) + + SkyLayer(color, speed)
    @@ -199,7 +199,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-08-24 15:00:16
    diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp index cae08ef39..cd6bbc0d2 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Fog/Fog.cpp @@ -40,7 +40,7 @@ void Fog::Register(sol::table & parent) @tparam int Min Distance fog starts (in Sectors) @tparam int Max Distance fog ends (in Sectors) @return A fog object. -@function Fog.new +@function Fog */ Fog::Fog(ScriptColor const& col, short minDistance, short maxDistance) { diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp index a3b8e0a47..9bbcdbf4a 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Level/FlowLevel.cpp @@ -11,7 +11,7 @@ These are things things which aren't present in the compiled level file itself. */ /*** Make a new Level object. - @function Level.new + @function Level @return a Level object */ void Level::Register(sol::table & parent) diff --git a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp index 269e554a0..bcb0e5de2 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/Settings/Settings.cpp @@ -15,19 +15,20 @@ void Settings::Register(sol::table & parent) /*** How should the application respond to script errors? Must be one of the following: -`ErrorMode.TERMINATE` - print to the log file and terminate the application when any script error is hit. +`ErrorMode.TERMINATE` - print to the log file and return to the title level when any script error is hit. This is the one you will want to go for if you want to know IMMEDIATELY if something has gone wrong. `ErrorMode.WARN` - print to the log file and continue running the application when a recoverable script error is hit. -Choose this one if terminating the application is too much for you. Note that unrecoverable errors will still terminate -the application. +Choose this one if booting to the title level is too much for you. `ErrorMode.SILENT` - do nothing when a recoverable script error is hit. Think __very__ carefully before using this setting. These error modes are here to help you to keep your scripts working properly, but if you opt to ignore errors, you won't be alerted if you've misused a function or passed an invalid argument. -As with `ErrorMode.WARN`, unrecoverable errors will still terminate the application. +In all of these modes, an *unrecoverable* error will boot you to the title level. If the title level itself +has an unrecoverable error, the game will close. + @mem errorMode */ "errorMode", &Settings::ErrorMode diff --git a/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp b/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp index a46442134..3bc4271ee 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/SkyLayer/SkyLayer.cpp @@ -37,7 +37,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16. @tparam Color color RGB color @tparam int speed cloud speed @return A SkyLayer object. -@function SkyLayer.new +@function SkyLayer */ SkyLayer::SkyLayer(ScriptColor const& col, short speed) { From b0ed147c936686f7c333a07f986f40c12fcb36f2 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 24 Aug 2022 23:23:57 +0100 Subject: [PATCH 040/106] Fix #700 --- TombEngine/Game/gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Game/gui.cpp b/TombEngine/Game/gui.cpp index 7eaa1bd2b..f5f0ec7a2 100644 --- a/TombEngine/Game/gui.cpp +++ b/TombEngine/Game/gui.cpp @@ -1495,7 +1495,7 @@ void GuiController::SetupAmmoSelector() { num++; ammo_object_list[0].invitem = INV_OBJECT_PISTOLS_AMMO; - ammo_object_list[0].amount = -1; + ammo_object_list[0].amount = AmountPistolsAmmo; num_ammo_slots = num; current_ammo_type = &CurrentPistolsAmmoType; } From 0a630c8e52fda772b4397a401c71813ce8b8fde6 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 24 Aug 2022 23:30:23 +0100 Subject: [PATCH 041/106] Remove New to finally hopefully kill the new/New discourse (the correct way is to use neither) --- .../Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp | 1 - .../Internal/TEN/Strings/DisplayString/DisplayString.cpp | 1 - 2 files changed, 2 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 8edc6cb58..365f1e466 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -132,7 +132,6 @@ static std::unique_ptr Create( void Moveable::Register(sol::table & parent) { parent.new_usertype(LUA_CLASS_NAME, - ScriptReserved_New, Create, sol::call_constructor, Create, sol::meta_function::index, index_error, sol::meta_function::new_index, newindex_error, diff --git a/TombEngine/Scripting/Internal/TEN/Strings/DisplayString/DisplayString.cpp b/TombEngine/Scripting/Internal/TEN/Strings/DisplayString/DisplayString.cpp index 1b0cc600a..7da684e54 100644 --- a/TombEngine/Scripting/Internal/TEN/Strings/DisplayString/DisplayString.cpp +++ b/TombEngine/Scripting/Internal/TEN/Strings/DisplayString/DisplayString.cpp @@ -93,7 +93,6 @@ void DisplayString::Register(sol::table & parent) { parent.new_usertype( ScriptReserved_DisplayString, - ScriptReserved_New, &CreateString, sol::call_constructor, &CreateString, /// Get the display string's color From e7a1a06cd6c5f9eae855ae7dc8240cd1c2f620d4 Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 25 Aug 2022 00:07:48 +0100 Subject: [PATCH 042/106] Add Lua changes to Changex.txt. --- Documentation/Changes.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index 2e7d80d69..6817f5cf4 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -1,3 +1,12 @@ +Version 1.0.2 +============= + +- EventSequence and Timer no longer require you to call Timer.UpdateAll in OnControlPhase. +- TEN.Logic.AddCallback and TEN.Logic.RemoveCallback have been added. +- GiveItem, TakeItem, and SetItemCount have been reworked (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables). +- Removing Pistols with TakeItem and SetItemCount now works correctly. +- Vec3s can now be saved and loaded in LevelVars and GameVars. + Version 1.0.1 ============= From 5fd30e05a162bc03802e80c0452df22d114fef0e Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 25 Aug 2022 00:07:48 +0100 Subject: [PATCH 043/106] Add Lua changes to Changes.txt. --- Documentation/Changes.txt | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index 2e7d80d69..6817f5cf4 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -1,3 +1,12 @@ +Version 1.0.2 +============= + +- EventSequence and Timer no longer require you to call Timer.UpdateAll in OnControlPhase. +- TEN.Logic.AddCallback and TEN.Logic.RemoveCallback have been added. +- GiveItem, TakeItem, and SetItemCount have been reworked (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables). +- Removing Pistols with TakeItem and SetItemCount now works correctly. +- Vec3s can now be saved and loaded in LevelVars and GameVars. + Version 1.0.1 ============= From b9a0e692af37bf73654b74df284de2c50925d01f Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 25 Aug 2022 21:28:59 +0100 Subject: [PATCH 044/106] Part 1 of hopefully fixing #671. --- TombEngine/Game/items.cpp | 5 ++++- TombEngine/Game/items.h | 1 + .../Internal/TEN/Objects/Moveable/MoveableObject.cpp | 4 ++++ TombEngine/Specific/level.cpp | 1 + 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp index 2d3a5bb19..6a2e9a1bc 100644 --- a/TombEngine/Game/items.cpp +++ b/TombEngine/Game/items.cpp @@ -447,6 +447,8 @@ void InitialiseItem(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; + item->VectorIndex = itemNumber; + item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; @@ -552,6 +554,7 @@ void InitialiseItemArray(int totalItem) { for(int i = g_Level.NumItems + 1; i < totalItem; i++, item++) { + item->VectorIndex = i-1; item->NextItem = i; item->Active = false; item->Data = nullptr; @@ -616,7 +619,7 @@ void UpdateItemRoom(ItemInfo* item, int height, int xOffset, int zOffset) item->Floor = GetFloorHeight(item->Location, x, z).value_or(NO_HEIGHT); if (item->RoomNumber != item->Location.roomNumber) - ItemNewRoom(FindItem(item), item->Location.roomNumber); + ItemNewRoom(item->VectorIndex, item->Location.roomNumber); } std::vector FindAllItems(short objectNumber) diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h index c923a7e1e..79b43c4d3 100644 --- a/TombEngine/Game/items.h +++ b/TombEngine/Game/items.h @@ -69,6 +69,7 @@ struct EntityAnimationData //todo we need to find good "default states" for a lot of these - squidshire 25/05/2022 struct ItemInfo { + short VectorIndex = -1; GAME_OBJECT_ID ObjectNumber; int Status; // ItemStatus enum. bool Active; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 365f1e466..50184f6d5 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -562,6 +562,10 @@ Vec3 Moveable::GetPos() const void Moveable::SetPos(Vec3 const& pos) { pos.StoreInPHDPos(m_item->Pose); + + //todo make a non-updating version + if(m_initialised) + UpdateItemRoom(m_item, pos.y); } Vec3 Moveable::GetJointPos(int jointIndex) const diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 4a5bc417a..afa0953eb 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -172,6 +172,7 @@ void LoadItems() { ItemInfo* item = &g_Level.Items[i]; + item->VectorIndex = i; item->Data = ITEM_DATA{}; item->ObjectNumber = from_underlying(ReadInt16()); item->RoomNumber = ReadInt16(); From dad4ac26f942e4c635ab412e97e4a6d30abe8a70 Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 25 Aug 2022 22:52:54 +0100 Subject: [PATCH 045/106] Part 2 of fixing #671 --- TombEngine/Game/items.cpp | 1 - .../TEN/Objects/Moveable/MoveableObject.cpp | 59 +++++++++++-------- .../TEN/Objects/Moveable/MoveableObject.h | 2 +- 3 files changed, 34 insertions(+), 28 deletions(-) diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp index 6a2e9a1bc..fa64a1522 100644 --- a/TombEngine/Game/items.cpp +++ b/TombEngine/Game/items.cpp @@ -605,7 +605,6 @@ int GlobalItemReplace(short search, GAME_OBJECT_ID replace) } // Offset values may be used to account for the quirk of room traversal only being able to occur at portals. -// Note: may not work for dynamic items because of FindItem. void UpdateItemRoom(ItemInfo* item, int height, int xOffset, int zOffset) { float sinY = phd_sin(item->Pose.Orientation.y); diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 50184f6d5..43b9c6e6d 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -94,7 +94,7 @@ static std::unique_ptr Create( std::string const & name, Vec3 const & pos, TypeOrNil const & rot, - short room, + TypeOrNil room, TypeOrNil animNumber, TypeOrNil frameNumber, TypeOrNil hp, @@ -108,9 +108,15 @@ 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]; - ptr->SetPos(pos); + if (std::holds_alternative(room)) + { + ptr->SetPos(pos, false); + ptr->SetRoom(std::get(room)); + } + else + ptr->SetPos(pos, true); + ptr->SetRot(USE_IF_HAVE(Rotation, rot, Rotation{})); - ptr->SetRoom(room); ptr->SetObjectID(objID); ptr->Init(); @@ -378,24 +384,10 @@ void Moveable::Register(sol::table & parent) // @treturn bool true if the moveable is active ScriptReserved_GetActive, &Moveable::GetActive, -/// Get the current room of the object -// @function Moveable:GetRoom -// @treturn int number representing the current room of the object ScriptReserved_GetRoom, &Moveable::GetRoom, -/// Set room of object -// This is used in conjunction with SetPosition to teleport an item to a new room. -// @function Moveable:SetRoom -// @tparam int ID the ID of the new room -// @usage -// local sas = TEN.Objects.GetMoveableByName("sas_enemy") -// sas:SetRoom(destinationRoom) -// sas:SetPosition(destinationPosition) ScriptReserved_SetRoom, &Moveable::SetRoom, -/// Get the object's position -// @function Moveable:GetPosition -// @treturn Vec3 a copy of the moveable's position ScriptReserved_GetPosition, & Moveable::GetPos, /// Get the object's joint position @@ -403,12 +395,6 @@ void Moveable::Register(sol::table & parent) // @treturn Vec3 a copy of the moveable's position ScriptReserved_GetJointPosition, & Moveable::GetJointPos, -/// Set the moveable's position -// If you are moving a moveable whose behaviour involves knowledge of room geometry, -// (e.g. a BADDY1, which uses it for pathfinding), then you *must* use this in conjunction -// with @{Moveable:SetRoom}. Otherwise, said moveable will not behave correctly. -// @function Moveable:SetPosition -// @tparam Vec3 position the new position of the moveable ScriptReserved_SetPosition, & Moveable::SetPos, /// Get the moveable's rotation @@ -554,17 +540,27 @@ bool Moveable::SetName(std::string const & id) return true; } +/// Get the object's position +// @function Moveable:GetPosition +// @treturn Vec3 a copy of the moveable's position Vec3 Moveable::GetPos() const { return Vec3(m_item->Pose); } -void Moveable::SetPos(Vec3 const& pos) +/// Set the moveable's position +// If you are moving a moveable whose behaviour involves knowledge of room geometry, +// (e.g. a BADDY1, which uses it for pathfinding), then the second argument should +// be true (or omitted, as true is the default). Otherwise, said moveable will not behave correctly. +// @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) { pos.StoreInPHDPos(m_item->Pose); - //todo make a non-updating version - if(m_initialised) + bool willUpdate = !updateRoom.has_value() || updateRoom.value(); + if(m_initialised && willUpdate) UpdateItemRoom(m_item, pos.y); } @@ -722,11 +718,22 @@ bool Moveable::GetHitStatus() const return m_item->HitStatus; } +/// Get the current room of the object +// @function Moveable:GetRoom +// @treturn int number representing the current room of the object short Moveable::GetRoom() const { return m_item->RoomNumber; } +/// Set room of object +// Use this if you are not using SetPosition's automatic room update - for example, when dealing with overlapping rooms. +// @function Moveable:SetRoom +// @tparam int ID the ID of the new room +// @usage +// local sas = TEN.Objects.GetMoveableByName("sas_enemy") +// sas:SetRoom(destinationRoom) +// sas:SetPosition(destinationPosition, false) void Moveable::SetRoom(short room) { const size_t nRooms = g_Level.Rooms.size(); diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h index 96225563e..a47a1cc81 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h @@ -42,7 +42,7 @@ public: [[nodiscard]] Vec3 GetPos() const; [[nodiscard]] Vec3 GetJointPos(int index) const; - void SetPos(Vec3 const& pos); + void SetPos(Vec3 const& pos, sol::optional updateRoom); [[nodiscard]] Rotation GetRot() const; void SetRot(Rotation const& rot); From e6319ee18a12910d37b870653330471e33424b11 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 26 Aug 2022 00:13:02 +0100 Subject: [PATCH 046/106] Update docs --- .../doc/2 classes/Objects.Moveable.html | 254 +++++++++--------- .../TEN/Objects/Moveable/MoveableObject.cpp | 18 +- 2 files changed, 140 insertions(+), 132 deletions(-) diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index d89f7958c..a945e9401 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -95,7 +95,7 @@ pickups, and Lara herself.

    Functions

    SkyLayer.new(color, speed)SkyLayer(color, speed)
    - + @@ -270,27 +270,8 @@ associated getters and setters. - - - - - - - - - - - - - - - - @@ -318,6 +299,25 @@ associated getters and setters. + + + + + + + + + + + + + + + +
    Moveable(object, name, position, rotation, room, animNumber, frameNumber, hp, OCB, AIBits)Moveable(object, name, position[, rotation[, room[, animNumber=0[, frameNumber=0[, hp=10[, OCB=0[, AIBits]]]]]]]) For more information on each parameter, see the associated getters and setters.
    Determine whether the moveable is active or not
    Moveable:GetRoom()Get the current room of the object
    Moveable:SetRoom(ID)Set room of object - This is used in conjunction with SetPosition to teleport an item to a new room.
    Moveable:GetPosition()Get the object's position
    Moveable:GetJointPosition() Get the object's joint position
    Moveable:SetPosition(position)Set the moveable's position - If you are moving a moveable whose behaviour involves knowledge of room geometry, - (e.g.
    Moveable:GetRotation() Moveable:Destroy() Destroy the moveable.
    Moveable:GetPosition()Get the object's position
    Moveable:SetPosition(position[, updateRoom])Set the moveable's position + If you are moving a moveable whose behaviour involves knowledge of room geometry, + (e.g.
    Moveable:GetRoom()Get the current room of the object
    Moveable:SetRoom(ID)Set room of object + Use this if you are not using SetPosition's automatic room update - for example, when dealing with overlapping rooms.

    @@ -329,7 +329,7 @@ associated getters and setters.
    - Moveable(object, name, position, rotation, room, animNumber, frameNumber, hp, OCB, AIBits) + Moveable(object, name, position[, rotation[, room[, animNumber=0[, frameNumber=0[, hp=10[, OCB=0[, AIBits]]]]]]])
    For more information on each parameter, see the @@ -354,30 +354,37 @@ most can just be ignored (see usage).
  • rotation Rotation rotation about x, y, and z axes (default Rotation(0, 0, 0)) + (optional)
  • room int - room ID item is in + room ID item is in (default: calculated automatically) + (optional)
  • animNumber int - anim number (default 0) + anim number + (default 0)
  • frameNumber int - frame number (default 0) + frame number + (default 0)
  • hp int - HP of item (default 10) + HP of item + (default 10)
  • OCB int ocb of item (default 0) + (default 0)
  • AIBits table table with AI bits (default {0,0,0,0,0,0}) + (optional)
  • @@ -394,10 +401,8 @@ most can just be ignored (see usage).
    local item = Moveable(
     	TEN.ObjID.PISTOLS_ITEM, -- object id
     	"test", -- name
    -	Vec3(18907, 0, 21201),
    -	Rotation(0,0,0),
    -	0, -- room
    -	)
    + Vec3(18907, 0, 21201) + )
    @@ -1242,74 +1247,6 @@ sas:SetAIBits({1, 0, -
    - - Moveable:GetRoom() -
    -
    - Get the current room of the object - - - -

    Returns:

    -
      - - int - number representing the current room of the object -
    - - - - -
    -
    - - Moveable:SetRoom(ID) -
    -
    - Set room of object - This is used in conjunction with SetPosition to teleport an item to a new room. - - -

    Parameters:

    -
      -
    • ID - int - the ID of the new room -
    • -
    - - - - -

    Usage:

    -
      -
      local sas = TEN.Objects.GetMoveableByName("sas_enemy")
      -sas:SetRoom(destinationRoom)
      -sas:SetPosition(destinationPosition)
      -
    - -
    -
    - - Moveable:GetPosition() -
    -
    - Get the object's position - - - -

    Returns:

    -
      - - Vec3 - a copy of the moveable's position -
    - - - -
    @@ -1330,30 +1267,6 @@ sas:SetPosition(destinationPosition) -
    -
    - - Moveable:SetPosition(position) -
    -
    - Set the moveable's position - If you are moving a moveable whose behaviour involves knowledge of room geometry, - (e.g. a BADDY1, which uses it for pathfinding), then you must use this in conjunction - with Moveable:SetRoom. Otherwise, said moveable will not behave correctly. - - -

    Parameters:

    -
      -
    • position - Vec3 - the new position of the moveable -
    • -
    - - - - -
    @@ -1480,6 +1393,103 @@ sas:SetPosition(destinationPosition) + +
    + + Moveable:GetPosition() +
    +
    + Get the object's position + + + +

    Returns:

    +
      + + Vec3 + a copy of the moveable's position +
    + + + + +
    +
    + + Moveable:SetPosition(position[, updateRoom]) +
    +
    + Set the moveable's position + If you are moving a moveable whose behaviour involves knowledge of room geometry, + (e.g. a BADDY1, which uses it for pathfinding), then the second argument should + be true (or omitted, as true is the default). Otherwise, said moveable will not behave correctly. + + +

    Parameters:

    +
      +
    • position + Vec3 + the new position of the moveable +
    • +
    • updateRoom + bool + Will room changes be automatically detected? Set to false if you are using overlapping rooms (default: true) + (optional) +
    • +
    + + + + + +
    +
    + + Moveable:GetRoom() +
    +
    + Get the current room of the object + + + +

    Returns:

    +
      + + int + number representing the current room of the object +
    + + + + +
    +
    + + Moveable:SetRoom(ID) +
    +
    + Set room of object + Use this if you are not using SetPosition's automatic room update - for example, when dealing with overlapping rooms. + + +

    Parameters:

    +
      +
    • ID + int + the ID of the new room +
    • +
    + + + + +

    Usage:

    +
      +
      local sas = TEN.Objects.GetMoveableByName("sas_enemy")
      +sas:SetRoom(destinationRoom)
      +sas:SetPosition(destinationPosition, false)
      +
    +
    @@ -1488,7 +1498,7 @@ sas:SetPosition(destinationPosition)
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-08-26 00:12:28
    diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 43b9c6e6d..aff367fc0 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -72,21 +72,19 @@ most can just be ignored (see usage). @tparam ObjID object ID @tparam string name Lua name of the item @tparam Vec3 position position in level - @tparam Rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0)) - @tparam int room room ID item is in - @tparam int animNumber anim number (default 0) - @tparam int frameNumber frame number (default 0) - @tparam int hp HP of item (default 10) - @tparam int OCB ocb of item (default 0) - @tparam table AIBits table with AI bits (default {0,0,0,0,0,0}) + @tparam[opt] Rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0)) + @int[opt] room room ID item is in (default: calculated automatically) + @int[opt=0] animNumber anim number + @int[opt=0] frameNumber frame number + @int[opt=10] hp HP of item + @int[opt=0] OCB ocb of item (default 0) + @tparam[opt] table AIBits table with AI bits (default {0,0,0,0,0,0}) @return reference to new Moveable object @usage local item = Moveable( TEN.ObjID.PISTOLS_ITEM, -- object id "test", -- name - Vec3(18907, 0, 21201), - Rotation(0,0,0), - 0, -- room + Vec3(18907, 0, 21201) ) */ static std::unique_ptr Create( From 08535c08a7c0c786f5665a99fbf8ad333edf2c55 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sat, 27 Aug 2022 14:31:03 +1000 Subject: [PATCH 047/106] Light cleanup --- .../Objects/TR4/Entity/tr4_crocodile.cpp | 20 ++--- .../Objects/TR4/Entity/tr4_skeleton.cpp | 88 +++++++------------ .../Objects/TR5/Entity/tr5_gladiator.cpp | 26 +++--- TombEngine/Objects/TR5/Entity/tr5_lion.cpp | 2 +- 4 files changed, 55 insertions(+), 81 deletions(-) diff --git a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp index d8c267c31..d71ffe5f2 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp @@ -30,9 +30,9 @@ namespace TEN::Entities::TR4 constexpr auto CROC_SWIM_SPEED = 16; - #define CROC_STATE_WALK_FORWARD_ANGLE ANGLE(3.0f) - #define CROC_SWIM_ANGLE ANGLE(3.0f) - #define CROC_STATE_RUN_FORWARD_ANGLE ANGLE(5.0f) + #define CROC_STATE_WALK_TURN_RATE_MAX ANGLE(3.0f) + #define CROC_STATE_RUN_TURN_RATE_MAX ANGLE(5.0f) + #define CROC_STATE_SWIM_TURN_RATE_MAX ANGLE(3.0f) const auto CrocodileBite = BiteInfo(Vector3(0.0f, -100.0f, 500.0f), 9); const vector CrocodileBiteAttackJoints = { 8, 9 }; @@ -49,7 +49,7 @@ namespace TEN::Entities::TR4 CROC_STATE_DEATH = 7, CROC_STATE_SWIM_FORWARD = 8, CROC_STATE_WATER_BITE_ATTACK = 9, - CROC_STATE_WATER_DEATH = 10, + CROC_STATE_WATER_DEATH = 10 }; enum CrocodileAnim @@ -118,12 +118,12 @@ namespace TEN::Entities::TR4 return; auto* item = &g_Level.Items[itemNumber]; - auto* creature = GetCreatureInfo(item); auto* object = &Objects[item->ObjectNumber]; + auto* creature = GetCreatureInfo(item); - AI_INFO AI; short angle = 0; short boneAngle = 0; + AI_INFO AI; if (item->HitPoints <= 0) { @@ -202,7 +202,7 @@ namespace TEN::Entities::TR4 break; case CROC_STATE_WALK_FORWARD: - creature->MaxTurn = CROC_STATE_WALK_FORWARD_ANGLE; + creature->MaxTurn = CROC_STATE_WALK_TURN_RATE_MAX; // Land to water transition. if (IsCrocodileInWater(item) && !item->Animation.RequiredState) @@ -221,7 +221,7 @@ namespace TEN::Entities::TR4 break; case CROC_STATE_RUN_FORWARD: - creature->MaxTurn = CROC_STATE_RUN_FORWARD_ANGLE; + creature->MaxTurn = CROC_STATE_RUN_TURN_RATE_MAX; // Land to water transition. if (IsCrocodileInWater(item)) @@ -242,7 +242,7 @@ namespace TEN::Entities::TR4 case CROC_STATE_BITE_ATTACK: if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase) - item->Animation.RequiredState = 0; + item->Animation.RequiredState = CROC_STATE_NONE_1; if (AI.bite && item->TestBits(JointBitType::Touch, CrocodileBiteAttackJoints)) @@ -260,7 +260,7 @@ namespace TEN::Entities::TR4 break; case CROC_STATE_SWIM_FORWARD: - creature->MaxTurn = CROC_SWIM_ANGLE; + creature->MaxTurn = CROC_STATE_SWIM_TURN_RATE_MAX; // Water to land transition. if (!IsCrocodileInWater(item)) diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp index 5f3e68d0c..15c8a16db 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp @@ -29,6 +29,7 @@ namespace TEN::Entities::TR4 const auto SkeletonBite = BiteInfo(Vector3(0.0f, -16.0f, 200.0f), 11); const vector SkeletonSwordAttackJoints = { 15, 16 }; + // TODO: Fill in missign states. enum SkeletonState { SKELETON_STATE_SUBTERRANEAN = 0, @@ -72,36 +73,28 @@ namespace TEN::Entities::TR4 void InitialiseSkeleton(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; - auto* object = &Objects[item->ObjectNumber]; ClearItem(itemNumber); + // TODO: Check cases 0 and 3. switch (item->TriggerFlags) { case 0: - item->Animation.AnimNumber = object->animIndex; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + SetAnimation(item, SKELETON_ANIM_EMERGE); item->Animation.ActiveState = SKELETON_STATE_SUBTERRANEAN; item->Animation.TargetState = SKELETON_STATE_SUBTERRANEAN; break; case 1: - item->Animation.AnimNumber = object->animIndex + SKELETON_ANIM_JUMP_RIGHT_START; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = SKELETON_STATE_JUMP_RIGHT; - item->Animation.TargetState = SKELETON_STATE_JUMP_RIGHT; + SetAnimation(item, SKELETON_ANIM_JUMP_RIGHT_START); break; case 2: - item->Animation.AnimNumber = object->animIndex + SKELETON_ANIM_JUMP_LEFT_START; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = SKELETON_STATE_JUMP_LEFT; - item->Animation.TargetState = SKELETON_STATE_JUMP_LEFT; + SetAnimation(item, SKELETON_ANIM_JUMP_LEFT_START); break; case 3: - item->Animation.AnimNumber = object->animIndex; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; + SetAnimation(item, SKELETON_ANIM_EMERGE); item->Animation.ActiveState = SKELETON_STATE_JUMP_LIE_DOWN; item->Animation.TargetState = SKELETON_STATE_JUMP_LIE_DOWN; //item->status = ITEM_DEACTIVATED; @@ -175,15 +168,15 @@ namespace TEN::Entities::TR4 bool jumpLeft = false; bool jumpRight = false; - int distance = 0; - short tilt = 0; short angle = 0; + short tilt = 0; short joint1 = 0; short joint2 = 0; short joint3 = 0; short rotation = 0; + int distance = 0; - // Can skeleton jump? Check for a distance of 1 and 2 sectors. + // Can skeleton jump? Check for a distance of 1 and 2 blocks. int x = item->Pose.Position.x; int y = item->Pose.Position.y; int z = item->Pose.Position.z; @@ -204,24 +197,24 @@ namespace TEN::Entities::TR4 int height3 = GetCollision(x, y, z, item->RoomNumber).Position.Floor; int height = 0; - bool canJump1sector = true; - if (enemyItem && item->BoxNumber == LaraItem->BoxNumber && item->MeshBits & 0x200 || - y >= height1 - CLICK(1.5f) || - y >= height2 + CLICK(2) || - y <= height2 - CLICK(2)) + bool canJump1Block = true; + if (enemyItem && item->BoxNumber == LaraItem->BoxNumber && (item->MeshBits & 0x200) || + y >= (height1 - CLICK(1.5f)) || + y >= (height2 + CLICK(2)) || + y <= (height2 - CLICK(2))) { height = height2; - canJump1sector = false; + canJump1Block = false; } - bool canJump2sectors = true; - if (enemyItem && item->BoxNumber == LaraItem->BoxNumber && item->MeshBits & 0x200 || - y >= height1 - CLICK(1.5f) || - y >= height - CLICK(1.5f) || - y >= height3 + CLICK(2) || - y <= height3 - CLICK(2)) + bool canJump2Blocks = true; + if (enemyItem && item->BoxNumber == LaraItem->BoxNumber && (item->MeshBits & 0x200) || + y >= (height1 - CLICK(1.5f)) || + y >= (height - CLICK(1.5f)) || + y >= (height3 + CLICK(2)) || + y <= (height3 - CLICK(2))) { - canJump2sectors = false; + canJump2Blocks = false; } if (item->AIBits) @@ -235,17 +228,17 @@ namespace TEN::Entities::TR4 if (item->HitStatus && Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun && AI.distance < pow(SECTOR(3.5f), 2) && - item->Animation.ActiveState != 7 && + item->Animation.ActiveState != SKELETON_STATE_USE_SHIELD && item->Animation.ActiveState != 17 && item->Animation.ActiveState != SKELETON_STATE_HURT_BY_SHOTGUN_1 && item->Animation.ActiveState != SKELETON_STATE_HURT_BY_SHOTGUN_2 && - item->Animation.ActiveState != 25) + item->Animation.ActiveState != SKELETON_STATE_JUMP_LIE_DOWN) { if (AI.angle >= ANGLE(67.5f) || AI.angle <= -ANGLE(67.5f)) { item->Animation.ActiveState = SKELETON_STATE_HURT_BY_SHOTGUN_2; item->Animation.AnimNumber = Objects[ID_SKELETON].animIndex + 33; - item->Pose.Orientation.y += AI.angle + -32768; + item->Pose.Orientation.y += AI.angle - ANGLE(180.0f); } else { @@ -381,14 +374,14 @@ namespace TEN::Entities::TR4 { if (item->AIBits & PATROL1) item->Animation.TargetState = 15; - else if (canJump1sector || canJump2sectors) + else if (canJump1Block || canJump2Blocks) { item->Animation.AnimNumber = Objects[ID_SKELETON].animIndex + 40; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; item->Animation.ActiveState = SKELETON_STATE_JUMP_LEFT; creature->MaxTurn = 0; - if (!canJump2sectors) + if (!canJump2Blocks) { item->Animation.TargetState = SKELETON_STATE_JUMP_FORWARD_1_BLOCK; creature->LOT.IsJumping = true; @@ -400,26 +393,15 @@ namespace TEN::Entities::TR4 } } else if (jumpLeft) - { - item->Animation.AnimNumber = Objects[ID_SKELETON].animIndex + 34; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = SKELETON_STATE_JUMP_LEFT; - item->Animation.TargetState = SKELETON_STATE_JUMP_LEFT; - } + SetAnimation(item, SKELETON_ANIM_JUMP_LEFT_START); else if (jumpRight) - { - item->Animation.AnimNumber = Objects[ID_SKELETON].animIndex + 37; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = SKELETON_STATE_JUMP_RIGHT; - item->Animation.TargetState = SKELETON_STATE_JUMP_RIGHT; - } + SetAnimation(item, SKELETON_ANIM_JUMP_RIGHT_START); else { if (creature->Mood == MoodType::Escape) { if (Lara.TargetEntity == item || - !AI.ahead || - item->HitStatus || + !AI.ahead || item->HitStatus || !(item->MeshBits & 0x200)) { item->Animation.TargetState = 15; @@ -430,8 +412,7 @@ namespace TEN::Entities::TR4 } else if (creature->Mood == MoodType::Bored || item->AIBits & FOLLOW && - (creature->ReachedGoal || - laraAI.distance > pow(SECTOR(2), 2))) + (creature->ReachedGoal || laraAI.distance > pow(SECTOR(2), 2))) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; @@ -439,8 +420,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = 15; } else if (Lara.TargetEntity == item && - laraAI.angle && - laraAI.distance < pow(SECTOR(2), 2) && + laraAI.angle && laraAI.distance < pow(SECTOR(2), 2) && TestProbability(0.5f) && (Lara.Control.Weapon.GunType == LaraWeaponType::Shotgun || TestProbability(0.06f)) && item->MeshBits == -1) @@ -509,7 +489,7 @@ namespace TEN::Entities::TR4 { if (AI.bite && AI.distance < pow(SECTOR(1), 2)) item->Animation.TargetState = 18; - else if (canJump1sector || canJump2sectors) + else if (canJump1Block || canJump2Blocks) { item->Animation.TargetState = 2; creature->MaxTurn = 0; @@ -530,7 +510,7 @@ namespace TEN::Entities::TR4 creature->MaxTurn = ANGLE(7.0f); creature->LOT.IsJumping = false; - if (item->AIBits & GUARD || canJump1sector || canJump2sectors) + if (item->AIBits & GUARD || canJump1Block || canJump2Blocks) { if (item->MeshBits & 0x200) { diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index 8434d8639..2bb89c123 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -88,8 +88,8 @@ namespace TEN::Entities::Creatures::TR5 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short tilt = 0; short angle = 0; + short tilt = 0; short joint0 = 0; short joint1 = 0; short joint2 = 0; @@ -99,11 +99,7 @@ namespace TEN::Entities::Creatures::TR5 item->HitPoints = 0; if (item->Animation.ActiveState != GLADIATOR_STATE_DEATH) - { - item->Animation.AnimNumber = Objects[ID_GLADIATOR].animIndex + GLADIATOR_ANIM_DEATH; - item->Animation.ActiveState = GLADIATOR_STATE_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - } + SetAnimation(item, GLADIATOR_ANIM_DEATH); } else { @@ -116,21 +112,21 @@ namespace TEN::Entities::Creatures::TR5 CreatureAIInfo(item, &AI); int unknown = true; - short rot; + short deltaAngle; int distance; if (creature->Enemy == LaraItem) { distance = AI.distance; - rot = AI.angle; + deltaAngle = AI.angle; } else { int dx = LaraItem->Pose.Position.x - item->Pose.Position.x; int dz = LaraItem->Pose.Position.z - item->Pose.Position.z; - rot = phd_atan(dz, dx) - item->Pose.Orientation.y; - if (rot <= -ANGLE(90.0f) || rot >= ANGLE(90.0f)) + deltaAngle = phd_atan(dz, dx) - item->Pose.Orientation.y; + if (deltaAngle <= -ANGLE(90.0f) || deltaAngle >= ANGLE(90.0f)) unknown = false; distance = pow(dx, 2) + pow(dz, 2); @@ -151,7 +147,7 @@ namespace TEN::Entities::Creatures::TR5 switch (item->Animation.ActiveState) { case GLADIATOR_STATE_IDLE: - joint2 = rot; + joint2 = deltaAngle; creature->MaxTurn = (-(int)(creature->Mood != MoodType::Bored)) & 0x16C; creature->Flags = 0; @@ -169,8 +165,7 @@ namespace TEN::Entities::Creatures::TR5 { if (creature->Mood == MoodType::Escape) { - if (Lara.TargetEntity != item && - AI.ahead && !item->HitStatus) + if (Lara.TargetEntity != item && AI.ahead && !item->HitStatus) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -179,8 +174,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(SECTOR(2), 2)))) { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; @@ -217,7 +211,7 @@ namespace TEN::Entities::Creatures::TR5 break; case GLADIATOR_STATE_WALK_FORWARD: - joint2 = rot; + joint2 = deltaAngle; creature->MaxTurn = creature->Mood != MoodType::Bored ? ANGLE(7.0f) : ANGLE(2.0f); creature->Flags = 0; diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp index 66fd9992e..f7dbe1196 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp @@ -23,9 +23,9 @@ namespace TEN::Entities::Creatures::TR5 constexpr auto LION_POUNCE_ATTACK_RANGE = SQUARE(SECTOR(1)); - const vector LionAttackJoints = { 3, 6, 21 }; const auto LionBite1 = BiteInfo(Vector3(2.0f, -10.0f, 250.0f), 21); const auto LionBite2 = BiteInfo(Vector3(-2.0f, -10.0f, 132.0f), 21); + const vector LionAttackJoints = { 3, 6, 21 }; enum LionState { From 680065ad0335b32429a5be5aaa21d46d6210312a Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 30 Aug 2022 15:20:44 +0100 Subject: [PATCH 048/106] Add hacky subtable fuckery --- TombEngine/Game/savegame.cpp | 15 ++ .../Scripting/Include/ScriptInterfaceGame.h | 7 +- TombEngine/Scripting/Internal/ScriptUtil.h | 6 +- .../Internal/TEN/Flow/FlowHandler.cpp | 2 + .../Internal/TEN/Logic/FuncNameHolder.h | 37 +++ .../Internal/TEN/Logic/LogicHandler.cpp | 251 ++++++++++++++++-- .../Internal/TEN/Logic/LogicHandler.h | 73 ++++- .../flatbuffers/ten_savegame_generated.h | 151 ++++++++++- .../Specific/savegame/schema/ten_savegame.fbs | 7 +- TombEngine/TombEngine.vcxproj | 1 + 10 files changed, 514 insertions(+), 36 deletions(-) create mode 100644 TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index 6ee4de384..9379db071 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -1082,6 +1082,16 @@ bool SaveGame::Save(int slot) putDataInVec(Save::VarUnion::tab, scriptTableOffset); } + else if (std::holds_alternative(s)) + { + std::string data = std::get(s).name; + auto strOffset = fbb.CreateString(data); + Save::funcNameTableBuilder ftb{ fbb }; + ftb.add_str(strOffset); + auto funcNameOffset = ftb.Finish(); + + putDataInVec(Save::VarUnion::funcName, funcNameOffset); + } else if (std::holds_alternative(s)) { Save::vec3TableBuilder vtb{ fbb }; @@ -1926,6 +1936,11 @@ bool SaveGame::Load(int slot) { loadedVars.push_back(ToVector3Int(var->u_as_vec3()->vec())); } + else if (var->u_type() == Save::VarUnion::funcName) + { + loadedVars.push_back(FuncName{var->u_as_funcName()->str()->str()}); + } + } } diff --git a/TombEngine/Scripting/Include/ScriptInterfaceGame.h b/TombEngine/Scripting/Include/ScriptInterfaceGame.h index 7c4c087a2..5181c8b32 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceGame.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceGame.h @@ -19,7 +19,12 @@ using VarSaveType = std::variant; using IndexTable = std::vector>; -using SavedVar = std::variant; +struct FuncName +{ + std::string name; +}; + +using SavedVar = std::variant; class ScriptInterfaceGame { public: diff --git a/TombEngine/Scripting/Internal/ScriptUtil.h b/TombEngine/Scripting/Internal/ScriptUtil.h index 49715c7f1..0700dfbeb 100644 --- a/TombEngine/Scripting/Internal/ScriptUtil.h +++ b/TombEngine/Scripting/Internal/ScriptUtil.h @@ -37,17 +37,19 @@ template using TypeOrNil = std::variant -void MakeSpecialTable(sol::state * state, std::string const & name, funcIndex const & fi, funcNewindex const & fni) +sol::table MakeSpecialTable(sol::state * state, std::string const & name, funcIndex const & fi, funcNewindex const & fni) { auto meta = MakeSpecialTableBase(state, name); meta.set_function("__index", fi); meta.set_function("__newindex", fni); + return (*state)[name]; } template -void MakeSpecialTable(sol::state * state, std::string const & name, funcIndex const & fi, funcNewindex const & fni, ObjPtr objPtr) +sol::table MakeSpecialTable(sol::state * state, std::string const & name, funcIndex const & fi, funcNewindex const & fni, ObjPtr objPtr) { auto meta = MakeSpecialTableBase(state, name); meta.set_function("__index", fi, objPtr); meta.set_function("__newindex", fni, objPtr); + return (*state)[name]; } diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index 9dd54070a..11c0978bc 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -8,6 +8,7 @@ #include "Flow/InventoryItem/InventoryItem.h" #include "InventorySlots.h" #include "Game/gui.h" +#include "Logic/FuncNameHolder.h" #include "Vec3/Vec3.h" #include "Objects/ScriptInterfaceObjectsHandler.h" #include "Specific/trutils.h" @@ -112,6 +113,7 @@ Specify which translations in the strings table correspond to which languages. Animations::Register(table_flow); Settings::Register(table_flow); Fog::Register(table_flow); + FuncNameHolder::Register(parent); m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_WeatherType, kWeatherTypes); m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_LaraType, kLaraTypes); diff --git a/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h b/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h new file mode 100644 index 000000000..f89a95759 --- /dev/null +++ b/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h @@ -0,0 +1,37 @@ +#pragma once +#include "LogicHandler.h" + +// Why do we need this class? +// We need a way to save and load functions in a way that remembers exactly what "path" they have in the LevelFuncs table hierarchy. +// Thus, even if we use Lua to put a LevelFuncs function in a variable with another, shorter name, we can still pass it into +// LevelVars and have it remember the right function name when loaded. +// todo actually test the above +// This is needed for things like Timers, which call a certain function after a certain amount of time. If we save and then load, +// the FuncNameHolder will be able to use its path as the key to find the actual Lua function to call at the end of the timer. + +// The alternative would be to pass in a full string, but then we would need to split the string at runtime to find +// the exact tables to look in, which seems like it would take longer. + +TO DO: +make sure nested tables save/loads work +make sure timers whose funcs take multiple args works +make sure nested tables AND multiple args works +class FuncNameHolder { +public: + std::string m_funcName; + LogicHandler* m_handler; + void Call(sol::variadic_args vs) + { + m_handler->CallLevelFunc(m_funcName, vs); + } + void CallDT(float dt) + { + m_handler->CallLevelFunc(m_funcName, dt); + } + + static void Register(sol::table & parent) + { + parent.new_usertype("FuncHolderNameString", sol::no_constructor, sol::meta_function::call, &Call); + } +}; + diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index e51798363..6dc2c8b0e 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -9,7 +9,7 @@ #include "ScriptUtil.h" #include "Objects/Moveable/MoveableObject.h" #include "Vec3/Vec3.h" - +#include "FuncNameHolder.h" using namespace TEN::Effects::Lightning; /*** @@ -30,6 +30,8 @@ static const std::unordered_map kCallbackPoints {"POSTCONTROLPHASE", CallbackPoint::PostControl}, }; +using LevelFuncsTable = std::pair; + void SetVariable(sol::table tab, sol::object key, sol::object value) { switch (value.get_type()) @@ -86,6 +88,10 @@ LogicHandler::LogicHandler(sol::state* lua, sol::table & parent) : m_handler{ lu m_handler.MakeReadOnlyTable(table_logic, ScriptReserved_CallbackPoint, kCallbackPoints); + //it crashes when here + // todo fix? + //FuncNameHolder::Register(table_logic); + ResetScripts(true); } @@ -102,23 +108,44 @@ Possible values for CallbackPoint: The order in which two functions with the same CallbackPoint are called is undefined. i.e. if you register `MyFunc` and `MyFunc2` with `PRECONTROLPHASE`, both will be called before `OnControlPhase`, but there is no guarantee whether `MyFunc` will be called before `MyFunc2`, or vice-versa. + + @function AddCallback @tparam point CallbackPoint When should the callback be called? -@tparam func string The LevelFuncs function to be called. Will receive as an argument the time in seconds since the last frame. +@tparam func string The name of the function to be called. Will receive as an argument the time in seconds since the last frame. @usage - LevelFuncs.MyFunc = function(dt) print(dt) end + local MyFunc = function(dt) print(dt) end TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") */ -void LogicHandler::AddCallback(CallbackPoint point, std::string const & name) +void LogicHandler::AddCallback(CallbackPoint point, FuncNameHolder & fnh) { + //sol::object obj = tab["funcName"]; + //sol::type type = obj.get_type(); + //switch(type) + //{ + //case sol::type::string: + // TENLog("fuck it's a string"); + // break; + + //case sol::type::userdata: + // TENLog("fuck it's userdata"); + // break; + + //case sol::type::table: + // TENLog("fuck it's a table"); + // break; + //} + + //auto fnh = tab["funcName"]; + //std::string name = tab["funcName"]; switch(point) { case CallbackPoint::PreControl: - m_callbacksPreControl.insert(name); + m_callbacksPreControl.insert(fnh.m_funcName); break; case CallbackPoint::PostControl: - m_callbacksPostControl.insert(name); + m_callbacksPostControl.insert(fnh.m_funcName); break; } } @@ -132,6 +159,7 @@ Will have no effect if the function was not registered as a callback @usage TEN.Logic.RemoveCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") */ +//todo this has to deal with LevelFuncs subtables too now void LogicHandler::RemoveCallback(CallbackPoint point, std::string const & name) { switch(point) @@ -146,33 +174,151 @@ void LogicHandler::RemoveCallback(CallbackPoint point, std::string const & name) } } + static constexpr char const* strKey = "__internal_name"; void LogicHandler::ResetLevelTables() { - MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + //todo does levelFuncs get cleared normally, pre-these changes? + //NO. the TABLE gets reset but m_levelFuncs does NOT get reset + + MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelVars, &GetVariable, &SetVariable); } -sol::protected_function LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaName) +sol::object LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaName) { - if (m_levelFuncs.find(luaName) == m_levelFuncs.end()) - return sol::lua_nil; + //if (m_levelFuncs.find(luaName) == m_levelFuncs.end()) + // return sol::lua_nil; - return m_levelFuncs.at(luaName); + std::string partName = tab.raw_get(strKey); + //std::string x = m_levelFuncsTables[luaName]; + sol::table theTab = m_levelFuncsTables[partName]; + //TENLog("looking for " + luaName); + //std::string x = theTab.raw_get(luaName); + //theTab.raw_get_or() + //TENLog("table has:"); + //for(auto & [key, val] : theTab) + //{ + // std::string keyStr = key.as(); + // std::string valStr = val.as(); + // TENLog(fmt::format("{} = {}", keyStr, valStr)); + //} + //TENLog(""); + std::string x; + sol::object obj = theTab.raw_get(luaName); + if (obj.is()) + { + x = obj.as(); + //TENLog("found " + luaName + ", it was " + x); + + //what if you are asking for a table? + if (m_levelFuncsFakeFuncs[x].valid()) + return m_levelFuncsFakeFuncs[x]; + else + return m_levelFuncsTables[x]; + } + if (obj.is()) + { + return obj; + } + else + { + return sol::nil; + } + //return m_levelFuncs.at(luaName); +} + +void LogicHandler::CallLevelFunc(std::string name, float dt) +{ + sol::protected_function f = m_levelFuncsActualFuncs[name]; + //for (auto & v : va) + //{ + // TENLog(v.as()); + //} + f.call(dt); +} + + +void LogicHandler::CallLevelFunc(std::string name, sol::variadic_args va) +{ + sol::protected_function f = m_levelFuncsActualFuncs[name]; + //for (auto & v : va) + //{ + // TENLog(v.as()); + //} + f.call(va); } bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value) { + + //make m_levelFuncs the 'root' table, make everything else go into "tab" (so maybe all these should act on "tab" and we gotta create original m_levelFuncs ourselves outside of here) + std::string partName; + std::string fullName; + sol::table newTab; + sol::table newLevelFuncsTab; + sol::table aTab; + sol::table meta; + FuncNameHolder fnh; switch (value.get_type()) { case sol::type::lua_nil: - m_levelFuncs.erase(luaName); - break; case sol::type::function: - m_levelFuncs.insert_or_assign(luaName, value.as()); + partName = tab.raw_get(strKey); + fullName = partName + "." + luaName; + aTab = m_levelFuncsTables[partName]; + aTab.raw_set(luaName, fullName); + m_levelFuncsActualFuncs[fullName] = value; + + fnh.m_funcName = fullName; + fnh.m_handler = this; + + m_levelFuncsFakeFuncs[fullName] = fnh; + + //newTab = sol::table{ *(m_handler.GetState()), sol::create }; + //newTab[sol::metatable_key] = sol::table{ *(m_handler.GetState()), sol::create }; + + //meta = newTab[sol::metatable_key]; + //meta.set_function("__call", &LogicHandler::CallLevelFunc, this); + //newTab.set("funcName", fullName); +// m_levelFuncsFakeFuncs[fullName] = newTab; + + //update: don't need to do this actually I don't think... + //todo make another m_levelFuncsActualFuncs member with the actual func call + break; + case sol::type::table: + //make a copy of the table using + //tab.raw_set(luaName, MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this)); + //todo need to make anonoymous version of MakeSpecialTable + newTab = sol::table{ *(m_handler.GetState()), sol::create }; + fullName = tab.raw_get(strKey) + "." + luaName; + m_levelFuncsTables[fullName] = newTab; + + partName = tab.raw_get(strKey); + aTab = m_levelFuncsTables[partName]; + aTab.raw_set(luaName, fullName); + + newTab.raw_set(strKey, fullName); + + for (auto& [key, val] : value.as()) + { + newTab[key] = val; + } + + newLevelFuncsTab = MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + newLevelFuncsTab.raw_set(strKey, fullName); + tab.raw_set(luaName, newLevelFuncsTab); + + for (auto& [key, val] : value.as()) + { + newLevelFuncsTab[key] = val; + } + //tab.raw_set(luaName, newTab); + + // assign the copy of the table break; default: - std::string error{ "Could not assign LevelFuncs." }; - error += luaName + "; it must be a function (or nil)."; + std::string error{ "Failed to add " }; + error += luaName + " to LevelFuncs or one of its tables; it must be a function, a table of functions, or nil."; return ScriptAssert(false, error); } return true; @@ -195,6 +341,10 @@ void LogicHandler::ResetScripts(bool clearGameVars) { FreeLevelScripts(); + //todo are these getting called? + //load level. walk to trigger that adds here + //save and reload + m_callbacksPreControl.clear(); m_callbacksPostControl.clear(); @@ -214,7 +364,16 @@ void LogicHandler::ResetScripts(bool clearGameVars) void LogicHandler::FreeLevelScripts() { - m_levelFuncs.clear(); + //m_levelFuncs.clear(); + //m_levelFuncs = + m_levelFuncs = MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + + m_levelFuncsTables = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncsActualFuncs = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncsFakeFuncs = sol::table{ *(m_handler.GetState()), sol::create }; + + m_levelFuncsTables[ScriptReserved_LevelFuncs] = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncs.raw_set(strKey, ScriptReserved_LevelFuncs); ResetLevelTables(); m_onStart = sol::nil; m_onLoad = sol::nil; @@ -296,6 +455,13 @@ void LogicHandler::SetVariables(std::vector const & vars) auto theVec = Vec3{ std::get(vars[second]) }; solTables[i][vars[first]] = theVec; } + else if (std::holds_alternative(vars[second])) + { + FuncNameHolder fnh; + fnh.m_funcName = std::get(vars[second]).name; + fnh.m_handler = this; + solTables[i][vars[first]] = fnh; + } else { solTables[i][vars[first]] = vars[second]; @@ -391,6 +557,20 @@ void LogicHandler::GetVariables(std::vector & vars) return first->second; }; + auto handleFuncName = [&](FuncNameHolder const& fnh) + { + //auto str = obj.as(); + auto [first, second] = varsMap.insert(std::make_pair(&fnh, nVars)); + + if (second) + { + vars.push_back(FuncName{ std::string{ fnh.m_funcName } }); + ++nVars; + } + + return first->second; + }; + std::function populate = [&](sol::table const & obj) { auto [first, second] = varsMap.insert(std::make_pair(obj.pointer(), nVars)); @@ -442,6 +622,8 @@ void LogicHandler::GetVariables(std::vector & vars) { if(second.is()) putInVars(handleVec3(second.as())); + else if(second.is()) + putInVars(handleFuncName(second.as())); else ScriptAssert(false, "Tried saving an unsupported userdata as a value"); } @@ -555,14 +737,17 @@ void LogicHandler::OnLoad() void LogicHandler::OnControlPhase(float dt) { - sol::table levelFuncs = (*m_handler.GetState())[ScriptReserved_LevelFuncs]; - - auto tryCall = [dt, &levelFuncs](std::string const& name) + //todo write that returned values will get ignored + auto tryCall = [this, dt](std::string const& name) { - if (!levelFuncs[name].valid()) + auto func = m_handler.GetState()->script("return " + name); + + //todo fail if this is nil + if (!func.valid()) ScriptAssertF(false, "Callback {} not valid", name); - else - levelFuncs[name].call(dt); + else //todo this is a FuncNameHolder, not a function, so ye + func.get().CallDT(dt); + //sol::function(func).call(dt); }; for (auto& name : m_callbacksPreControl) @@ -670,8 +855,26 @@ void LogicHandler::InitCallbacks() { auto assignCB = [this](sol::protected_function& func, std::string const & luaFunc) { std::string fullName = "LevelFuncs." + luaFunc; - func = (*m_handler.GetState())["LevelFuncs"][luaFunc]; + + sol::object theData = (*m_handler.GetState())["LevelFuncs"][luaFunc]; + std::string err{ "Level's script does not define callback " + fullName}; + if (!ScriptAssert(theData.valid(), err)) { + ScriptWarn("Defaulting to no " + fullName + " behaviour."); + return; + } + FuncNameHolder fnh = (*m_handler.GetState())["LevelFuncs"][luaFunc]; + + func = m_levelFuncsActualFuncs[fnh.m_funcName]; + + if(func.get_type() == sol::type::function) + { + TENLog("function"); + } + if(func.get_type() == sol::type::userdata) + { + TENLog("userdata"); + } if (!ScriptAssert(func.valid(), err)) { ScriptWarn("Defaulting to no " + fullName + " behaviour."); } diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 498102f1c..a62fa3136 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -5,12 +5,76 @@ #include #include "Strings/StringsHandler.h" +class FuncNameHolder; enum class CallbackPoint; +//template class OnlyAllows +//{ +// OnlyAllows() +// { +// +// } +//}; +enum class TestEnum +{ + one, + two, + three +}; + +template bool allow(TestEnum type) +{ + std::array allowedTypes{allowed...}; + for(TestEnum e : allowedTypes) + { + if (e == type) + { + return true; + } + } + + return false; +} + class LogicHandler : public ScriptInterfaceGame { private: - std::unordered_map m_levelFuncs{}; + // Hierarchy of tables. + // + // LevelFuncs + // |- TEN + // |- Timer + // |- Util + // |- Ext + // |- MyLib + // |- MySecondLib + // |- SubTable + // + // Each of these tables can only contain other tables as well as a string with their "path". + // For example, the SubTable table will have a path of "LevelFuncs.Ext.MySecondLib.SubTable". + // It uses this to construct the full path name of any functions that end up in m_levelFuncsActualFuncs. + // + // Each of these has a metatable whose __index metamethod looks in m_levelFuncsTables, using the path + // as the key, for the full name of the function. It then gets the FuncNameHolder from m_levelFuncsFakeFuncs, + // and that FuncNameHolder's __call metamethod looks in m_levelFuncsActualFuncs for the real function. + sol::table m_levelFuncs{}; + + // Maps full function paths into Lua functions. + sol::table m_levelFuncsActualFuncs{}; + + // Maps full function paths to FunctionNameHolders. + sol::table m_levelFuncsFakeFuncs{}; + + // Contains tables; each table refers to a table in the LevelFuncs hierarchy, and contains the full names + // of the functions to index in m_levelFuncsActualFuncs (or fake funcs? idk). + // Tables are non-nested, so the following are all at the base level of m_levelFuncsTables. + // "LevelFuncs" + // "LevelFuncs.TEN" + // "LevelFuncs.TEN.Util" + // "LevelFuncs.MyLevel" + // "LevelFuncs.MyLevel.CoolFuncs" + sol::table m_levelFuncsTables{}; + sol::protected_function m_onStart{}; sol::protected_function m_onLoad{}; sol::protected_function m_onControlPhase{}; @@ -27,17 +91,20 @@ private: public: LogicHandler(sol::state* lua, sol::table & parent); + void CallLevelFunc(std::string, sol::variadic_args); + void CallLevelFunc(std::string, float dt); + void FreeLevelScripts() override; void LogPrint(sol::variadic_args va); bool SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value); - void AddCallback(CallbackPoint point, std::string const& name); + void AddCallback(CallbackPoint point, FuncNameHolder & holder); void RemoveCallback(CallbackPoint point, std::string const & name); void ResetScripts(bool clearGameVars) override; - sol::protected_function GetLevelFunc(sol::table tab, std::string const& luaName); + sol::object GetLevelFunc(sol::table tab, std::string const& luaName); void ExecuteScriptFile(const std::string& luaFilename) override; void ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer, std::string const& arguments) override; diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h index ad9d4a229..9a483bfe0 100644 --- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h +++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h @@ -143,6 +143,10 @@ struct vec3Table; struct vec3TableBuilder; struct vec3TableT; +struct funcNameTable; +struct funcNameTableBuilder; +struct funcNameTableT; + struct UnionTable; struct UnionTableBuilder; struct UnionTableT; @@ -206,37 +210,40 @@ enum class VarUnion : uint8_t { num = 3, boolean = 4, vec3 = 5, + funcName = 6, MIN = NONE, - MAX = vec3 + MAX = funcName }; -inline const VarUnion (&EnumValuesVarUnion())[6] { +inline const VarUnion (&EnumValuesVarUnion())[7] { static const VarUnion values[] = { VarUnion::NONE, VarUnion::str, VarUnion::tab, VarUnion::num, VarUnion::boolean, - VarUnion::vec3 + VarUnion::vec3, + VarUnion::funcName }; return values; } inline const char * const *EnumNamesVarUnion() { - static const char * const names[7] = { + static const char * const names[8] = { "NONE", "str", "tab", "num", "boolean", "vec3", + "funcName", nullptr }; return names; } inline const char *EnumNameVarUnion(VarUnion e) { - if (flatbuffers::IsOutRange(e, VarUnion::NONE, VarUnion::vec3)) return ""; + if (flatbuffers::IsOutRange(e, VarUnion::NONE, VarUnion::funcName)) return ""; const size_t index = static_cast(e); return EnumNamesVarUnion()[index]; } @@ -265,6 +272,10 @@ template<> struct VarUnionTraits { static const VarUnion enum_value = VarUnion::vec3; }; +template<> struct VarUnionTraits { + static const VarUnion enum_value = VarUnion::funcName; +}; + struct VarUnionUnion { VarUnion type; void *value; @@ -337,6 +348,14 @@ struct VarUnionUnion { return type == VarUnion::vec3 ? reinterpret_cast(value) : nullptr; } + TEN::Save::funcNameTableT *AsfuncName() { + return type == VarUnion::funcName ? + reinterpret_cast(value) : nullptr; + } + const TEN::Save::funcNameTableT *AsfuncName() const { + return type == VarUnion::funcName ? + reinterpret_cast(value) : nullptr; + } }; bool VerifyVarUnion(flatbuffers::Verifier &verifier, const void *obj, VarUnion type); @@ -5438,6 +5457,74 @@ struct vec3Table::Traits { flatbuffers::Offset Createvec3Table(flatbuffers::FlatBufferBuilder &_fbb, const vec3TableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +struct funcNameTableT : public flatbuffers::NativeTable { + typedef funcNameTable TableType; + std::string str{}; +}; + +struct funcNameTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { + typedef funcNameTableT NativeTableType; + typedef funcNameTableBuilder Builder; + struct Traits; + enum FlatBuffersVTableOffset FLATBUFFERS_VTABLE_UNDERLYING_TYPE { + VT_STR = 4 + }; + const flatbuffers::String *str() const { + return GetPointer(VT_STR); + } + bool Verify(flatbuffers::Verifier &verifier) const { + return VerifyTableStart(verifier) && + VerifyOffset(verifier, VT_STR) && + verifier.VerifyString(str()) && + verifier.EndTable(); + } + funcNameTableT *UnPack(const flatbuffers::resolver_function_t *_resolver = nullptr) const; + void UnPackTo(funcNameTableT *_o, const flatbuffers::resolver_function_t *_resolver = nullptr) const; + static flatbuffers::Offset Pack(flatbuffers::FlatBufferBuilder &_fbb, const funcNameTableT* _o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); +}; + +struct funcNameTableBuilder { + typedef funcNameTable Table; + flatbuffers::FlatBufferBuilder &fbb_; + flatbuffers::uoffset_t start_; + void add_str(flatbuffers::Offset str) { + fbb_.AddOffset(funcNameTable::VT_STR, str); + } + explicit funcNameTableBuilder(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 CreatefuncNameTable( + flatbuffers::FlatBufferBuilder &_fbb, + flatbuffers::Offset str = 0) { + funcNameTableBuilder builder_(_fbb); + builder_.add_str(str); + return builder_.Finish(); +} + +struct funcNameTable::Traits { + using type = funcNameTable; + static auto constexpr Create = CreatefuncNameTable; +}; + +inline flatbuffers::Offset CreatefuncNameTableDirect( + flatbuffers::FlatBufferBuilder &_fbb, + const char *str = nullptr) { + auto str__ = str ? _fbb.CreateString(str) : 0; + return TEN::Save::CreatefuncNameTable( + _fbb, + str__); +} + +flatbuffers::Offset CreatefuncNameTable(flatbuffers::FlatBufferBuilder &_fbb, const funcNameTableT *_o, const flatbuffers::rehasher_function_t *_rehasher = nullptr); + struct UnionTableT : public flatbuffers::NativeTable { typedef UnionTable TableType; TEN::Save::VarUnionUnion u{}; @@ -5473,6 +5560,9 @@ struct UnionTable FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table { const TEN::Save::vec3Table *u_as_vec3() const { return u_type() == TEN::Save::VarUnion::vec3 ? static_cast(u()) : nullptr; } + const TEN::Save::funcNameTable *u_as_funcName() const { + return u_type() == TEN::Save::VarUnion::funcName ? static_cast(u()) : nullptr; + } bool Verify(flatbuffers::Verifier &verifier) const { return VerifyTableStart(verifier) && VerifyField(verifier, VT_U_TYPE) && @@ -5505,6 +5595,10 @@ template<> inline const TEN::Save::vec3Table *UnionTable::u_as inline const TEN::Save::funcNameTable *UnionTable::u_as() const { + return u_as_funcName(); +} + struct UnionTableBuilder { typedef UnionTable Table; flatbuffers::FlatBufferBuilder &fbb_; @@ -8068,6 +8162,32 @@ inline flatbuffers::Offset Createvec3Table(flatbuffers::FlatBufferBui _vec); } +inline funcNameTableT *funcNameTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const { + auto _o = std::make_unique(); + UnPackTo(_o.get(), _resolver); + return _o.release(); +} + +inline void funcNameTable::UnPackTo(funcNameTableT *_o, const flatbuffers::resolver_function_t *_resolver) const { + (void)_o; + (void)_resolver; + { auto _e = str(); if (_e) _o->str = _e->str(); } +} + +inline flatbuffers::Offset funcNameTable::Pack(flatbuffers::FlatBufferBuilder &_fbb, const funcNameTableT* _o, const flatbuffers::rehasher_function_t *_rehasher) { + return CreatefuncNameTable(_fbb, _o, _rehasher); +} + +inline flatbuffers::Offset CreatefuncNameTable(flatbuffers::FlatBufferBuilder &_fbb, const funcNameTableT *_o, const flatbuffers::rehasher_function_t *_rehasher) { + (void)_rehasher; + (void)_o; + struct _VectorArgs { flatbuffers::FlatBufferBuilder *__fbb; const funcNameTableT* __o; const flatbuffers::rehasher_function_t *__rehasher; } _va = { &_fbb, _o, _rehasher}; (void)_va; + auto _str = _o->str.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->str); + return TEN::Save::CreatefuncNameTable( + _fbb, + _str); +} + inline UnionTableT *UnionTable::UnPack(const flatbuffers::resolver_function_t *_resolver) const { auto _o = std::make_unique(); UnPackTo(_o.get(), _resolver); @@ -8376,6 +8496,10 @@ inline bool VerifyVarUnion(flatbuffers::Verifier &verifier, const void *obj, Var auto ptr = reinterpret_cast(obj); return verifier.VerifyTable(ptr); } + case VarUnion::funcName: { + auto ptr = reinterpret_cast(obj); + return verifier.VerifyTable(ptr); + } default: return true; } } @@ -8414,6 +8538,10 @@ inline void *VarUnionUnion::UnPack(const void *obj, VarUnion type, const flatbuf auto ptr = reinterpret_cast(obj); return ptr->UnPack(resolver); } + case VarUnion::funcName: { + auto ptr = reinterpret_cast(obj); + return ptr->UnPack(resolver); + } default: return nullptr; } } @@ -8440,6 +8568,10 @@ inline flatbuffers::Offset VarUnionUnion::Pack(flatbuffers::FlatBufferBuil auto ptr = reinterpret_cast(value); return Createvec3Table(_fbb, ptr, _rehasher).Union(); } + case VarUnion::funcName: { + auto ptr = reinterpret_cast(value); + return CreatefuncNameTable(_fbb, ptr, _rehasher).Union(); + } default: return 0; } } @@ -8466,6 +8598,10 @@ inline VarUnionUnion::VarUnionUnion(const VarUnionUnion &u) : type(u.type), valu FLATBUFFERS_ASSERT(false); // TEN::Save::vec3TableT not copyable. break; } + case VarUnion::funcName: { + value = new TEN::Save::funcNameTableT(*reinterpret_cast(u.value)); + break; + } default: break; } @@ -8498,6 +8634,11 @@ inline void VarUnionUnion::Reset() { delete ptr; break; } + case VarUnion::funcName: { + auto ptr = reinterpret_cast(value); + delete ptr; + break; + } default: break; } value = nullptr; diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs index 90e21696b..b6e140fdb 100644 --- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs +++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs @@ -389,12 +389,17 @@ table vec3Table { vec: Vector3; } +table funcNameTable { + str: string; +} + union VarUnion { str: stringTable, tab: ScriptTable, num: doubleTable, boolean: boolTable, - vec3: vec3Table + vec3: vec3Table, + funcName: funcNameTable } table UnionTable{ diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index e040db513..49676eb5a 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -234,6 +234,7 @@ CALL gen.bat + From 3e1887fb99e08d732ac15c6eebdc70647a992bab Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 30 Aug 2022 20:41:07 +0100 Subject: [PATCH 049/106] I tested this and it seems to work. --- TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h | 5 ----- 1 file changed, 5 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h b/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h index f89a95759..6788cc564 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h @@ -5,17 +5,12 @@ // We need a way to save and load functions in a way that remembers exactly what "path" they have in the LevelFuncs table hierarchy. // Thus, even if we use Lua to put a LevelFuncs function in a variable with another, shorter name, we can still pass it into // LevelVars and have it remember the right function name when loaded. -// todo actually test the above // This is needed for things like Timers, which call a certain function after a certain amount of time. If we save and then load, // the FuncNameHolder will be able to use its path as the key to find the actual Lua function to call at the end of the timer. // The alternative would be to pass in a full string, but then we would need to split the string at runtime to find // the exact tables to look in, which seems like it would take longer. -TO DO: -make sure nested tables save/loads work -make sure timers whose funcs take multiple args works -make sure nested tables AND multiple args works class FuncNameHolder { public: std::string m_funcName; From 8c55327b46d0feda3bfce019f9bcdb4f8ada2799 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 30 Aug 2022 22:59:45 +0100 Subject: [PATCH 050/106] Rename FuncNameHolder to LevelFunc. --- .../Scripting/Internal/ReservedScriptNames.h | 1 + .../Internal/TEN/Flow/FlowHandler.cpp | 5 ++- .../Internal/TEN/Logic/FuncNameHolder.h | 5 +-- .../Internal/TEN/Logic/LogicHandler.cpp | 17 +++++----- .../Internal/TEN/Logic/LogicHandler.h | 33 ++----------------- 5 files changed, 18 insertions(+), 43 deletions(-) diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h index 6ce0294ab..edd14601b 100644 --- a/TombEngine/Scripting/Internal/ReservedScriptNames.h +++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h @@ -20,6 +20,7 @@ static constexpr char ScriptReserved_AIObject[] = "AIObject"; static constexpr char ScriptReserved_DisplayString[] = "DisplayString"; static constexpr char ScriptReserved_Vec3[] = "Vec3"; static constexpr char ScriptReserved_Rotation[] = "Rotation"; +static constexpr char ScriptReserved_LevelFunc[] = "LevelFunc"; // Member functions static constexpr char ScriptReserved_New[] = "New"; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index 11c0978bc..3ad18239c 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -11,6 +11,7 @@ #include "Logic/FuncNameHolder.h" #include "Vec3/Vec3.h" #include "Objects/ScriptInterfaceObjectsHandler.h" +#include "Strings/ScriptInterfaceStringsHandler.h" #include "Specific/trutils.h" /*** @@ -113,7 +114,9 @@ Specify which translations in the strings table correspond to which languages. Animations::Register(table_flow); Settings::Register(table_flow); Fog::Register(table_flow); - FuncNameHolder::Register(parent); + + //todo find out why this can't be in logic + LevelFunc::Register(parent); m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_WeatherType, kWeatherTypes); m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_LaraType, kLaraTypes); diff --git a/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h b/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h index 6788cc564..a525a8f0f 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h @@ -1,5 +1,6 @@ #pragma once #include "LogicHandler.h" +#include "ReservedScriptNames.h" // Why do we need this class? // We need a way to save and load functions in a way that remembers exactly what "path" they have in the LevelFuncs table hierarchy. @@ -11,7 +12,7 @@ // The alternative would be to pass in a full string, but then we would need to split the string at runtime to find // the exact tables to look in, which seems like it would take longer. -class FuncNameHolder { +class LevelFunc { public: std::string m_funcName; LogicHandler* m_handler; @@ -26,7 +27,7 @@ public: static void Register(sol::table & parent) { - parent.new_usertype("FuncHolderNameString", sol::no_constructor, sol::meta_function::call, &Call); + parent.new_usertype(ScriptReserved_LevelFunc, sol::no_constructor, sol::meta_function::call, &Call); } }; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 6dc2c8b0e..2caf9da23 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -117,7 +117,7 @@ i.e. if you register `MyFunc` and `MyFunc2` with `PRECONTROLPHASE`, both will be local MyFunc = function(dt) print(dt) end TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") */ -void LogicHandler::AddCallback(CallbackPoint point, FuncNameHolder & fnh) +void LogicHandler::AddCallback(CallbackPoint point, LevelFunc & fnh) { //sol::object obj = tab["funcName"]; //sol::type type = obj.get_type(); @@ -258,7 +258,7 @@ bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol: sol::table newLevelFuncsTab; sol::table aTab; sol::table meta; - FuncNameHolder fnh; + LevelFunc fnh; switch (value.get_type()) { case sol::type::lua_nil: @@ -457,7 +457,7 @@ void LogicHandler::SetVariables(std::vector const & vars) } else if (std::holds_alternative(vars[second])) { - FuncNameHolder fnh; + LevelFunc fnh; fnh.m_funcName = std::get(vars[second]).name; fnh.m_handler = this; solTables[i][vars[first]] = fnh; @@ -557,7 +557,7 @@ void LogicHandler::GetVariables(std::vector & vars) return first->second; }; - auto handleFuncName = [&](FuncNameHolder const& fnh) + auto handleFuncName = [&](LevelFunc const& fnh) { //auto str = obj.as(); auto [first, second] = varsMap.insert(std::make_pair(&fnh, nVars)); @@ -622,8 +622,8 @@ void LogicHandler::GetVariables(std::vector & vars) { if(second.is()) putInVars(handleVec3(second.as())); - else if(second.is()) - putInVars(handleFuncName(second.as())); + else if(second.is()) + putInVars(handleFuncName(second.as())); else ScriptAssert(false, "Tried saving an unsupported userdata as a value"); } @@ -746,8 +746,7 @@ void LogicHandler::OnControlPhase(float dt) if (!func.valid()) ScriptAssertF(false, "Callback {} not valid", name); else //todo this is a FuncNameHolder, not a function, so ye - func.get().CallDT(dt); - //sol::function(func).call(dt); + func.get().CallDT(dt); }; for (auto& name : m_callbacksPreControl) @@ -863,7 +862,7 @@ void LogicHandler::InitCallbacks() ScriptWarn("Defaulting to no " + fullName + " behaviour."); return; } - FuncNameHolder fnh = (*m_handler.GetState())["LevelFuncs"][luaFunc]; + LevelFunc fnh = (*m_handler.GetState())["LevelFuncs"][luaFunc]; func = m_levelFuncsActualFuncs[fnh.m_funcName]; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index a62fa3136..86a00ff70 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -3,39 +3,10 @@ #include "Game/items.h" #include "LuaHandler.h" #include -#include "Strings/StringsHandler.h" -class FuncNameHolder; +class LevelFunc; enum class CallbackPoint; -//template class OnlyAllows -//{ -// OnlyAllows() -// { -// -// } -//}; -enum class TestEnum -{ - one, - two, - three -}; - -template bool allow(TestEnum type) -{ - std::array allowedTypes{allowed...}; - for(TestEnum e : allowedTypes) - { - if (e == type) - { - return true; - } - } - - return false; -} - class LogicHandler : public ScriptInterfaceGame { private: @@ -99,7 +70,7 @@ public: void LogPrint(sol::variadic_args va); bool SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value); - void AddCallback(CallbackPoint point, FuncNameHolder & holder); + void AddCallback(CallbackPoint point, LevelFunc & holder); void RemoveCallback(CallbackPoint point, std::string const & name); void ResetScripts(bool clearGameVars) override; From 3af6bfb7aa770a8f50842fc8e5fb8e339b450639 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 30 Aug 2022 23:26:04 +0100 Subject: [PATCH 051/106] Clean stuff, give a proper name to a variable. --- .../Internal/TEN/Logic/LogicHandler.cpp | 58 ++++--------------- .../Internal/TEN/Logic/LogicHandler.h | 8 +-- 2 files changed, 14 insertions(+), 52 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 2caf9da23..d04f36fc1 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -186,71 +186,33 @@ void LogicHandler::ResetLevelTables() sol::object LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaName) { - //if (m_levelFuncs.find(luaName) == m_levelFuncs.end()) - // return sol::lua_nil; - std::string partName = tab.raw_get(strKey); - //std::string x = m_levelFuncsTables[luaName]; sol::table theTab = m_levelFuncsTables[partName]; - //TENLog("looking for " + luaName); - //std::string x = theTab.raw_get(luaName); - //theTab.raw_get_or() - //TENLog("table has:"); - //for(auto & [key, val] : theTab) - //{ - // std::string keyStr = key.as(); - // std::string valStr = val.as(); - // TENLog(fmt::format("{} = {}", keyStr, valStr)); - //} - //TENLog(""); - std::string x; + sol::object obj = theTab.raw_get(luaName); if (obj.is()) { - x = obj.as(); - //TENLog("found " + luaName + ", it was " + x); - - //what if you are asking for a table? - if (m_levelFuncsFakeFuncs[x].valid()) - return m_levelFuncsFakeFuncs[x]; - else - return m_levelFuncsTables[x]; + std::string key = obj.as(); + if (m_levelFuncsFakeFuncs[key].valid()) + return m_levelFuncsFakeFuncs[key]; } - if (obj.is()) - { - return obj; - } - else - { - return sol::nil; - } - //return m_levelFuncs.at(luaName); + return sol::nil; } void LogicHandler::CallLevelFunc(std::string name, float dt) { - sol::protected_function f = m_levelFuncsActualFuncs[name]; - //for (auto & v : va) - //{ - // TENLog(v.as()); - //} + sol::protected_function f = m_levelFuncs_luaFunctions[name]; f.call(dt); } - void LogicHandler::CallLevelFunc(std::string name, sol::variadic_args va) { - sol::protected_function f = m_levelFuncsActualFuncs[name]; - //for (auto & v : va) - //{ - // TENLog(v.as()); - //} + sol::protected_function f = m_levelFuncs_luaFunctions[name]; f.call(va); } bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value) { - //make m_levelFuncs the 'root' table, make everything else go into "tab" (so maybe all these should act on "tab" and we gotta create original m_levelFuncs ourselves outside of here) std::string partName; std::string fullName; @@ -267,7 +229,7 @@ bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol: fullName = partName + "." + luaName; aTab = m_levelFuncsTables[partName]; aTab.raw_set(luaName, fullName); - m_levelFuncsActualFuncs[fullName] = value; + m_levelFuncs_luaFunctions[fullName] = value; fnh.m_funcName = fullName; fnh.m_handler = this; @@ -369,7 +331,7 @@ void LogicHandler::FreeLevelScripts() m_levelFuncs = MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); m_levelFuncsTables = sol::table{ *(m_handler.GetState()), sol::create }; - m_levelFuncsActualFuncs = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncs_luaFunctions = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncsFakeFuncs = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncsTables[ScriptReserved_LevelFuncs] = sol::table{ *(m_handler.GetState()), sol::create }; @@ -864,7 +826,7 @@ void LogicHandler::InitCallbacks() } LevelFunc fnh = (*m_handler.GetState())["LevelFuncs"][luaFunc]; - func = m_levelFuncsActualFuncs[fnh.m_funcName]; + func = m_levelFuncs_luaFunctions[fnh.m_funcName]; if(func.get_type() == sol::type::function) { diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 86a00ff70..d07031192 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -23,21 +23,21 @@ private: // // Each of these tables can only contain other tables as well as a string with their "path". // For example, the SubTable table will have a path of "LevelFuncs.Ext.MySecondLib.SubTable". - // It uses this to construct the full path name of any functions that end up in m_levelFuncsActualFuncs. + // It uses this to construct the full path name of any functions that end up in m_levelFuncs_luaFunctions. // // Each of these has a metatable whose __index metamethod looks in m_levelFuncsTables, using the path // as the key, for the full name of the function. It then gets the FuncNameHolder from m_levelFuncsFakeFuncs, - // and that FuncNameHolder's __call metamethod looks in m_levelFuncsActualFuncs for the real function. + // and that FuncNameHolder's __call metamethod looks in m_levelFuncs_luaFunctions for the real function. sol::table m_levelFuncs{}; // Maps full function paths into Lua functions. - sol::table m_levelFuncsActualFuncs{}; + sol::table m_levelFuncs_luaFunctions{}; // Maps full function paths to FunctionNameHolders. sol::table m_levelFuncsFakeFuncs{}; // Contains tables; each table refers to a table in the LevelFuncs hierarchy, and contains the full names - // of the functions to index in m_levelFuncsActualFuncs (or fake funcs? idk). + // of the functions to index in m_levelFuncs_luaFunctions. // Tables are non-nested, so the following are all at the base level of m_levelFuncsTables. // "LevelFuncs" // "LevelFuncs.TEN" From ebcc0c62b0fddc45ca158bc66a58691319c0abe1 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 30 Aug 2022 23:42:59 +0100 Subject: [PATCH 052/106] Rename another var, more cleanup --- .../Internal/TEN/Logic/LogicHandler.cpp | 27 ++++--------------- .../Internal/TEN/Logic/LogicHandler.h | 4 +-- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index d04f36fc1..1e966ac91 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -193,8 +193,8 @@ sol::object LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaNam if (obj.is()) { std::string key = obj.as(); - if (m_levelFuncsFakeFuncs[key].valid()) - return m_levelFuncsFakeFuncs[key]; + if (m_levelFuncs_levelFuncObjects[key].valid()) + return m_levelFuncs_levelFuncObjects[key]; } return sol::nil; } @@ -213,7 +213,6 @@ void LogicHandler::CallLevelFunc(std::string name, sol::variadic_args va) bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value) { - //make m_levelFuncs the 'root' table, make everything else go into "tab" (so maybe all these should act on "tab" and we gotta create original m_levelFuncs ourselves outside of here) std::string partName; std::string fullName; sol::table newTab; @@ -224,6 +223,7 @@ bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol: switch (value.get_type()) { case sol::type::lua_nil: + //todo should we handle this? case sol::type::function: partName = tab.raw_get(strKey); fullName = partName + "." + luaName; @@ -234,23 +234,9 @@ bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol: fnh.m_funcName = fullName; fnh.m_handler = this; - m_levelFuncsFakeFuncs[fullName] = fnh; - - //newTab = sol::table{ *(m_handler.GetState()), sol::create }; - //newTab[sol::metatable_key] = sol::table{ *(m_handler.GetState()), sol::create }; - - //meta = newTab[sol::metatable_key]; - //meta.set_function("__call", &LogicHandler::CallLevelFunc, this); - //newTab.set("funcName", fullName); -// m_levelFuncsFakeFuncs[fullName] = newTab; - - //update: don't need to do this actually I don't think... - //todo make another m_levelFuncsActualFuncs member with the actual func call + m_levelFuncs_levelFuncObjects[fullName] = fnh; break; case sol::type::table: - //make a copy of the table using - //tab.raw_set(luaName, MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this)); - //todo need to make anonoymous version of MakeSpecialTable newTab = sol::table{ *(m_handler.GetState()), sol::create }; fullName = tab.raw_get(strKey) + "." + luaName; m_levelFuncsTables[fullName] = newTab; @@ -274,9 +260,6 @@ bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol: { newLevelFuncsTab[key] = val; } - //tab.raw_set(luaName, newTab); - - // assign the copy of the table break; default: std::string error{ "Failed to add " }; @@ -332,7 +315,7 @@ void LogicHandler::FreeLevelScripts() m_levelFuncsTables = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncs_luaFunctions = sol::table{ *(m_handler.GetState()), sol::create }; - m_levelFuncsFakeFuncs = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncs_levelFuncObjects = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncsTables[ScriptReserved_LevelFuncs] = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncs.raw_set(strKey, ScriptReserved_LevelFuncs); diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index d07031192..1f9c8e79f 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -33,8 +33,8 @@ private: // Maps full function paths into Lua functions. sol::table m_levelFuncs_luaFunctions{}; - // Maps full function paths to FunctionNameHolders. - sol::table m_levelFuncsFakeFuncs{}; + // Maps full function paths to LevelFunc objects. + sol::table m_levelFuncs_levelFuncObjects{}; // Contains tables; each table refers to a table in the LevelFuncs hierarchy, and contains the full names // of the functions to index in m_levelFuncs_luaFunctions. From 1398cce49e18af6a6f230dcb4a3efb1ef2ad14fb Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 31 Aug 2022 18:58:58 +0100 Subject: [PATCH 053/106] Make one of the new tables an unordered_map so we can actually see what's in it with the debugger. --- .../Internal/TEN/Logic/LogicHandler.cpp | 80 +++++++++---------- .../Internal/TEN/Logic/LogicHandler.h | 2 +- 2 files changed, 40 insertions(+), 42 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 1e966ac91..9f75389d9 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -187,12 +187,12 @@ void LogicHandler::ResetLevelTables() sol::object LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaName) { std::string partName = tab.raw_get(strKey); - sol::table theTab = m_levelFuncsTables[partName]; + auto & theMap = m_levelFuncs_tablesOfNames[partName]; - sol::object obj = theTab.raw_get(luaName); - if (obj.is()) + auto fullNameIt = theMap.find(luaName); + if (fullNameIt != std::cend(theMap)) { - std::string key = obj.as(); + std::string_view key = fullNameIt->second; if (m_levelFuncs_levelFuncObjects[key].valid()) return m_levelFuncs_levelFuncObjects[key]; } @@ -213,54 +213,51 @@ void LogicHandler::CallLevelFunc(std::string name, sol::variadic_args va) bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value) { - std::string partName; std::string fullName; - sol::table newTab; + std::unordered_map newNameTab; sol::table newLevelFuncsTab; - sol::table aTab; sol::table meta; - LevelFunc fnh; + LevelFunc levelFuncObject; + std::string partName; switch (value.get_type()) { case sol::type::lua_nil: //todo should we handle this? case sol::type::function: - partName = tab.raw_get(strKey); - fullName = partName + "." + luaName; - aTab = m_levelFuncsTables[partName]; - aTab.raw_set(luaName, fullName); - m_levelFuncs_luaFunctions[fullName] = value; + { + partName = tab.raw_get(strKey); + fullName = partName + "." + luaName; + auto & parentNameTab = m_levelFuncs_tablesOfNames[partName]; + parentNameTab.insert_or_assign(luaName, fullName); - fnh.m_funcName = fullName; - fnh.m_handler = this; + m_levelFuncs_luaFunctions[fullName] = value; - m_levelFuncs_levelFuncObjects[fullName] = fnh; - break; + levelFuncObject.m_funcName = fullName; + levelFuncObject.m_handler = this; + + m_levelFuncs_levelFuncObjects[fullName] = levelFuncObject; + } + break; case sol::type::table: - newTab = sol::table{ *(m_handler.GetState()), sol::create }; - fullName = tab.raw_get(strKey) + "." + luaName; - m_levelFuncsTables[fullName] = newTab; + { + fullName = tab.raw_get(strKey) + "." + luaName; + m_levelFuncs_tablesOfNames.insert_or_assign(fullName, newNameTab); - partName = tab.raw_get(strKey); - aTab = m_levelFuncsTables[partName]; - aTab.raw_set(luaName, fullName); + auto& parentNameTab = m_levelFuncs_tablesOfNames[partName]; + partName = tab.raw_get(strKey); + parentNameTab = m_levelFuncs_tablesOfNames[partName]; + parentNameTab.insert_or_assign(luaName, fullName); - newTab.raw_set(strKey, fullName); + newLevelFuncsTab = MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + newLevelFuncsTab.raw_set(strKey, fullName); + tab.raw_set(luaName, newLevelFuncsTab); - for (auto& [key, val] : value.as()) - { - newTab[key] = val; - } - - newLevelFuncsTab = MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); - newLevelFuncsTab.raw_set(strKey, fullName); - tab.raw_set(luaName, newLevelFuncsTab); - - for (auto& [key, val] : value.as()) - { - newLevelFuncsTab[key] = val; - } - break; + for (auto& [key, val] : value.as()) + { + newLevelFuncsTab[key] = val; + } + } + break; default: std::string error{ "Failed to add " }; error += luaName + " to LevelFuncs or one of its tables; it must be a function, a table of functions, or nil."; @@ -312,13 +309,14 @@ void LogicHandler::FreeLevelScripts() //m_levelFuncs.clear(); //m_levelFuncs = m_levelFuncs = MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + m_levelFuncs.raw_set(strKey, ScriptReserved_LevelFuncs); - m_levelFuncsTables = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncs_tablesOfNames.clear(); m_levelFuncs_luaFunctions = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncs_levelFuncObjects = sol::table{ *(m_handler.GetState()), sol::create }; - m_levelFuncsTables[ScriptReserved_LevelFuncs] = sol::table{ *(m_handler.GetState()), sol::create }; - m_levelFuncs.raw_set(strKey, ScriptReserved_LevelFuncs); + m_levelFuncs_tablesOfNames.emplace(std::make_pair(ScriptReserved_LevelFuncs, std::unordered_map{})); + ResetLevelTables(); m_onStart = sol::nil; m_onLoad = sol::nil; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 1f9c8e79f..61721b22a 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -44,7 +44,7 @@ private: // "LevelFuncs.TEN.Util" // "LevelFuncs.MyLevel" // "LevelFuncs.MyLevel.CoolFuncs" - sol::table m_levelFuncsTables{}; + std::unordered_map> m_levelFuncs_tablesOfNames{}; sol::protected_function m_onStart{}; sol::protected_function m_onLoad{}; From 56446b1ae66305fd147ea739fcd87979fc23963f Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 1 Sep 2022 21:30:59 +0100 Subject: [PATCH 054/106] Make another table into an unordered_map, cleanup stuff --- .../Internal/TEN/Logic/LogicHandler.cpp | 113 +++++++----------- .../Internal/TEN/Logic/LogicHandler.h | 15 +-- 2 files changed, 50 insertions(+), 78 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 9f75389d9..d8f7dcc39 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -112,40 +112,21 @@ i.e. if you register `MyFunc` and `MyFunc2` with `PRECONTROLPHASE`, both will be @function AddCallback @tparam point CallbackPoint When should the callback be called? -@tparam func string The name of the function to be called. Will receive as an argument the time in seconds since the last frame. +@tparam LevelFunc The function to be called (must be in the LevelFuncs hierarchy). Will receive as an argument the time in seconds since the last frame. @usage - local MyFunc = function(dt) print(dt) end - TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") + LevelFuncs.MyFunc = function(dt) print(dt) end + TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, LevelFuncs.MyFunc) */ -void LogicHandler::AddCallback(CallbackPoint point, LevelFunc & fnh) +void LogicHandler::AddCallback(CallbackPoint point, LevelFunc const & lf) { - //sol::object obj = tab["funcName"]; - //sol::type type = obj.get_type(); - //switch(type) - //{ - //case sol::type::string: - // TENLog("fuck it's a string"); - // break; - - //case sol::type::userdata: - // TENLog("fuck it's userdata"); - // break; - - //case sol::type::table: - // TENLog("fuck it's a table"); - // break; - //} - - //auto fnh = tab["funcName"]; - //std::string name = tab["funcName"]; switch(point) { case CallbackPoint::PreControl: - m_callbacksPreControl.insert(fnh.m_funcName); + m_callbacksPreControl.insert(lf.m_funcName); break; case CallbackPoint::PostControl: - m_callbacksPostControl.insert(fnh.m_funcName); + m_callbacksPostControl.insert(lf.m_funcName); break; } } @@ -159,17 +140,16 @@ Will have no effect if the function was not registered as a callback @usage TEN.Logic.RemoveCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") */ -//todo this has to deal with LevelFuncs subtables too now -void LogicHandler::RemoveCallback(CallbackPoint point, std::string const & name) +void LogicHandler::RemoveCallback(CallbackPoint point, LevelFunc const & lf) { switch(point) { case CallbackPoint::PreControl: - m_callbacksPreControl.erase(name); + m_callbacksPreControl.erase(lf.m_funcName); break; case CallbackPoint::PostControl: - m_callbacksPostControl.erase(name); + m_callbacksPostControl.erase(lf.m_funcName); break; } } @@ -184,7 +164,7 @@ void LogicHandler::ResetLevelTables() MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelVars, &GetVariable, &SetVariable); } -sol::object LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaName) +sol::object LogicHandler::GetLevelFuncsMember(sol::table tab, std::string const& luaName) { std::string partName = tab.raw_get(strKey); auto & theMap = m_levelFuncs_tablesOfNames[partName]; @@ -199,68 +179,67 @@ sol::object LogicHandler::GetLevelFunc(sol::table tab, std::string const& luaNam return sol::nil; } -void LogicHandler::CallLevelFunc(std::string name, float dt) +void LogicHandler::CallLevelFunc(std::string const & name, float dt) { sol::protected_function f = m_levelFuncs_luaFunctions[name]; f.call(dt); } -void LogicHandler::CallLevelFunc(std::string name, sol::variadic_args va) +void LogicHandler::CallLevelFunc(std::string const & name, sol::variadic_args va) { sol::protected_function f = m_levelFuncs_luaFunctions[name]; f.call(va); } -bool LogicHandler::SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value) +bool LogicHandler::SetLevelFuncsMember(sol::table tab, std::string const& luaName, sol::object value) { - std::string fullName; - std::unordered_map newNameTab; - sol::table newLevelFuncsTab; - sol::table meta; - LevelFunc levelFuncObject; - std::string partName; - switch (value.get_type()) + if (sol::type::lua_nil == value.get_type()) { - case sol::type::lua_nil: + std::string error{ "Tried to set LevelFuncs member " }; + error += luaName + " to nil; this not permitted at this time."; + return ScriptAssert(false, error); + //todo should we handle this? - case sol::type::function: + } + else if (sol::type::function == value.get_type()) { - partName = tab.raw_get(strKey); - fullName = partName + "." + luaName; - auto & parentNameTab = m_levelFuncs_tablesOfNames[partName]; + // Add the name to the table of names + auto partName = tab.raw_get(strKey); + auto fullName = partName + "." + luaName; + auto& parentNameTab = m_levelFuncs_tablesOfNames[partName]; parentNameTab.insert_or_assign(luaName, fullName); - m_levelFuncs_luaFunctions[fullName] = value; - + // Create a LevelFunc userdata and add that too + LevelFunc levelFuncObject; levelFuncObject.m_funcName = fullName; levelFuncObject.m_handler = this; - m_levelFuncs_levelFuncObjects[fullName] = levelFuncObject; + + // Add the function itself + m_levelFuncs_luaFunctions[fullName] = value; } - break; - case sol::type::table: + else if (sol::type::table == value.get_type()) { - fullName = tab.raw_get(strKey) + "." + luaName; - m_levelFuncs_tablesOfNames.insert_or_assign(fullName, newNameTab); + // Create and add a new name map + std::unordered_map newNameMap; + auto fullName = tab.raw_get(strKey) + "." + luaName; + m_levelFuncs_tablesOfNames.insert_or_assign(fullName, newNameMap); - auto& parentNameTab = m_levelFuncs_tablesOfNames[partName]; - partName = tab.raw_get(strKey); - parentNameTab = m_levelFuncs_tablesOfNames[partName]; - parentNameTab.insert_or_assign(luaName, fullName); - - newLevelFuncsTab = MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + // Create a new table to put in the LevelFuncs hierarchy + auto newLevelFuncsTab = MakeSpecialTable(m_handler.GetState(), luaName, &LogicHandler::GetLevelFuncsMember, &LogicHandler::SetLevelFuncsMember, this); newLevelFuncsTab.raw_set(strKey, fullName); tab.raw_set(luaName, newLevelFuncsTab); + // "populate" the new table. This will trigger the __newindex metafunction and will + // thus call this function recursively, handling all subtables and functions. for (auto& [key, val] : value.as()) { newLevelFuncsTab[key] = val; } } - break; - default: + else{ std::string error{ "Failed to add " }; - error += luaName + " to LevelFuncs or one of its tables; it must be a function, a table of functions, or nil."; + error += luaName + " to LevelFuncs or one of its tables; it must be a function or a table of functions."; return ScriptAssert(false, error); } return true; @@ -308,11 +287,11 @@ void LogicHandler::FreeLevelScripts() { //m_levelFuncs.clear(); //m_levelFuncs = - m_levelFuncs = MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFunc, &LogicHandler::SetLevelFunc, this); + m_levelFuncs = MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFuncsMember, &LogicHandler::SetLevelFuncsMember, this); m_levelFuncs.raw_set(strKey, ScriptReserved_LevelFuncs); m_levelFuncs_tablesOfNames.clear(); - m_levelFuncs_luaFunctions = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncs_luaFunctions.clear(); m_levelFuncs_levelFuncObjects = sol::table{ *(m_handler.GetState()), sol::create }; m_levelFuncs_tablesOfNames.emplace(std::make_pair(ScriptReserved_LevelFuncs, std::unordered_map{})); @@ -809,14 +788,6 @@ void LogicHandler::InitCallbacks() func = m_levelFuncs_luaFunctions[fnh.m_funcName]; - if(func.get_type() == sol::type::function) - { - TENLog("function"); - } - if(func.get_type() == sol::type::userdata) - { - TENLog("userdata"); - } if (!ScriptAssert(func.valid(), err)) { ScriptWarn("Defaulting to no " + fullName + " behaviour."); } diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 61721b22a..a927d9b88 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -31,9 +31,10 @@ private: sol::table m_levelFuncs{}; // Maps full function paths into Lua functions. - sol::table m_levelFuncs_luaFunctions{}; + std::unordered_map m_levelFuncs_luaFunctions{}; // Maps full function paths to LevelFunc objects. + // This is a table instead of a C++ container to more easily interface with Sol. sol::table m_levelFuncs_levelFuncObjects{}; // Contains tables; each table refers to a table in the LevelFuncs hierarchy, and contains the full names @@ -62,20 +63,20 @@ private: public: LogicHandler(sol::state* lua, sol::table & parent); - void CallLevelFunc(std::string, sol::variadic_args); - void CallLevelFunc(std::string, float dt); + void CallLevelFunc(std::string const &, sol::variadic_args); + void CallLevelFunc(std::string const &, float dt); void FreeLevelScripts() override; void LogPrint(sol::variadic_args va); - bool SetLevelFunc(sol::table tab, std::string const& luaName, sol::object value); + bool SetLevelFuncsMember(sol::table tab, std::string const& luaName, sol::object value); - void AddCallback(CallbackPoint point, LevelFunc & holder); - void RemoveCallback(CallbackPoint point, std::string const & name); + void AddCallback(CallbackPoint point, LevelFunc const & lf); + void RemoveCallback(CallbackPoint point, LevelFunc const & lf); void ResetScripts(bool clearGameVars) override; - sol::object GetLevelFunc(sol::table tab, std::string const& luaName); + sol::object GetLevelFuncsMember(sol::table tab, std::string const& luaName); void ExecuteScriptFile(const std::string& luaFilename) override; void ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer, std::string const& arguments) override; From cb89daaac77642cc1978daa975ef51735d0ded8e Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 1 Sep 2022 21:32:25 +0100 Subject: [PATCH 055/106] Fix comment --- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index d8f7dcc39..77e5710da 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -136,7 +136,7 @@ Will have no effect if the function was not registered as a callback @function RemoveCallback @tparam point CallbackPoint The callback point the function was registered with. See @{AddCallback} -@tparam func string The LevelFuncs function to remove. +@tparam func LevelFunc the function to remove; must be in the LevelFuncs hierarchy. @usage TEN.Logic.RemoveCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc") */ From ee5f4602d8869f9ea3d55b7e2217d21b44aeb3e9 Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 1 Sep 2022 21:35:40 +0100 Subject: [PATCH 056/106] Fix more comments --- .../Internal/TEN/Logic/LogicHandler.cpp | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 77e5710da..e45258419 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -108,11 +108,11 @@ Possible values for CallbackPoint: The order in which two functions with the same CallbackPoint are called is undefined. i.e. if you register `MyFunc` and `MyFunc2` with `PRECONTROLPHASE`, both will be called before `OnControlPhase`, but there is no guarantee whether `MyFunc` will be called before `MyFunc2`, or vice-versa. - +Any returned value will be discarded. @function AddCallback @tparam point CallbackPoint When should the callback be called? -@tparam LevelFunc The function to be called (must be in the LevelFuncs hierarchy). Will receive as an argument the time in seconds since the last frame. +@tparam LevelFunc The function to be called (must be in the LevelFuncs hierarchy). Will receive, as an argument, the time in seconds since the last frame. @usage LevelFuncs.MyFunc = function(dt) print(dt) end TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, LevelFuncs.MyFunc) @@ -157,10 +157,6 @@ void LogicHandler::RemoveCallback(CallbackPoint point, LevelFunc const & lf) static constexpr char const* strKey = "__internal_name"; void LogicHandler::ResetLevelTables() { - //todo does levelFuncs get cleared normally, pre-these changes? - //NO. the TABLE gets reset but m_levelFuncs does NOT get reset - - MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelVars, &GetVariable, &SetVariable); } @@ -198,8 +194,6 @@ bool LogicHandler::SetLevelFuncsMember(sol::table tab, std::string const& luaNam std::string error{ "Tried to set LevelFuncs member " }; error += luaName + " to nil; this not permitted at this time."; return ScriptAssert(false, error); - - //todo should we handle this? } else if (sol::type::function == value.get_type()) { @@ -262,10 +256,6 @@ void LogicHandler::ResetScripts(bool clearGameVars) { FreeLevelScripts(); - //todo are these getting called? - //load level. walk to trigger that adds here - //save and reload - m_callbacksPreControl.clear(); m_callbacksPostControl.clear(); @@ -659,15 +649,13 @@ void LogicHandler::OnLoad() void LogicHandler::OnControlPhase(float dt) { - //todo write that returned values will get ignored auto tryCall = [this, dt](std::string const& name) { auto func = m_handler.GetState()->script("return " + name); - //todo fail if this is nil if (!func.valid()) ScriptAssertF(false, "Callback {} not valid", name); - else //todo this is a FuncNameHolder, not a function, so ye + else func.get().CallDT(dt); }; From c73366c0eeb90c7cc87a3f1780f220cd7297fee2 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 2 Sep 2022 16:41:52 +0100 Subject: [PATCH 057/106] Fixz typo --- TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h b/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h index 872adfb79..917ce4575 100644 --- a/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h +++ b/TombEngine/Scripting/Include/Flow/ScriptInterfaceFlowHandler.h @@ -32,7 +32,7 @@ public: virtual bool HasOverhangClimb() const = 0; virtual bool HasSlideExtended() const = 0; virtual ScriptInterfaceLevel * GetLevel(int level) = 0; - virtual int GetLevelNumber(std::string const& flieName) = 0; + virtual int GetLevelNumber(std::string const& fileName) = 0; virtual bool CanPlayAnyLevel() const = 0; virtual bool DoFlow() = 0; }; From 04e8e62480029abe7489f0cea0176b10fb27e192 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 2 Sep 2022 21:11:13 +0100 Subject: [PATCH 058/106] Don't "clean globals" when creating a new LuaHandler. Create the Logic table/object last. Seems to fix some weird crashes. --- TombEngine/Scripting/Internal/LuaHandler.cpp | 1 - TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp | 3 --- .../Scripting/Internal/TEN/Logic/LogicHandler.cpp | 4 +--- TombEngine/Specific/winmain.cpp | 10 ++++++++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/TombEngine/Scripting/Internal/LuaHandler.cpp b/TombEngine/Scripting/Internal/LuaHandler.cpp index 6b5b73aba..208d710fa 100644 --- a/TombEngine/Scripting/Internal/LuaHandler.cpp +++ b/TombEngine/Scripting/Internal/LuaHandler.cpp @@ -4,7 +4,6 @@ LuaHandler::LuaHandler(sol::state* lua) : m_lua{ lua } { - ResetGlobals(); } void LuaHandler::ResetGlobals() diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index 3ad18239c..0bb4e7d67 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -115,9 +115,6 @@ Specify which translations in the strings table correspond to which languages. Settings::Register(table_flow); Fog::Register(table_flow); - //todo find out why this can't be in logic - LevelFunc::Register(parent); - m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_WeatherType, kWeatherTypes); m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_LaraType, kLaraTypes); m_handler.MakeReadOnlyTable(table_flow, ScriptReserved_InvItem, kInventorySlots); diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index e45258419..60514f466 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -88,9 +88,7 @@ LogicHandler::LogicHandler(sol::state* lua, sol::table & parent) : m_handler{ lu m_handler.MakeReadOnlyTable(table_logic, ScriptReserved_CallbackPoint, kCallbackPoints); - //it crashes when here - // todo fix? - //FuncNameHolder::Register(table_logic); + LevelFunc::Register(table_logic); ResetScripts(true); } diff --git a/TombEngine/Specific/winmain.cpp b/TombEngine/Specific/winmain.cpp index 5e3ff1d48..6f2de8410 100644 --- a/TombEngine/Specific/winmain.cpp +++ b/TombEngine/Specific/winmain.cpp @@ -281,12 +281,18 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine // Initialise scripting try { - // TODO: make sure the right objects are deleted at the end g_GameFlow = ScriptInterfaceState::CreateFlow(); g_GameFlow->LoadFlowScript(); - g_GameScript = ScriptInterfaceState::CreateGame(); g_GameScriptEntities = ScriptInterfaceState::CreateObjectsHandler(); g_GameStringsHandler = ScriptInterfaceState::CreateStringsHandler(); + + // This must be loaded last as it adds metafunctions to the global + // table so that every global variable added henceforth gets put + // into a special hidden table which we can clean up. + // By doing this last, we ensure that all built-in usertypes + // are added to a hierarchy in the REAL global table, not the fake + // hidden one. + g_GameScript = ScriptInterfaceState::CreateGame(); } catch (TENScriptException const& e) { From 2bb64d544d054013fdd2e117ddca4ae9013e724e Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 2 Sep 2022 21:32:51 +0100 Subject: [PATCH 059/106] Rename FuncNameHolder.h -> LevelFunc.h. --- .../Internal/TEN/Logic/{FuncNameHolder.h => LevelFunc.h} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename TombEngine/Scripting/Internal/TEN/Logic/{FuncNameHolder.h => LevelFunc.h} (100%) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h b/TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h similarity index 100% rename from TombEngine/Scripting/Internal/TEN/Logic/FuncNameHolder.h rename to TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h From 5d9c69244945a271b2df6ff2ba738d923899a0b0 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 2 Sep 2022 21:49:29 +0100 Subject: [PATCH 060/106] Make missing LevelFuncs callback message a plain message rather than an error. --- .../Internal/TEN/Logic/LogicHandler.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 60514f466..0d8550542 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -9,7 +9,8 @@ #include "ScriptUtil.h" #include "Objects/Moveable/MoveableObject.h" #include "Vec3/Vec3.h" -#include "FuncNameHolder.h" +#include "LevelFunc.h" + using namespace TEN::Effects::Lightning; /*** @@ -765,17 +766,21 @@ void LogicHandler::InitCallbacks() sol::object theData = (*m_handler.GetState())["LevelFuncs"][luaFunc]; - std::string err{ "Level's script does not define callback " + fullName}; - if (!ScriptAssert(theData.valid(), err)) { - ScriptWarn("Defaulting to no " + fullName + " behaviour."); + std::string msg{ "Level's script does not define callback " + fullName + + ". Defaulting to no " + fullName + " behaviour."}; + + if(!theData.valid()) + { + TENLog(msg); return; } + LevelFunc fnh = (*m_handler.GetState())["LevelFuncs"][luaFunc]; func = m_levelFuncs_luaFunctions[fnh.m_funcName]; - if (!ScriptAssert(func.valid(), err)) { - ScriptWarn("Defaulting to no " + fullName + " behaviour."); + if (!func.valid()) { + TENLog(msg); } }; From f145c5dec52b8c9ea63736eceec09df11c0c5113 Mon Sep 17 00:00:00 2001 From: hispidence Date: Fri, 2 Sep 2022 21:51:28 +0100 Subject: [PATCH 061/106] Add LevelFunc file to project. --- TombEngine/TombEngine.vcxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj index 49676eb5a..e55ba18d9 100644 --- a/TombEngine/TombEngine.vcxproj +++ b/TombEngine/TombEngine.vcxproj @@ -234,7 +234,7 @@ CALL gen.bat - + From 12a43c5fe2d467ae8eba563874f53c59a7a9abc9 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sat, 3 Sep 2022 12:46:35 +1000 Subject: [PATCH 062/106] Demagic tr2 silencer probabilities --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 12 ++++----- .../Objects/TR2/Entity/tr2_silencer.cpp | 27 ++++++++++++------- 2 files changed, 23 insertions(+), 16 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index baa2cf01d..da31a49a3 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -31,7 +31,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto APE_RUN_POUND_GROUND_CHANCE = 0.015f; constexpr auto APE_RUN_RUN_LEFT_CHANCE = 0.02f; - constexpr auto SHIFT = 75; + constexpr auto APE_SHIFT = 75; #define APE_RUN_TURN_RATE_MAX ANGLE(5.0f) #define APE_DISPLAY_ANGLE ANGLE(45.0f) @@ -122,12 +122,12 @@ namespace TEN::Entities::Creatures::TR1 if (yy < yFloor) { - item->Pose.Position.x = (yFloor * SECTOR(1)) - SHIFT; + item->Pose.Position.x = (yFloor * SECTOR(1)) - APE_SHIFT; item->Pose.Orientation.y = ANGLE(90.0f); } else { - item->Pose.Position.x = (yy * SECTOR(1)) + SHIFT; + item->Pose.Position.x = (yy * SECTOR(1)) + APE_SHIFT; item->Pose.Orientation.y = -ANGLE(90.0f); } } @@ -135,12 +135,12 @@ namespace TEN::Entities::Creatures::TR1 { if (xx < xFloor) { - item->Pose.Position.z = (xFloor * SECTOR(1)) - SHIFT; + item->Pose.Position.z = (xFloor * SECTOR(1)) - APE_SHIFT; item->Pose.Orientation.y = 0; } else { - item->Pose.Position.z = (xx * SECTOR(1)) + SHIFT; + item->Pose.Position.z = (xx * SECTOR(1)) + APE_SHIFT; item->Pose.Orientation.y = -ANGLE(180.0f); } } @@ -149,7 +149,7 @@ namespace TEN::Entities::Creatures::TR1 // diagonal } - if (CreatureVault(itemNumber, angle, 2, SHIFT) == 2) + if (CreatureVault(itemNumber, angle, 2, APE_SHIFT) == 2) { item->Pose.Position.y = y; SetAnimation(item, APE_ANIM_VAULT); diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index 442333b9f..39b34afdc 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -8,8 +8,11 @@ #include "Game/misc.h" #include "Game/people.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; + namespace TEN::Entities::Creatures::TR2 { const auto SilencerGunBite = BiteInfo(Vector3(3.0f, 331.0f, 56.0f), 10); @@ -36,13 +39,16 @@ namespace TEN::Entities::Creatures::TR2 short angle = 0; short tilt = 0; - Vector3Shrt extraHeadRot = Vector3Shrt::Zero; - Vector3Shrt extraTorsoRot = Vector3Shrt::Zero; + auto extraHeadRot = Vector3Shrt::Zero; + auto extraTorsoRot = Vector3Shrt::Zero; if (item->HitPoints <= 0) { - if (item->Animation.ActiveState != 12 && item->Animation.ActiveState != 13) + if (item->Animation.ActiveState != 12 && + item->Animation.ActiveState != 13) + { SetAnimation(item, 20); + } } else { @@ -83,7 +89,7 @@ namespace TEN::Entities::Creatures::TR2 if (Targetable(item, &AI)) { item->Animation.TargetState = 3; - item->Animation.RequiredState = (GetRandomControl() >= 0x4000 ? 10 : 6); + item->Animation.RequiredState = TestProbability(0.5f) ? 6 : 10; } if (creature->Mood == MoodType::Attack || !AI.ahead) @@ -101,9 +107,9 @@ namespace TEN::Entities::Creatures::TR2 } else { - if (GetRandomControl() >= 1280) + if (TestProbability(0.96f)) { - if (GetRandomControl() < 2560) + if (TestProbability(0.08f)) { item->Animation.TargetState = 3; item->Animation.RequiredState = 1; @@ -130,13 +136,13 @@ namespace TEN::Entities::Creatures::TR2 else if (Targetable(item, &AI)) { item->Animation.TargetState = 3; - item->Animation.RequiredState = (GetRandomControl() >= 0x4000 ? 10 : 6); + item->Animation.RequiredState = TestProbability(0.5f) ? 6 : 10; } else { if (AI.distance > pow(SECTOR(2), 2) || !AI.ahead) item->Animation.TargetState = 2; - if (creature->Mood == MoodType::Bored && GetRandomControl() < 0x300) + if (creature->Mood == MoodType::Bored && TestProbability(0.025f)) item->Animation.TargetState = 3; } @@ -167,7 +173,7 @@ namespace TEN::Entities::Creatures::TR2 break; } else if (creature->Mood == MoodType::Attack) - item->Animation.TargetState = (GetRandomControl() >= 0x4000) ? 3 : 2; + item->Animation.TargetState = TestProbability(0.5f) ? 2 : 3; else item->Animation.TargetState = 3; @@ -186,8 +192,9 @@ namespace TEN::Entities::Creatures::TR2 } else { - if (creature->Mood == MoodType::Attack || GetRandomControl() < 0x100) + if (creature->Mood == MoodType::Attack || TestProbability(0.008f)) item->Animation.TargetState = 3; + if (!AI.ahead) item->Animation.TargetState = 3; } From 0a8a2ec5bae0d536233f11e6f4d60b823c825ca1 Mon Sep 17 00:00:00 2001 From: hispidence Date: Sat, 3 Sep 2022 12:25:05 +0100 Subject: [PATCH 063/106] Move "first-party" scripts into TEN folder. --- Documentation/config.ld | 2 +- Scripts/{ => TEN}/EventSequence.lua | 0 Scripts/{ => TEN}/Timer.lua | 0 Scripts/{ => TEN}/Util.lua | 0 Scripts/TestLevel.lua | 2 +- Scripts/Title.lua | 6 +++--- 6 files changed, 5 insertions(+), 5 deletions(-) rename Scripts/{ => TEN}/EventSequence.lua (100%) rename Scripts/{ => TEN}/Timer.lua (100%) rename Scripts/{ => TEN}/Util.lua (100%) diff --git a/Documentation/config.ld b/Documentation/config.ld index 903bc8e9e..7da4273b6 100644 --- a/Documentation/config.ld +++ b/Documentation/config.ld @@ -24,7 +24,7 @@ Other than the "special tables" (GameVars, LevelVars and LevelFuncs), every modu For example, to call GetMoveableByName, you would have to do: local door = TEN.Objects.GetMoveableByName("door_type4_14") To save on typing, you can put the following at the start of a Lua file: - local Util = require("Util") + local Util = require("TEN.Util") Util.ShortenTENCalls() This will put the modules and classes in the global table. In other words, it means you can do the following: local door = GetMoveableByName("door_type4_14") diff --git a/Scripts/EventSequence.lua b/Scripts/TEN/EventSequence.lua similarity index 100% rename from Scripts/EventSequence.lua rename to Scripts/TEN/EventSequence.lua diff --git a/Scripts/Timer.lua b/Scripts/TEN/Timer.lua similarity index 100% rename from Scripts/Timer.lua rename to Scripts/TEN/Timer.lua diff --git a/Scripts/Util.lua b/Scripts/TEN/Util.lua similarity index 100% rename from Scripts/Util.lua rename to Scripts/TEN/Util.lua diff --git a/Scripts/TestLevel.lua b/Scripts/TestLevel.lua index 96377870c..97cc77026 100644 --- a/Scripts/TestLevel.lua +++ b/Scripts/TestLevel.lua @@ -1,6 +1,6 @@ -- Test level script file -local Util = require("Util") +local Util = require("TEN.Util") Util.ShortenTENCalls() -- Called when entering a level, not called when loading from a save diff --git a/Scripts/Title.lua b/Scripts/Title.lua index 7f448b583..29d567b19 100644 --- a/Scripts/Title.lua +++ b/Scripts/Title.lua @@ -1,10 +1,10 @@ -- Title script file -local Util = require("Util") +local Util = require("TEN.Util") Util.ShortenTENCalls() LevelFuncs.OnLoad = function() end LevelFuncs.OnSave = function() end LevelFuncs.OnEnd = function() end - -LevelFuncs.OnControlPhase = function() end \ No newline at end of file +LevelFuncs.OnStart = function() end +LevelFuncs.OnControlPhase = function(dt) end From d4138040de2d07caa9c20dd2117661719c9389f1 Mon Sep 17 00:00:00 2001 From: hispidence Date: Sat, 3 Sep 2022 13:32:49 +0100 Subject: [PATCH 064/106] Fix include --- TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index 0bb4e7d67..12abbcf26 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -8,7 +8,7 @@ #include "Flow/InventoryItem/InventoryItem.h" #include "InventorySlots.h" #include "Game/gui.h" -#include "Logic/FuncNameHolder.h" +#include "Logic/LevelFunc.h" #include "Vec3/Vec3.h" #include "Objects/ScriptInterfaceObjectsHandler.h" #include "Strings/ScriptInterfaceStringsHandler.h" From 817c67bac42b97a93d8db9c335990832aa2441cf Mon Sep 17 00:00:00 2001 From: Sezz Date: Sat, 3 Sep 2022 23:09:12 +1000 Subject: [PATCH 065/106] Demagic tr2_silencer.cpp; demagic some probabilities; cleanup --- .../Objects/TR2/Entity/tr2_barracuda.cpp | 2 +- .../Objects/TR2/Entity/tr2_bird_monster.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_dragon.cpp | 2 +- .../Objects/TR2/Entity/tr2_knife_thrower.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_rat.cpp | 2 +- .../Objects/TR2/Entity/tr2_silencer.cpp | 158 +++++++++++------- TombEngine/Objects/TR2/Entity/tr2_skidman.cpp | 2 +- .../Objects/TR2/Entity/tr2_spear_guardian.cpp | 32 ++-- TombEngine/Objects/TR2/Entity/tr2_spider.cpp | 8 +- .../Objects/TR2/Entity/tr2_sword_guardian.cpp | 18 +- TombEngine/Objects/TR3/Entity/tr3_civvy.cpp | 1 - TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 1 - .../Objects/TR3/Entity/tr3_mp_stick.cpp | 1 - .../Objects/TR3/Entity/tr3_scuba_diver.cpp | 1 - TombEngine/Objects/TR3/Entity/tr3_trex.cpp | 1 - .../Objects/TR3/Entity/tr3_tribesman.cpp | 1 - TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_baboon.cpp | 3 +- TombEngine/Objects/TR4/Entity/tr4_bat.cpp | 2 +- .../Objects/TR4/Entity/tr4_big_beetle.cpp | 2 +- .../Objects/TR4/Entity/tr4_big_scorpion.cpp | 2 +- 21 files changed, 139 insertions(+), 106 deletions(-) diff --git a/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp b/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp index 68e717b09..99b759bbf 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_barracuda.cpp @@ -23,7 +23,7 @@ namespace TEN::Entities::Creatures::TR2 enum BarracudaState { - BARRACUDA_STATE_NONE = 0, + // No state 0. BARRACUDA_STATE_IDLE = 1, BARRACUDA_STATE_SWIM_SLOW = 2, BARRACUDA_STATE_SWIM_FAST = 3, diff --git a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp index a71985072..7c98cdb70 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_bird_monster.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::Creatures::TR2 enum BirdMonsterState { - BMONSTER_STATE_NONE = 0, + // No state 0. BMONSTER_STATE_IDLE = 1, BMONSTER_STATE_WALK_FORWARD = 2, BMONSTER_STATE_SLAM_ATTACK_START = 3, diff --git a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp index 2ab45bf54..129af7a09 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp @@ -53,7 +53,7 @@ namespace TEN::Entities::Creatures::TR2 enum DragonState { - DRAGON_STATE_NONE = 0, + // No state 0. DRAGON_STATE_WALK = 1, DRAGON_STATE_LEFT = 2, DRAGON_STATE_RIGHT = 3, diff --git a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp index de1b22b40..24867691e 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::Creatures::TR2 enum KnifeThrowerState { - KTHROWER_STATE_NONE = 0, + // No state 0. KTHROWER_STATE_IDLE = 1, KTHROWER_STATE_WALK_FORWARD = 2, KTHROWER_STATE_RUN_FORWARD = 3, diff --git a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp index a636344e6..8f9843212 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_rat.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_rat.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::Creatures::TR2 enum RatState { - RAT_STATE_NONE = 0, + // No state 0. RAT_STATE_WALK_FORWARD = 1, RAT_STATE_IDLE = 2, RAT_STATE_SQUEAK = 3, diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index 39b34afdc..198914ae2 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -15,18 +15,63 @@ using namespace TEN::Math::Random; namespace TEN::Entities::Creatures::TR2 { + constexpr auto SILENCER_SHOT_DAMAGE = 50; + constexpr auto SILENCER_RUN_RANGE = SQUARE(SECTOR(2)); + const auto SilencerGunBite = BiteInfo(Vector3(3.0f, 331.0f, 56.0f), 10); - // TODO + #define SILENCER_WALK_TURN_RATE_MAX ANGLE(5.0f) + #define SILENCER_RUN_TURN_RATE_MAX ANGLE(5.0f) + enum SilencerState { - + // No state 0. + SILENCER_STATE_WALK_FORWARD = 1, + SILENCER_STATE_RUN_FORWARD = 2, + SILENCER_STATE_IDLE_FRAME = 3, + SILENCER_STATE_IDLE = 4, + SILENCER_STATE_POSE = 5, + SILENCER_STATE_AIM_1 = 6, + SILENCER_STATE_SHOOT_1 = 7, + // No state 8. + SILENCER_STATE_RUN_SHOOT = 9, + SILENCER_STATE_AIM_2 = 10, + SILENCER_STATE_SHOOT_2 = 11, + SILENCER_STATE_DEATH_1 = 12, + SILENCER_STATE_DEATH_2 = 13 }; - // TODO enum SilencerAnim { - + SILENCER_ANIM_IDLE_FRAME = 0, + SILENCER_ANIM_IDLE_TO_WALK_FORWARD = 1, + SILENCER_ANIM_WALK_FORWARD = 2, + SILENCER_ANIM_WALK_FORWARD_TO_IDLE = 3, + SILENCER_ANIM_WALK_FORWARD_TO_POSE = 4, + SILENCER_ANIM_POSE = 5, + SILENCER_ANIM_WALK_FORWARD_TO_RUN_FORWARD = 6, + SILENCER_ANIM_RUN_FORWARD = 7, + SILENCER_ANIM_RUN_FORWARD_TO_IDLE = 8, + SILENCER_ANIM_IDLE_TO_RUN_FORWARD = 9, + SILENCER_ANIM_POSE_TO_IDLE = 10, + SILENCER_ANIM_RUN_FORWARD_AIM_LEFT = 11, + SILENCER_ANIM_RUN_FORWARD_SHOOT_LEFT = 12, + SILENCER_ANIM_RUN_FORWARD_UNAIM_LEFT = 13, + SILENCER_ANIM_AIM_1_START = 14, + SILENCER_ANIM_AIM_1_CONTINUE = 15, + SILENCER_ANIM_SHOOT_1 = 16, + SILENCER_ANIM_UNAIM_1 = 17, + SILENCER_ANIM_POSE_TO_AIM_1 = 18, + SILENCER_ANIM_IDLE = 19, + SILENCER_ANIM_DEATH_1 = 20, + SILENCER_ANIM_DEATH_2 = 21, // Unused. + SILENCER_ANIM_AIM_2_START = 22, + SILENCER_ANIM_AIM_2_CONTINUE = 23, + SILENCER_ANIM_SHOOT_2 = 24, + SILENCER_ANIM_UNAIM_2 = 25, + SILENCER_ANIM_RUN_FORWARD_AIM_RIGHT = 26, + SILENCER_ANIM_RUN_FORWARD_SHOOT_RIGHT = 27, + SILENCER_ANIM_RUN_FORWARD_UNAIM_RIGHT = 28 }; void SilencerControl(short itemNumber) @@ -44,10 +89,10 @@ namespace TEN::Entities::Creatures::TR2 if (item->HitPoints <= 0) { - if (item->Animation.ActiveState != 12 && - item->Animation.ActiveState != 13) + if (item->Animation.ActiveState != SILENCER_STATE_DEATH_1 && + item->Animation.ActiveState != SILENCER_STATE_DEATH_2) { - SetAnimation(item, 20); + SetAnimation(item, SILENCER_ANIM_DEATH_1); } } else @@ -62,7 +107,7 @@ namespace TEN::Entities::Creatures::TR2 switch (item->Animation.ActiveState) { - case 3: + case SILENCER_STATE_IDLE_FRAME: creature->MaxTurn = 0; if (AI.ahead) @@ -73,7 +118,7 @@ namespace TEN::Entities::Creatures::TR2 break; - case 4: + case SILENCER_STATE_IDLE: creature->MaxTurn = 0; if (AI.ahead) @@ -81,28 +126,28 @@ namespace TEN::Entities::Creatures::TR2 if (creature->Mood == MoodType::Escape) { - item->Animation.TargetState = 3; - item->Animation.RequiredState = 2; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = SILENCER_STATE_RUN_FORWARD; } else { if (Targetable(item, &AI)) { - item->Animation.TargetState = 3; - item->Animation.RequiredState = TestProbability(0.5f) ? 6 : 10; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = TestProbability(0.5f) ? SILENCER_STATE_AIM_1 : SILENCER_STATE_AIM_2; } if (creature->Mood == MoodType::Attack || !AI.ahead) { - if (AI.distance >= pow(SECTOR(2), 2)) + if (AI.distance >= SILENCER_RUN_RANGE) { - item->Animation.TargetState = 3; - item->Animation.RequiredState = 2; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = SILENCER_STATE_RUN_FORWARD; } else { - item->Animation.TargetState = 3; - item->Animation.RequiredState = 1; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = SILENCER_STATE_WALK_FORWARD; } } else @@ -111,45 +156,45 @@ namespace TEN::Entities::Creatures::TR2 { if (TestProbability(0.08f)) { - item->Animation.TargetState = 3; - item->Animation.RequiredState = 1; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = SILENCER_STATE_WALK_FORWARD; } } else { - item->Animation.TargetState = 3; - item->Animation.RequiredState = 5; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = SILENCER_STATE_POSE; } } } break; - case 1: + case SILENCER_STATE_WALK_FORWARD: + creature->MaxTurn = SILENCER_WALK_TURN_RATE_MAX; + if (AI.ahead) extraHeadRot.y = AI.angle; - creature->MaxTurn = 910; - if (creature->Mood == MoodType::Escape) - item->Animation.TargetState = 2; + item->Animation.TargetState = SILENCER_STATE_RUN_FORWARD; else if (Targetable(item, &AI)) { - item->Animation.TargetState = 3; - item->Animation.RequiredState = TestProbability(0.5f) ? 6 : 10; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = TestProbability(0.5f) ? SILENCER_STATE_AIM_1 : SILENCER_STATE_AIM_2; } else { - if (AI.distance > pow(SECTOR(2), 2) || !AI.ahead) - item->Animation.TargetState = 2; + if (AI.distance > SILENCER_RUN_RANGE || !AI.ahead) + item->Animation.TargetState = SILENCER_STATE_RUN_FORWARD; if (creature->Mood == MoodType::Bored && TestProbability(0.025f)) - item->Animation.TargetState = 3; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; } break; - case 2: - creature->MaxTurn = ANGLE(5.0f); + case SILENCER_STATE_RUN_FORWARD: + creature->MaxTurn = SILENCER_RUN_TURN_RATE_MAX; creature->Flags = 0; tilt = angle / 4; @@ -159,27 +204,26 @@ namespace TEN::Entities::Creatures::TR2 if (creature->Mood == MoodType::Escape) { if (Targetable(item, &AI)) - item->Animation.TargetState = 9; + item->Animation.TargetState = SILENCER_STATE_RUN_SHOOT; break; - } if (Targetable(item, &AI)) { - if (AI.distance >= pow(SECTOR(2), 2) && AI.zoneNumber == AI.enemyZone) - item->Animation.TargetState = 9; + if (AI.distance >= SILENCER_RUN_RANGE && AI.zoneNumber == AI.enemyZone) + item->Animation.TargetState = SILENCER_STATE_RUN_SHOOT; break; } else if (creature->Mood == MoodType::Attack) - item->Animation.TargetState = TestProbability(0.5f) ? 2 : 3; + item->Animation.TargetState = TestProbability(0.5f) ? SILENCER_STATE_RUN_FORWARD : SILENCER_STATE_IDLE_FRAME; else - item->Animation.TargetState = 3; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; break; - case 5: + case SILENCER_STATE_POSE: creature->MaxTurn = 0; if (AI.ahead) @@ -187,22 +231,22 @@ namespace TEN::Entities::Creatures::TR2 if (Targetable(item, &AI)) { - item->Animation.TargetState = 3; - item->Animation.RequiredState = 6; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; + item->Animation.RequiredState = SILENCER_STATE_AIM_1; } else { if (creature->Mood == MoodType::Attack || TestProbability(0.008f)) - item->Animation.TargetState = 3; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; if (!AI.ahead) - item->Animation.TargetState = 3; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; } break; - case 6: - case 10: + case SILENCER_STATE_AIM_1: + case SILENCER_STATE_AIM_2: creature->MaxTurn = 0; creature->Flags = 0; @@ -215,16 +259,16 @@ namespace TEN::Entities::Creatures::TR2 extraHeadRot.y = AI.angle; if (creature->Mood == MoodType::Escape) - item->Animation.TargetState = 3; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; else if (Targetable(item, &AI)) - item->Animation.TargetState = item->Animation.ActiveState != 6 ? 11 : 7; + item->Animation.TargetState = (item->Animation.ActiveState != SILENCER_STATE_AIM_1) ? SILENCER_STATE_SHOOT_2 : SILENCER_STATE_SHOOT_1; else - item->Animation.TargetState = 3; + item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; break; - case 7: - case 11: + case SILENCER_STATE_SHOOT_1: + case SILENCER_STATE_SHOOT_2: creature->MaxTurn = 0; if (AI.ahead) @@ -237,14 +281,14 @@ namespace TEN::Entities::Creatures::TR2 if (!creature->Flags) { - ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, 50); + ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, SILENCER_SHOT_DAMAGE); creature->Flags = 1; } break; - case 9: - creature->MaxTurn = ANGLE(5.0f); + case SILENCER_STATE_RUN_SHOOT: + creature->MaxTurn = SILENCER_RUN_TURN_RATE_MAX; if (AI.ahead) { @@ -256,10 +300,10 @@ namespace TEN::Entities::Creatures::TR2 if (!item->Animation.RequiredState) { - if (!ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, 50)) - item->Animation.TargetState = 2; + if (!ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, SILENCER_SHOT_DAMAGE)) + item->Animation.TargetState = SILENCER_STATE_RUN_FORWARD; - item->Animation.RequiredState = 9; + item->Animation.RequiredState = SILENCER_STATE_RUN_SHOOT; } break; diff --git a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp index fb0c8b51c..a075d43ec 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_skidman.cpp @@ -28,7 +28,7 @@ namespace TEN::Entities::Creatures::TR2 enum SnowmobileManState { - SMAN_STATE_NONE = 0, + // No state 0. SMAN_STATE_WAIT = 1, SMAN_STATE_MOVING = 2, SMAN_STATE_START_LEFT = 3, diff --git a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp index 32a46fbf1..a425f87ac 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp @@ -10,8 +10,11 @@ #include "Game/misc.h" #include "Sound/sound.h" #include "Specific/level.h" +#include "Specific/prng.h" #include "Specific/setup.h" +using namespace TEN::Math::Random; + namespace TEN::Entities::Creatures::TR2 { const auto SpearBiteLeft = BiteInfo(Vector3(0.0f, 0.0f, 920.0f), 11); @@ -29,7 +32,7 @@ namespace TEN::Entities::Creatures::TR2 }; - static void XianDamage(ItemInfo* item, int damage) + void XianDamage(ItemInfo* item, int damage) { auto* creature = GetCreatureInfo(item); @@ -76,7 +79,7 @@ namespace TEN::Entities::Creatures::TR2 short neck = 0; short tilt = 0; - bool laraAlive = LaraItem->HitPoints > 0; + bool isLaraAlive = LaraItem->HitPoints > 0; if (item->HitPoints <= 0) { @@ -125,10 +128,9 @@ namespace TEN::Entities::Creatures::TR2 if (creature->Mood == MoodType::Bored) { - int random = GetRandomControl(); - if (random < 0x200) + if (TestProbability(0.015f)) item->Animation.TargetState = 2; - else if (random < 0x400) + else if (TestProbability(0.03f)) item->Animation.TargetState = 3; } else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) @@ -148,10 +150,9 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 3; else if (creature->Mood == MoodType::Bored) { - int random = GetRandomControl(); - if (random < 0x200) + if (TestProbability(0.015f)) item->Animation.TargetState = 1; - else if (random < 0x400) + else if (TestProbability(0.03f)) item->Animation.TargetState = 3; } else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) @@ -171,17 +172,16 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 4; else if (creature->Mood == MoodType::Bored) { - int random = GetRandomControl(); - if (random < 0x200) + if (TestProbability(0.015f)) item->Animation.TargetState = 1; - else if (random < 0x400) + else if (TestProbability(0.03f)) item->Animation.TargetState = 2; } else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) { if (AI.distance < pow(SECTOR(1.5f), 2)) item->Animation.TargetState = 7; - else if (GetRandomControl() < 0x4000) + else if (TestProbability(0.5f)) item->Animation.TargetState = 9; else item->Animation.TargetState = 11; @@ -201,7 +201,7 @@ namespace TEN::Entities::Creatures::TR2 break; else if (creature->Mood == MoodType::Bored) { - if (GetRandomControl() < 0x4000) + if (TestProbability(0.5f)) item->Animation.TargetState = 1; else item->Animation.TargetState = 2; @@ -301,7 +301,7 @@ namespace TEN::Entities::Creatures::TR2 if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) { - if (GetRandomControl() < 0x4000) + if (TestProbability(0.5f)) item->Animation.TargetState = 1; else item->Animation.TargetState = 2; @@ -332,7 +332,7 @@ namespace TEN::Entities::Creatures::TR2 if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) { - if (GetRandomControl() < 0x4000) + if (TestProbability(0.5f)) item->Animation.TargetState = 1; else item->Animation.TargetState = 2; @@ -346,7 +346,7 @@ namespace TEN::Entities::Creatures::TR2 } } - if (laraAlive && LaraItem->HitPoints <= 0) + if (isLaraAlive && LaraItem->HitPoints <= 0) { CreatureKill(item, 49, 19, 2); return; diff --git a/TombEngine/Objects/TR2/Entity/tr2_spider.cpp b/TombEngine/Objects/TR2/Entity/tr2_spider.cpp index e7bb5ac5a..6b5a3be87 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spider.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spider.cpp @@ -18,7 +18,7 @@ namespace TEN::Entities::Creatures::TR2 { const auto SpiderBite = BiteInfo(Vector3(0.0f, 0.0f, 41.0f), 1); - static void S_SpiderBite(ItemInfo* item) + void S_SpiderBite(ItemInfo* item) { auto pos = Vector3Int((int)round(SpiderBite.Position.x), (int)round(SpiderBite.Position.y), (int)round(SpiderBite.Position.z)); GetJointAbsPosition(item, &pos, SpiderBite.meshNum); @@ -26,7 +26,7 @@ namespace TEN::Entities::Creatures::TR2 DoBloodSplat(pos.x, pos.y, pos.z, 10, item->Pose.Position.y, item->RoomNumber); } - static void SpiderLeap(short itemNumber, ItemInfo* item, short angle) + void SpiderLeap(short itemNumber, ItemInfo* item, short angle) { auto vec = GameVector( item->Pose.Position.x, @@ -40,9 +40,7 @@ namespace TEN::Entities::Creatures::TR2 if (item->Pose.Position.y > (vec.y - CLICK(1.5f))) return; - item->Pose.Position.x = vec.x; - item->Pose.Position.y = vec.y; - item->Pose.Position.z = vec.z; + item->Pose.Position = Vector3Int(vec.x, vec.y, vec.z); if (item->RoomNumber != vec.roomNumber) ItemNewRoom(item->RoomNumber, vec.roomNumber); diff --git a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp index 699280d38..a0aab17aa 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_sword_guardian.cpp @@ -11,8 +11,11 @@ #include "Game/Lara/lara.h" #include "Game/misc.h" #include "Sound/sound.h" +#include "Specific/prng.h" #include "Specific/level.h" +using namespace TEN::Math::Random; + namespace TEN::Entities::Creatures::TR2 { const auto SwordBite = BiteInfo(Vector3(0.0f, 37.0f, 550.0f), 15); @@ -24,7 +27,7 @@ namespace TEN::Entities::Creatures::TR2 ClearItem(itemNumber); } - static void SwordGuardianFly(ItemInfo* item) + void SwordGuardianFly(ItemInfo* item) { Vector3Int pos; pos.x = (GetRandomControl() * 256 / 32768) + item->Pose.Position.x - 128; @@ -47,7 +50,7 @@ namespace TEN::Entities::Creatures::TR2 short head = 0; short torso = 0; - bool laraAlive = LaraItem->HitPoints > 0; + bool isLaraAlive = LaraItem->HitPoints > 0; if (item->HitPoints <= 0) { @@ -114,15 +117,10 @@ namespace TEN::Entities::Creatures::TR2 if (AI.ahead) head = AI.angle; - if (laraAlive) + if (isLaraAlive) { if (AI.bite && AI.distance < pow(SECTOR(1), 2)) - { - if (GetRandomControl() >= 0x4000) - item->Animation.TargetState = 5; - else - item->Animation.TargetState = 3; - } + item->Animation.TargetState = TestProbability(0.5f) ? 3 : 5; else { if (AI.zoneNumber == AI.enemyZone) @@ -142,7 +140,7 @@ namespace TEN::Entities::Creatures::TR2 if (AI.ahead) head = AI.angle; - if (laraAlive) + if (isLaraAlive) { if (AI.bite && AI.distance < pow(SECTOR(2), 2)) item->Animation.TargetState = 10; diff --git a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp index be9f320fe..9c2f66591 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_civvy.cpp @@ -42,7 +42,6 @@ namespace TEN::Entities::Creatures::TR3 // TODO enum CivvyState { - CIVVY_STATE_NONE, CIVVY_STATE_IDLE, CIVVY_STATE_WALK_FORWARD, CIVVY_PUNCH2, diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index e3e72d317..259cabe70 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -25,7 +25,6 @@ namespace TEN::Entities::Creatures::TR3 enum MPGunState { - MPGUN_STATE_NONE = 0, MPGUN_STATE_WAIT = 1, MPGUN_STATE_WALK = 2, MPGUN_STATE_RUN = 3, diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index 525f60f34..7bedb6242 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -26,7 +26,6 @@ namespace TEN::Entities::Creatures::TR3 enum MPStickState { - MPSTICK_STATE_NONE, MPSTICK_STATE_STOP, MPSTICK_STATE_WALK, MPSTICK_STATE_PUNCH2, diff --git a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp index 095ee262e..c4c7c77d2 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_scuba_diver.cpp @@ -23,7 +23,6 @@ namespace TEN::Entities::Creatures::TR3 enum ScubaDiverState { - SDIVER_STATE_NONE = 0, SDIVER_STATE_SWIM = 1, SDIVER_STATE_TREAD_WATER_IDLE = 2, SDIVER_STATE_SWIM_SHOOT = 3, diff --git a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp index 137deb7af..867ecd344 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_trex.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_trex.cpp @@ -29,7 +29,6 @@ namespace TEN::Entities::Creatures::TR3 enum TRexState { - TREX_STATE_NONE = 0, TREX_STATE_IDLE = 1, TREX_STATE_WALK_FORWARD = 2, TREX_STATE_RUN_FORWARD = 3, diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index 4ff0ae04c..355f78f18 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -47,7 +47,6 @@ namespace TEN::Entities::Creatures::TR3 enum TribesmanState { - TRIBESMAN_STATE_NONE = 0, TRIBESMAN_STATE_CROUCH_IDLE = 1, TRIBESMAN_STATE_WALK_FORWARD = 2, TRIBESMAN_STATE_RUN_FORWARD = 3, diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp index 9851152e8..bb776e024 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp @@ -44,7 +44,7 @@ namespace TEN::Entities::TR4 enum AhmetState { - AHMET_STATE_NONE = 0, + // No state 0. AHMET_STATE_IDLE = 1, AHMET_STATE_WALK_FORWARD = 2, AHMET_STATE_RUN_FORWARD = 3, diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp index b6c3c037b..9232eea13 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp @@ -49,8 +49,7 @@ namespace TEN::Entities::TR4 enum BaboonState { - BABOON_STATE_NULL = 0, - BABOON_STATE_NONE = 1, + // No states 0-1. BABOON_STATE_WALK_FORWARD = 2, BABOON_STATE_IDLE = 3, BABOON_STATE_RUN_FORWARD = 4, diff --git a/TombEngine/Objects/TR4/Entity/tr4_bat.cpp b/TombEngine/Objects/TR4/Entity/tr4_bat.cpp index a7736ea16..916f63312 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_bat.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_bat.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::TR4 enum BatState { - BAT_STATE_NONE = 0, + // No state 0. BAT_STATE_DROP_FROM_CEILING = 1, BAT_STATE_FLY = 2, BAT_STATE_ATTACK = 3, diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp index bf15fe9c9..54113a7fc 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp @@ -28,7 +28,7 @@ namespace TEN::Entities::TR4 enum BigBeetleState { - BBEETLE_STATE_NONE = 0, + // No state 0. BBEETLE_STATE_IDLE = 1, BBEETLE_STATE_TAKE_OFF = 2, BBEETLE_STATE_FLY_FORWARD = 3, diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp index 3827f52db..3d1cef69a 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_scorpion.cpp @@ -35,7 +35,7 @@ namespace TEN::Entities::TR4 enum BigScorpionState { - BSCORPION_STATE_NONE = 0, + // No state 0. BSCORPION_STATE_IDLE = 1, BSCORPION_STATE_WALK_FORWARD = 2, BSCORPION_STATE_RUN_FORWARD = 3, From c3fa1453165462013ce543b06bf7d39a1fbd6b61 Mon Sep 17 00:00:00 2001 From: hispidence Date: Sat, 3 Sep 2022 16:56:21 +0100 Subject: [PATCH 066/106] Update New_Level.lua --- Scripts/New_Level.lua | 4 +- Scripts/TestLevel.lua | 125 ------------------------------------------ 2 files changed, 2 insertions(+), 127 deletions(-) delete mode 100644 Scripts/TestLevel.lua diff --git a/Scripts/New_Level.lua b/Scripts/New_Level.lua index 417714e2e..c4e30aba4 100644 --- a/Scripts/New_Level.lua +++ b/Scripts/New_Level.lua @@ -1,7 +1,7 @@ -- New level script file. -- To include other script files, you can use require("filename") command. -local Util = require("Util") +local Util = require("TEN.Util") Util.ShortenTENCalls() -- Called when entering a level, either after leveljump, new game or loading game @@ -27,4 +27,4 @@ LevelFuncs.OnEnd = function() end LevelFuncs.PrintText = function(Triggerer, Argument) local TestText = DisplayString(Argument, 100, 100, Color.new(250,250,250)) ShowString(TestText, 1) -end \ No newline at end of file +end diff --git a/Scripts/TestLevel.lua b/Scripts/TestLevel.lua deleted file mode 100644 index 97cc77026..000000000 --- a/Scripts/TestLevel.lua +++ /dev/null @@ -1,125 +0,0 @@ --- Test level script file - -local Util = require("TEN.Util") -Util.ShortenTENCalls() - --- Called when entering a level, not called when loading from a save -LevelFuncs.OnStart = function() end - --- Called only when loading from a save -LevelFuncs.OnLoad = function() end - -LevelFuncs.OnSave = function() end - --- dt stands for "delta time", and holds the time in seconds since the last call to OnControlPhase -LevelFuncs.OnControlPhase = function(dt) end - -LevelFuncs.OnEnd = function() end - --- An example function which prints a string and leaves it on screen for 1 second. --- Argument should be typed in TE trigger manager window's argument text field. - -LevelFuncs.PrintText = function(Triggerer, Argument) - local TestText = DisplayString(Argument, 100, 100, Color.new(250,250,250)) - ShowString(TestText, 1) -end - - --- Another example function which emits rotating electric halo around object, --- which triggered it. - -local currentX = 0.0 -local currentY = 0.0 - -LevelFuncs.EmitHaloOnActionPush = function(Triggerer) - - -- This is a list of all possible keys which can be checked for their pushed/not pushed state. - -- Later we will move them to separate internal file or make them internal TEN constants. - - local Keys = - { - Forward = 0, - Back = 1, - Left = 2, - Right = 3, - Crouch = 4, - Sprint = 5, - Walk = 6, - Jump = 7, - Action = 8, - Draw = 9, - Flare = 10, - Look = 11, - Roll = 12, - Inventory = 13, - Pause = 14, - StepLeft = 15, - StepRight = 16 - } - - -- First argument which is passed to function that is triggered from TE volumes is - -- always an object which triggered it (except cases when triggerer is static mesh or - -- flyby camera). We can directly use Triggerer argument to get some properties from - -- it. In this case, we get position of a root joint (in case of Lara, it is her hips). - - local pos = Triggerer:GetJointPosition(0) - - -- math.random() is an internal Lua method which returns a value between 2 specified limits, - -- in our case something between 200 and 255. We use it to vary halo intensity a bit. - - local color = math.random(200, 255) - - local velocity = Vec3(0, 0, 0) -- No velocity - - -- Again, we can use velocity to get some value between 60 and 80 to vary rotation rate of - -- a spawned halo particle. - - local rot = math.random(60, 80) - - -- circleLength is standard mathematical constant for circle length which is later used to - -- get sin/cos value to rotate light and particle around an object. - - local circleLength = 3.14 * 2.0 - - -- Progress currentX and currentY variables to change current X and Y positions of the halo. - - currentX = currentX + 0.2 - currentY = currentY + 0.1 - - -- Here we clamp currentX and currentY values to max circle length, because sin/cos operations - -- can't operate out of circle length range. - - if (currentX > circleLength) then - currentX = currentX - circleLength; - end - - if (currentY > circleLength) then - currentY = currentY - circleLength; - end - - local horizontalAmplitude = 384 -- 3 clicks height, where effect wanders about. - local haloRotationDistance = 256 -- rotate on distance 2 clicks around object. - - -- Calculate relative offset of a halo using simple sin/cos functions. - - local offsetX = math.cos(currentX) * haloRotationDistance - local offsetZ = math.sin(currentX) * haloRotationDistance - - local offsetY = math.sin(currentY) * horizontalAmplitude - - -- Add relative offsets to joint position. - - pos.x = pos.x + offsetX - pos.y = pos.y + offsetY - pos.z = pos.z + offsetZ - - -- Play electrical sound. - - Misc.PlaySound(197, pos) - - -- Emit particle and light. Look into manual for list of arguments. - - Effects.EmitParticle(pos, velocity, 2, 1, rot, Color.new(color * 0.5, color * 0.5, color), Color.new(color * 0.2, color * 0.1, color), 2, 16, 64, 1, false, false) - Effects.EmitLight(pos, Color.new(color * 0.5, color * 0.5, color), 7) - -end From 8abd35327d5926192e146515fb6aeb8e823d41f9 Mon Sep 17 00:00:00 2001 From: Sezz Date: Sun, 4 Sep 2022 20:23:02 +1000 Subject: [PATCH 067/106] Cleanup --- TombEngine/Game/people.cpp | 30 ++++----- .../Objects/TR2/Entity/tr2_silencer.cpp | 6 +- TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 53 +++++++-------- .../Objects/TR3/Entity/tr3_mp_stick.cpp | 67 +++++++++---------- .../Objects/TR4/Entity/tr4_hammerhead.cpp | 3 +- .../Objects/TR4/Entity/tr4_knight_templar.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_setha.cpp | 22 ++---- .../Objects/TR4/Entity/tr4_small_scorpion.cpp | 13 ++-- .../Objects/TR4/Entity/tr4_wild_boar.cpp | 17 ++--- 9 files changed, 91 insertions(+), 122 deletions(-) diff --git a/TombEngine/Game/people.cpp b/TombEngine/Game/people.cpp index 688ca2fc5..e4b3805d7 100644 --- a/TombEngine/Game/people.cpp +++ b/TombEngine/Game/people.cpp @@ -17,45 +17,45 @@ bool ShotLara(ItemInfo* item, AI_INFO* AI, BiteInfo gun, short extraRotation, in auto* creature = GetCreatureInfo(item); auto* enemy = creature->Enemy; - bool hit = false; - bool targetable = false; + bool hasHit = false; + bool isTargetable = false; - if (AI->distance <= pow(MAX_VISIBILITY_DISTANCE, 2) && Targetable(item, AI)) + if (AI->distance <= SQUARE(MAX_VISIBILITY_DISTANCE) && Targetable(item, AI)) { int distance = phd_sin(AI->enemyFacing) * enemy->Animation.Velocity.z * pow(MAX_VISIBILITY_DISTANCE, 2) / 300; - distance = pow(distance, 2) + AI->distance; - if (distance <= pow(MAX_VISIBILITY_DISTANCE, 2)) + distance = SQUARE(distance) + AI->distance; + if (distance <= SQUARE(MAX_VISIBILITY_DISTANCE)) { - int random = (pow(MAX_VISIBILITY_DISTANCE, 2) - AI->distance) / (pow(MAX_VISIBILITY_DISTANCE, 2) / 0x5000) + 8192; - hit = GetRandomControl() < random; + int random = (SQUARE(MAX_VISIBILITY_DISTANCE) - AI->distance) / (SQUARE(MAX_VISIBILITY_DISTANCE) / 0x5000) + 8192; + hasHit = GetRandomControl() < random; } else - hit = false; + hasHit = false; - targetable = true; + isTargetable = true; } else { - hit = false; - targetable = false; + hasHit = false; + isTargetable = false; } if (damage) { if (enemy->IsLara()) { - if (hit) + if (hasHit) { DoDamage(enemy, damage); CreatureEffect(item, gun, &GunHit); } - else if (targetable) + else if (isTargetable) CreatureEffect(item, gun, &GunMiss); } else { CreatureEffect(item, gun, &GunShot); - if (hit) + if (hasHit) { enemy->HitStatus = true; enemy->HitPoints += damage / -10; @@ -74,7 +74,7 @@ bool ShotLara(ItemInfo* item, AI_INFO* AI, BiteInfo gun, short extraRotation, in // TODO: smash objects - return targetable; + return isTargetable; } short GunMiss(int x, int y, int z, short velocity, short yRot, short roomNumber) diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index 198914ae2..515b9f59d 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -15,7 +15,7 @@ using namespace TEN::Math::Random; namespace TEN::Entities::Creatures::TR2 { - constexpr auto SILENCER_SHOT_DAMAGE = 50; + constexpr auto SILENCER_SHOOT_ATTACK_DAMAGE = 50; constexpr auto SILENCER_RUN_RANGE = SQUARE(SECTOR(2)); const auto SilencerGunBite = BiteInfo(Vector3(3.0f, 331.0f, 56.0f), 10); @@ -281,7 +281,7 @@ namespace TEN::Entities::Creatures::TR2 if (!creature->Flags) { - ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, SILENCER_SHOT_DAMAGE); + ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, SILENCER_SHOOT_ATTACK_DAMAGE); creature->Flags = 1; } @@ -300,7 +300,7 @@ namespace TEN::Entities::Creatures::TR2 if (!item->Animation.RequiredState) { - if (!ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, SILENCER_SHOT_DAMAGE)) + if (!ShotLara(item, &AI, SilencerGunBite, extraTorsoRot.y, SILENCER_SHOOT_ATTACK_DAMAGE)) item->Animation.TargetState = SILENCER_STATE_RUN_FORWARD; item->Animation.RequiredState = SILENCER_STATE_RUN_SHOOT; diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index 259cabe70..7d944b43f 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -61,11 +61,10 @@ namespace TEN::Entities::Creatures::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; short tilt = 0; - short torsoX = 0; - short torsoY = 0; + short head = 0; + auto extraTorsoRot = Vector3Shrt::Zero; if (creature->FiredWeapon) { @@ -103,8 +102,8 @@ namespace TEN::Entities::Creatures::TR3 AI.angle < ANGLE(45.0f)) { head = AI.angle; - torsoY = AI.angle; - ShotLara(item, &AI, MPGunBite, torsoY, 32); + extraTorsoRot.y = AI.angle; + ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32); SoundEffect(SFX_TR3_OIL_SMG_FIRE, &item->Pose, SoundEnvironment::Land, 1.0f, 0.7f); creature->FiredWeapon = 1; } @@ -306,14 +305,14 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_AIM_1: if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 12 || (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 1 && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 10)) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) + if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.RequiredState = MPGUN_STATE_WAIT; } else if (item->HitStatus && TestProbability(0.25f) && cover) @@ -327,8 +326,8 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_SHOOT_1: if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (item->Animation.RequiredState == MPGUN_STATE_WAIT) @@ -339,13 +338,13 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_SHOOT_2: if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) + if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.TargetState = MPGUN_STATE_WAIT; } else if (item->HitStatus && TestProbability(0.25f) && cover) @@ -360,14 +359,14 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_SHOOT_3B: if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase || item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 11) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) + if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.TargetState = MPGUN_STATE_WAIT; } else if (item->HitStatus && TestProbability(0.25f) && cover) @@ -381,14 +380,14 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_AIM_4: if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if ((item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 18 && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 17) || (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 19 && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 6)) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) + if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.RequiredState = MPGUN_STATE_WALK; } else if (item->HitStatus && TestProbability(0.25f) && cover) @@ -406,8 +405,8 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_SHOOT_4B: if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (item->Animation.RequiredState == MPGUN_STATE_WALK) @@ -415,7 +414,7 @@ namespace TEN::Entities::Creatures::TR3 if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 16) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32)) + if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.TargetState = MPGUN_STATE_WALK; } @@ -443,7 +442,7 @@ namespace TEN::Entities::Creatures::TR3 creature->MaxTurn = ANGLE(1.0f); if (AI.ahead) - torsoY = AI.angle; + extraTorsoRot.y = AI.angle; if (Targetable(item, &AI)) item->Animation.TargetState = MPGUN_STATE_CROUCH_SHOT; @@ -454,11 +453,11 @@ namespace TEN::Entities::Creatures::TR3 case MPGUN_STATE_CROUCH_SHOT: if (AI.ahead) - torsoY = AI.angle; + extraTorsoRot.y = AI.angle; if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase) { - if (!ShotLara(item, &AI, MPGunBite, torsoY, 32) || TestProbability(0.125f)) + if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32) || TestProbability(0.125f)) item->Animation.TargetState = MPGUN_STATE_CROUCHED; } @@ -478,8 +477,8 @@ namespace TEN::Entities::Creatures::TR3 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, torsoY); - CreatureJoint(item, 1, torsoX); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); CreatureJoint(item, 2, head); CreatureAnimation(itemNumber, angle, tilt); } diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index 7bedb6242..d7433e8c4 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -55,10 +55,7 @@ namespace TEN::Entities::Creatures::TR3 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[ID_MP_WITH_STICK].animIndex + 6; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = item->Animation.TargetState = MPSTICK_STATE_STOP; + SetAnimation(item, 6); } void MPStickControl(short itemNumber) @@ -69,11 +66,10 @@ namespace TEN::Entities::Creatures::TR3 auto* item = &g_Level.Items[itemNumber]; auto* creature = GetCreatureInfo(item); - short head = 0; short angle = 0; short tilt = 0; - short torsoX = 0; - short torsoY = 0; + short head = 0; + auto extraTorsoRot = Vector3Shrt::Zero; if (item->BoxNumber != NO_BOX && (g_Level.Boxes[item->BoxNumber].flags & BLOCKED)) { @@ -86,9 +82,7 @@ namespace TEN::Entities::Creatures::TR3 { if (item->Animation.ActiveState != MPSTICK_STATE_DEATH) { - item->Animation.AnimNumber = Objects[ID_MP_WITH_STICK].animIndex + 26; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = MPSTICK_STATE_DEATH; + SetAnimation(item, 26); creature->LOT.Step = 256; } } @@ -104,7 +98,7 @@ namespace TEN::Entities::Creatures::TR3 int dz = LaraItem->Pose.Position.z - item->Pose.Position.z; laraAI.distance = pow(dx, 2) + pow(dx, 2); - int bestDistance = 0x7fffffff; + int bestDistance = INT_MAX; for (int slot = 0; slot < ActiveCreatures.size(); slot++) { auto* currentCreature = ActiveCreatures[slot]; @@ -195,7 +189,6 @@ namespace TEN::Entities::Creatures::TR3 break; } - else if (item->AIBits & PATROL1) item->Animation.TargetState = MPSTICK_STATE_WALK; @@ -289,8 +282,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (AI.bite && AI.distance < pow(SECTOR(0.5f), 2)) @@ -306,8 +299,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) @@ -323,8 +316,8 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (AI.bite && AI.distance < pow(SECTOR(1.25f), 2)) @@ -339,16 +332,16 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (enemy->IsLara()) { if (!creature->Flags && item->TestBits(JointBitType::Touch, MPStickPunchAttackJoints)) { - CreatureEffect(item, MPStickBite1, DoBloodSplat); DoDamage(enemy, 80); + CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; } @@ -361,10 +354,10 @@ namespace TEN::Entities::Creatures::TR3 abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) { - creature->Flags = 1; - CreatureEffect(item, MPStickBite1, DoBloodSplat); DoDamage(enemy, 5); + CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); + creature->Flags = 1; } } } @@ -376,16 +369,16 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (enemy->IsLara()) { if (!creature->Flags && item->TestBits(JointBitType::Touch, MPStickPunchAttackJoints)) { - CreatureEffect(item, MPStickBite1, DoBloodSplat); DoDamage(enemy, 80); + CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; } @@ -398,10 +391,10 @@ namespace TEN::Entities::Creatures::TR3 abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) { - creature->Flags = 1; - CreatureEffect(item, MPStickBite1, DoBloodSplat); DoDamage(enemy, 5); + CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); + creature->Flags = 1; } } } @@ -416,18 +409,18 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) { - torsoX = AI.xAngle; - torsoY = AI.angle; + extraTorsoRot.x = AI.xAngle; + extraTorsoRot.y = AI.angle; } if (enemy->IsLara()) { if (creature->Flags != 2 && item->TestBits(JointBitType::Touch, MPStickPunchAttackJoints)) { - CreatureEffect(item, MPStickBite1, DoBloodSplat); DoDamage(enemy, 100); - creature->Flags = 2; + CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(70, &item->Pose); + creature->Flags = 2; } } else @@ -438,10 +431,10 @@ namespace TEN::Entities::Creatures::TR3 abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) { - creature->Flags = 2; - CreatureEffect(item, MPStickBite1, DoBloodSplat); DoDamage(enemy, 6); + CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); + creature->Flags = 2; } } } @@ -452,7 +445,7 @@ namespace TEN::Entities::Creatures::TR3 creature->MaxTurn = ANGLE(6.0f); if (AI.ahead) - torsoY = AI.angle; + extraTorsoRot.y = AI.angle; if (enemy->IsLara()) { @@ -487,8 +480,8 @@ namespace TEN::Entities::Creatures::TR3 } CreatureTilt(item, tilt); - CreatureJoint(item, 0, torsoY); - CreatureJoint(item, 1, torsoX); + CreatureJoint(item, 0, extraTorsoRot.y); + CreatureJoint(item, 1, extraTorsoRot.x); CreatureJoint(item, 2, head); if (item->Animation.ActiveState < MPSTICK_STATE_DEATH) diff --git a/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp b/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp index 6533c94e1..029fe7793 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_hammerhead.cpp @@ -16,6 +16,7 @@ using std::vector; namespace TEN::Entities::TR4 { constexpr auto HAMMERHEAD_BITE_ATTACK_DAMAGE = 120; + constexpr auto HAMMERHEAD_ATTACK_RANGE = SQUARE(SECTOR(0.66f)); const auto HammerheadBite = BiteInfo(Vector3::Zero, 12); const vector HammerheadBiteAttackJoints = { 10, 12, 13 }; @@ -109,7 +110,7 @@ namespace TEN::Entities::TR4 if (AI.distance <= pow(SECTOR(1), 2)) { - if (AI.distance < pow(682, 2)) + if (AI.distance < HAMMERHEAD_ATTACK_RANGE) item->Animation.TargetState = HAMMERHEAD_STATE_IDLE_BITE_ATTACK; } else diff --git a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp index 60185d1f0..7999dad2f 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp @@ -29,7 +29,7 @@ namespace TEN::Entities::TR4 enum KnightTemplarState { - KTEMPLAR_STATE_NONE = 0, + // No state 0. KTEMPLAR_STATE_IDLE = 1, KTEMPLAR_STATE_WALK_FORWARD = 2, KTEMPLAR_STATE_SWORD_ATTACK_1 = 3, diff --git a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp index 0dac11758..292c98829 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_setha.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_setha.cpp @@ -29,10 +29,7 @@ namespace TEN::Entities::TR4 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex + 4; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = 12; - item->Animation.TargetState = 12; + SetAnimation(item, 4); } void SethaControl(short itemNumber) @@ -113,8 +110,7 @@ namespace TEN::Entities::TR4 else if (LaraItem->Pose.Position.y >= (item->Pose.Position.y - SECTOR(1))) { if (AI.distance < pow(SECTOR(2.5f), 2) && - AI.ahead && - TestProbability(0.5f) && + AI.ahead && TestProbability(0.5f) && Targetable(item, &AI)) { item->Animation.TargetState = 11; @@ -195,8 +191,7 @@ namespace TEN::Entities::TR4 if (AI.bite && AI.distance < pow(SECTOR(4), 2) || - canJump || - creature->ReachedGoal) + canJump || creature->ReachedGoal) { item->Animation.TargetState = 1; } @@ -210,8 +205,7 @@ namespace TEN::Entities::TR4 if (AI.bite && AI.distance < pow(SECTOR(4), 2) || - canJump || - creature->ReachedGoal) + canJump || creature->ReachedGoal) { item->Animation.TargetState = 1; } @@ -659,9 +653,7 @@ namespace TEN::Entities::TR4 ); TriggerSethaSparks1( - pos.x, - pos.y, - pos.z, + pos.x, pos.y, pos.z, (pos1.x - pos.x), (pos1.y - pos.y), (SECTOR(1) - (GetRandomControl() & 0x7FF))); @@ -673,9 +665,7 @@ namespace TEN::Entities::TR4 ); TriggerSethaSparks1( - pos.x, - pos.y, - pos.z, + pos.x, pos.y, pos.z, (pos2.x - pos.x), (pos2.y - pos.y), (SECTOR(1) - (GetRandomControl() & 0x7FF))); diff --git a/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp b/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp index 04f9b176a..959ead06e 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_small_scorpion.cpp @@ -57,11 +57,7 @@ namespace TEN::Entities::TR4 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[ID_SMALL_SCORPION].animIndex + SSCORPION_ANIM_IDLE; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.TargetState = SSCORPION_STATE_IDLE; - item->Animation.ActiveState = SSCORPION_STATE_IDLE; + SetAnimation(item, SSCORPION_ANIM_IDLE); } void SmallScorpionControl(short itemNumber) @@ -73,9 +69,9 @@ namespace TEN::Entities::TR4 auto* creature = GetCreatureInfo(item); short angle = 0; + short tilt = 0; short head = 0; short neck = 0; - short tilt = 0; short joint0 = 0; short joint1 = 0; short joint2 = 0; @@ -87,9 +83,7 @@ namespace TEN::Entities::TR4 if (item->Animation.ActiveState != SSCORPION_STATE_DEATH_1 && item->Animation.ActiveState != SSCORPION_STATE_DEATH_2) { - item->Animation.AnimNumber = Objects[ID_SMALL_SCORPION].animIndex + SSCORPION_ANIM_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = SSCORPION_STATE_DEATH_1; + SetAnimation(item, SSCORPION_ANIM_DEATH); } } else @@ -118,6 +112,7 @@ namespace TEN::Entities::TR4 else if (AI.bite) { creature->MaxTurn = ANGLE(6.0f); + if (TestProbability(0.5f)) item->Animation.TargetState = SSCORPION_STATE_ATTACK_1; else diff --git a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp index 1070394eb..7a10b5ef3 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp @@ -18,14 +18,13 @@ using namespace TEN::Math::Random; namespace TEN::Entities::TR4 { constexpr auto WILD_BOAR_ATTACK_DAMAGE = 30; - constexpr auto WILD_BOAR_ATTACK_RANGE = SQUARE(CLICK(1)); const auto WildBoarBite = BiteInfo(Vector3::Zero, 14); enum WildBoarState { - BOAR_STATE_NONE = 0, + // No state 0. BOAR_STATE_IDLE = 1, BOAR_STATE_RUN_FORWARD = 2, BOAR_STATE_GRAZE = 3, @@ -51,11 +50,7 @@ namespace TEN::Entities::TR4 auto* item = &g_Level.Items[itemNumber]; ClearItem(itemNumber); - - item->Animation.AnimNumber = Objects[ID_WILD_BOAR].animIndex + BOAR_ANIM_IDLE; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = BOAR_STATE_IDLE; - item->Animation.TargetState = BOAR_STATE_IDLE; + SetAnimation(item, BOAR_ANIM_IDLE); } void WildBoarControl(short itemNumber) @@ -67,9 +62,9 @@ namespace TEN::Entities::TR4 auto* creature = GetCreatureInfo(item); short angle = 0; + short tilt = 0; short head = 0; short neck = 0; - short tilt = 0; short joint0 = 0; short joint1 = 0; short joint2 = 0; @@ -192,11 +187,7 @@ namespace TEN::Entities::TR4 item->HitPoints = 0; if (item->Animation.ActiveState != BOAR_STATE_DEATH) - { - item->Animation.AnimNumber = Objects[ID_WILD_BOAR].animIndex + BOAR_ANIM_DEATH; - item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; - item->Animation.ActiveState = BOAR_STATE_DEATH; - } + SetAnimation(item, BOAR_ANIM_DEATH); } CreatureJoint(item, 0, joint0); From 5bef92e760293081a7034725c67b3a4ee5d1dbe0 Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 6 Sep 2022 20:05:06 +1000 Subject: [PATCH 068/106] WIP simplify stargate --- TombEngine/Game/collision/collide_item.cpp | 30 ++--- TombEngine/Game/collision/sphere.cpp | 2 +- TombEngine/Game/control/trigger.cpp | 1 + TombEngine/Objects/TR4/Trap/tr4_stargate.cpp | 134 +++++++------------ TombEngine/Specific/phd_global.cpp | 18 +-- TombEngine/Specific/phd_global.h | 4 +- 6 files changed, 79 insertions(+), 110 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 8011fe5c4..805a21aae 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -613,10 +613,10 @@ bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius) auto bounds = (BOUNDING_BOX*)GetBestFrame(item); auto laraBounds = (BOUNDING_BOX*)GetBestFrame(laraItem); - if (item->Pose.Position.y + bounds->Y2 <= laraItem->Pose.Position.y + laraBounds->Y1) + if ((item->Pose.Position.y + bounds->Y2) <= (laraItem->Pose.Position.y + laraBounds->Y1)) return false; - if (item->Pose.Position.y + bounds->Y1 >= laraItem->Pose.Position.y + laraBounds->Y2) + if ((item->Pose.Position.y + bounds->Y1) >= (laraItem->Pose.Position.y + laraBounds->Y2)) return false; float sinY = phd_sin(item->Pose.Orientation.y); @@ -624,13 +624,13 @@ bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius) int x = laraItem->Pose.Position.x - item->Pose.Position.x; int z = laraItem->Pose.Position.z - item->Pose.Position.z; - int dx = (cosY * x) - (sinY * z); - int dz = (cosY * z) + (sinY * x); + int dx = (x * cosY) - (z * sinY); + int dz = (z * cosY) + (x * sinY); - if (dx >= bounds->X1 - radius && - dx <= radius + bounds->X2 && - dz >= bounds->Z1 - radius && - dz <= radius + bounds->Z2) + if (dx >= (bounds->X1 - radius) && + dx <= (radius + bounds->X2) && + dz >= (bounds->Z1 - radius) && + dz <= (radius + bounds->Z2)) { return true; } @@ -731,13 +731,13 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool spa auto* lara = item2->IsLara() ? GetLaraInfo(item2) : nullptr; - if (lara != nullptr && spasmEnabled && bounds->Y2 - bounds->Y1 > CLICK(1)) + if (lara != nullptr && spasmEnabled && (bounds->Y2 - bounds->Y1) > CLICK(1)) { rx = (bounds->X1 + bounds->X2) / 2; rz = (bounds->Z1 + bounds->Z2) / 2; - dx -= cosY * rx + sinY * rz; - dz -= cosY * rz - sinY * rx; + dx -= (rx * cosY) + (rz * sinY); + dz -= (rz * cosY) - (rx * sinY); lara->HitDirection = (item2->Pose.Orientation.y - phd_atan(dz, dz) - ANGLE(135.0f)) / ANGLE(90.0f); DoDamage(item2, 0); // Dummy hurt call. Only for ooh sound! @@ -752,12 +752,12 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool spa coll->Setup.LowerCeilingBound = 0; coll->Setup.UpperCeilingBound = MAX_HEIGHT; - auto facing = coll->Setup.ForwardAngle; + auto headingAngle = coll->Setup.ForwardAngle; coll->Setup.ForwardAngle = phd_atan(item2->Pose.Position.z - coll->Setup.OldPosition.z, item2->Pose.Position.x - coll->Setup.OldPosition.x); GetCollisionInfo(coll, item2); - coll->Setup.ForwardAngle = facing; + coll->Setup.ForwardAngle = headingAngle; if (coll->CollisionType == CT_NONE) { @@ -775,8 +775,8 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool spa // If Lara is in the process of aligning to an object, cancel it. if (lara != nullptr && lara->Control.Count.PositionAdjust > (LARA_POSITION_ADJUST_MAX_TIME / 6)) { - Lara.Control.IsMoving = false; - Lara.Control.HandStatus = HandStatus::Free; + lara->Control.IsMoving = false; + lara->Control.HandStatus = HandStatus::Free; } return true; diff --git a/TombEngine/Game/collision/sphere.cpp b/TombEngine/Game/collision/sphere.cpp index 017cd77ad..77dd40087 100644 --- a/TombEngine/Game/collision/sphere.cpp +++ b/TombEngine/Game/collision/sphere.cpp @@ -78,7 +78,7 @@ int TestCollision(ItemInfo* item, ItemInfo* laraItem) int dz = z1 - z2; int r = r1 + r2; - if ((pow(dx, 2) + pow(dy, 2) + pow(dz, 2)) < pow(r, 2)) + if ((SQUARE(dx) + SQUARE(dy) + SQUARE(dz)) < SQUARE(r)) { item->SetBits(JointBitType::Touch, i); laraItem->SetBits(JointBitType::Touch, j); diff --git a/TombEngine/Game/control/trigger.cpp b/TombEngine/Game/control/trigger.cpp index ec97fd506..ee5e38f49 100644 --- a/TombEngine/Game/control/trigger.cpp +++ b/TombEngine/Game/control/trigger.cpp @@ -56,6 +56,7 @@ int TriggerActive(ItemInfo* item) flag = !flag; } } + return flag; } diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index 515db8e47..15a7c8de9 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -1,46 +1,45 @@ #include "framework.h" -#include "tr4_stargate.h" -#include "Specific/level.h" -#include "Game/control/control.h" -#include "Sound/sound.h" -#include "Game/collision/collide_room.h" -#include "Game/collision/collide_item.h" -#include "Game/collision/sphere.h" -#include "Game/Lara/lara.h" -#include "Game/effects/effects.h" +#include "Objects/TR4/Trap/tr4_stargate.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" + +using std::vector; namespace TEN::Entities::TR4 { - short StargateBounds[24] = + constexpr auto STARGATE_HARM_DAMAGE = 100; + + const vector StargateHarmJoints = { 9, 10, 12, 13, 15, 16, 18, 19, 21, 22, 24, 25 }; + const vector StargateBounds = { - -512, 512, -1024, - -896, -96, 96, - -512, 512, -128, - 0, -96, 96, - -512, -384, -1024, - 0, -96, 96, - 384, 512, -1024, - 0, -96, 96 + Vector3Int(-CLICK(2), CLICK(2), -SECTOR(2)), + Vector3Int(-896, -96, 96), + Vector3Int(-CLICK(2), CLICK(2), -128), + Vector3Int(0, -96, 96), + Vector3Int(-CLICK(2), -384, -SECTOR(2)), + Vector3Int(0, -96, 96), + Vector3Int(384, CLICK(2), -SECTOR(2)), + Vector3Int(0, -96, 96) }; void StargateControl(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; - item->ItemFlags[3] = 50; if (TriggerActive(item)) { - int touchBits = 0x036DB600; - item->ItemFlags[0] = short(touchBits & 0xFFFF); - item->ItemFlags[1] = short((touchBits >> 16) & 0xFFFF); - SoundEffect(SFX_TR4_STARGATE_SWIRL, &item->Pose); AnimateItem(item); } - else - item->ItemFlags[0] = item->ItemFlags[1] = 0; } void StargateCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) @@ -50,67 +49,36 @@ namespace TEN::Entities::TR4 if (item->Status == ITEM_INVISIBLE) return; - if (TestBoundsCollide(item, laraItem, coll->Setup.Radius)) + if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) + return; + + // TODO: Define bounds for collision with the border. + /*for (auto& bounds : StargateBounds) { - for (int i = 0; i < 8; i++) + GlobalCollisionBounds.X1 = bounds.x; + GlobalCollisionBounds.Y1 = bounds.y; + GlobalCollisionBounds.Z1 = bounds.z; + + if (TestWithGlobalCollisionBounds(item, laraItem, coll)) + ItemPushItem(item, laraItem, coll, 0, 2); + }*/ + + if (TriggerActive(item) && + item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 20 && // Hardcoded frame range. + item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 60) + { + // Blades incur damage cumulatively. + for (int i = 0; i < StargateHarmJoints.size(); i++) { - GlobalCollisionBounds.X1 = StargateBounds[3 * i + 0]; - GlobalCollisionBounds.Y1 = StargateBounds[3 * i + 1]; - GlobalCollisionBounds.Z1 = StargateBounds[3 * i + 2]; - - if (TestWithGlobalCollisionBounds(item, laraItem, coll)) - ItemPushItem(item, laraItem, coll, 0, 2); - } - - int result = TestCollision(item, laraItem); - if (result) - { - int flags = item->ItemFlags[0] | item->ItemFlags[1] << 16; - result &= flags; - - if (result) + if (item->TestBits(JointBitType::Touch, StargateHarmJoints[i])); { - int j = 0; - do - { - if (result & 1) - { - GlobalCollisionBounds.X1 = CreatureSpheres[j].x - CreatureSpheres[j].r - item->Pose.Position.x; - GlobalCollisionBounds.Y1 = CreatureSpheres[j].y - CreatureSpheres[j].r - item->Pose.Position.y; - GlobalCollisionBounds.Z1 = CreatureSpheres[j].z - CreatureSpheres[j].r - item->Pose.Position.z; - GlobalCollisionBounds.X2 = CreatureSpheres[j].x + CreatureSpheres[j].r - item->Pose.Position.x; - GlobalCollisionBounds.Y2 = CreatureSpheres[j].y + CreatureSpheres[j].r - item->Pose.Position.y; - GlobalCollisionBounds.Z2 = CreatureSpheres[j].z + CreatureSpheres[j].r - item->Pose.Position.z; - - int oldX = LaraItem->Pose.Position.x; - int oldY = LaraItem->Pose.Position.y; - int oldZ = LaraItem->Pose.Position.z; - - if (ItemPushItem(item, laraItem, coll, flags & 1, 2)) - { - if ((flags & 1) && - (oldX != LaraItem->Pose.Position.x || - oldY != LaraItem->Pose.Position.y || - oldZ != LaraItem->Pose.Position.z) && - TriggerActive(item)) - { - DoBloodSplat((GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32, - (GetRandomControl() & 0x1F) + CreatureSpheres[j].y - 16, - (GetRandomControl() & 0x3F) + laraItem->Pose.Position.z - 32, - (GetRandomControl() & 3) + 2, - 2 * GetRandomControl(), - laraItem->RoomNumber); - - DoDamage(laraItem, 100); - } - } - } - - result /= 2; - j++; - flags /= 2; - - } while (result); + DoDamage(laraItem, STARGATE_HARM_DAMAGE); + DoBloodSplat((GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32, + (GetRandomControl() & 0x1F) + CreatureSpheres[i].y - 16, + (GetRandomControl() & 0x3F) + laraItem->Pose.Position.z - 32, + (GetRandomControl() & 3) + 2, + GetRandomControl() * 2, + laraItem->RoomNumber); } } } diff --git a/TombEngine/Specific/phd_global.cpp b/TombEngine/Specific/phd_global.cpp index 1696bc4bc..9e9e88dc3 100644 --- a/TombEngine/Specific/phd_global.cpp +++ b/TombEngine/Specific/phd_global.cpp @@ -5,21 +5,21 @@ const Vector2Int Vector2Int::Zero = Vector2Int(0, 0); const Vector3Int Vector3Int::Zero = Vector3Int(0, 0, 0); const Vector3Shrt Vector3Shrt::Zero = Vector3Shrt(0, 0, 0); -BOUNDING_BOX operator+(const BOUNDING_BOX& box, const PHD_3DPOS& vec) +BOUNDING_BOX operator+(const BOUNDING_BOX& box, const PHD_3DPOS& pose) { - BOUNDING_BOX box2 = box; - box2.X1 += vec.Position.x; - box2.X2 += vec.Position.x; - box2.Y1 += vec.Position.y; - box2.Y2 += vec.Position.y; - box2.Z1 += vec.Position.z; - box2.Z2 += vec.Position.z; + auto box2 = box; + box2.X1 += pose.Position.x; + box2.X2 += pose.Position.x; + box2.Y1 += pose.Position.y; + box2.Y2 += pose.Position.y; + box2.Z1 += pose.Position.z; + box2.Z2 += pose.Position.z; return box2; } BOUNDING_BOX operator*(const BOUNDING_BOX& box, const float scale) { - BOUNDING_BOX box2 = box; + auto box2 = box; box2.X1 *= scale; box2.X2 *= scale; box2.Y1 *= scale; diff --git a/TombEngine/Specific/phd_global.h b/TombEngine/Specific/phd_global.h index 44b22b53c..cae2ab8e1 100644 --- a/TombEngine/Specific/phd_global.h +++ b/TombEngine/Specific/phd_global.h @@ -595,5 +595,5 @@ struct BOUNDING_BOX int Height() { return abs(Y2 - Y1); } }; -BOUNDING_BOX operator+(const BOUNDING_BOX& box, const PHD_3DPOS& vec); -BOUNDING_BOX operator*(const BOUNDING_BOX& box, const float scale); \ No newline at end of file +BOUNDING_BOX operator+(const BOUNDING_BOX& box, const PHD_3DPOS& pose); +BOUNDING_BOX operator*(const BOUNDING_BOX& box, const float scale); From 806381dc8bcc162b815cb1649155b0bfe713ec4c Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 6 Sep 2022 21:23:09 +0100 Subject: [PATCH 069/106] Separate Lua changes into own section --- Documentation/Changes.txt | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index d4dbb497b..707bed723 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -1,11 +1,8 @@ Version 1.0.2 ============= -- EventSequence and Timer no longer require you to call Timer.UpdateAll in OnControlPhase. -- TEN.Logic.AddCallback and TEN.Logic.RemoveCallback have been added. -- GiveItem, TakeItem, and SetItemCount have been reworked (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables). -- Removing Pistols with TakeItem and SetItemCount now works correctly. -- Vec3s can now be saved and loaded in LevelVars and GameVars. +* Removing Pistols with TakeItem and SetItemCount now works correctly. +* Vec3s can now be saved and loaded in LevelVars and GameVars. * Adjust max turn rate of idle state. * Align Lara on slopes when crouching, crawling, and dying. * Better slope alignment for large, flat enemies (i.e. big scorpion and crocodile). @@ -18,6 +15,16 @@ Version 1.0.2 * Fix incorrect viewport size in windowed mode. * Fix Lara's subway train death so that she no longer slides slowly after the animation has finished. +Lua API changes: +* LevelFuncs can now contain tables as well as functions. These tables can contain functions and other tables, and so forth. +* Moveable functions SetOnHit, SetOnKilled, SetOnCollidedWithObject and SetOnCollidedWithRoom no longer take strings, and instead take function objects themselves. The function still has to be in the LevelFuncs hierarchy: +Before: +baddy:SetOnHit("HealLara") +After: +baddy:SetOnHit(LevelFuncs.HealLara) +* EventSequence and Timer no longer require you to call Timer.UpdateAll in OnControlPhase. +* TEN.Logic.AddCallback and TEN.Logic.RemoveCallback have been added. +* GiveItem, TakeItem, and SetItemCount have been reworked (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables). Version 1.0.1 ============= From 5d0ea864c6937e4b331fb045adbfa66ec923176a Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 6 Sep 2022 21:26:49 +0100 Subject: [PATCH 070/106] Improve documentation --- .../Internal/TEN/Logic/LogicHandler.cpp | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 0d8550542..834344773 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -726,9 +726,9 @@ Unlike @{LevelVars}, this table will remain intact for the entirety of the game. @table GameVars */ -/*** A table with level-specific functions. +/*** A table nested table system for level-specific functions. -This serves two purposes: it holds the level callbacks (listed below) as well as +This serves a few purposes: it holds the level callbacks (listed below) as well as any trigger functions you might have specified. For example, if you give a trigger a Lua name of "my_trigger" in Tomb Editor, you will have to implement it as a member of this table: @@ -737,6 +737,23 @@ of this table: -- implementation goes here end +You can organise functions into tables within the hierarchy: + + LevelFuncs.enemyFuncs = {} + + LevelFuncs.enemyFuncs.makeBaddyRunAway = function() + -- implementation goes here + end + + LevelFuncs.enemyFuncs.makeBaddyUseMedkit = function() + -- implementation goes here + end + +There are two special subtables which you should not overwrite: + + LevelFuncs.TEN -- this is for 'first-party' functions, i.e. ones that come with TombEngine. + LevelFuncs.Ext -- this is for 'third-party' functions. If you write a library providing LevelFuncs functions for other builders to use in their levels, put those functions in LevelFuncs.Ext.YourLibraryNameHere + The following are the level callbacks. They are optional; if your level has no special behaviour for a particular scenario, you do not need to implement the function. For example, if your level does not need any special initialisation when it is loaded, From 418ab7e8b154318d9f3364fac24af3d7f0768111 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 6 Sep 2022 21:28:44 +0100 Subject: [PATCH 071/106] Improve documentation, fix ExecuteFunction behaviour --- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp | 5 +++-- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h | 1 + .../Internal/TEN/Objects/Moveable/MoveableObject.cpp | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 834344773..6aaf56f69 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -111,7 +111,7 @@ Any returned value will be discarded. @function AddCallback @tparam point CallbackPoint When should the callback be called? -@tparam LevelFunc The function to be called (must be in the LevelFuncs hierarchy). Will receive, as an argument, the time in seconds since the last frame. +@tparam function func The function to be called (must be in the LevelFuncs hierarchy). Will receive, as an argument, the time in seconds since the last frame. @usage LevelFuncs.MyFunc = function(dt) print(dt) end TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, LevelFuncs.MyFunc) @@ -594,7 +594,8 @@ void LogicHandler::ExecuteScriptFile(const std::string & luaFilename) void LogicHandler::ExecuteFunction(std::string const& name, short idOne, short idTwo) { sol::protected_function_result r; - sol::protected_function func = (*m_handler.GetState())["LevelFuncs"][name.c_str()]; + sol::protected_function func = m_levelFuncs_luaFunctions[name]; + r = func(std::make_unique(idOne), std::make_unique(idTwo)); if (!r.valid()) { diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index a927d9b88..81ff7fc3d 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -12,6 +12,7 @@ class LogicHandler : public ScriptInterfaceGame private: // Hierarchy of tables. // + // For example: // LevelFuncs // |- TEN // |- Timer diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 42dd705d5..06ec83458 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -15,6 +15,7 @@ #include "Objects/ObjectsHandler.h" #include "ReservedScriptNames.h" #include "Color/Color.h" +#include "Logic/LevelFunc.h" #include "Rotation/Rotation.h" #include "Vec3/Vec3.h" From a30ec88d3fb65d27dac604c87dfe0a748424c3fa Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 6 Sep 2022 21:31:04 +0100 Subject: [PATCH 072/106] Improve SetOnCollidedWithObject, SetOnCollidedWithRoom, SetOnHit and SetOnKilled to use LevelFuncs. Removed Getters for these for now as it's not really trivial to decide what useful thing they will return. --- .../TEN/Objects/Moveable/MoveableObject.cpp | 115 +++++++----------- 1 file changed, 44 insertions(+), 71 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp index 06ec83458..9e22c144f 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp @@ -172,50 +172,14 @@ void Moveable::Register(sol::table & parent) // @treturn int a number representing the status of the object ScriptReserved_GetStatus, &Moveable::GetStatus, -/// Set the name of the function to be called when the moveable is shot by Lara -// Note that this will be triggered twice when shot with both pistols at once. -// @function Moveable:SetOnHit -// @tparam string name of callback function to be called ScriptReserved_SetOnHit, &Moveable::SetOnHit, -/// Get the name of the function called when this moveable is shot -// @function Moveable:GetOnHit -// @treturn string name of the function - ScriptReserved_GetOnHit, &Moveable::GetOnHit, - -/// Set the name of the function called when this moveable collides with another moveable -// @function Moveable:SetOnCollidedWithObject -// @tparam string name of callback function to be called ScriptReserved_SetOnCollidedWithObject, &Moveable::SetOnCollidedWithObject, -/// Get the name of the function called when this moveable collides with another moveable -// @function Moveable:GetOnCollidedWithObject -// @treturn string name of the function - ScriptReserved_GetOnCollidedWithObject, &Moveable::GetOnCollidedWithObject, - -/// Set the name of the function called when this moveable collides with room geometry (e.g. a wall or floor) -// @function Moveable:SetOnCollidedWithRoom -// @tparam string name of callback function to be called ScriptReserved_SetOnCollidedWithRoom, &Moveable::SetOnCollidedWithRoom, -/// Get the name of the function called when this moveable collides with room geometry (e.g. a wall or floor) -// @function Moveable:GetOnCollidedWithRoom -// @treturn string name of the function - ScriptReserved_GetOnCollidedWithRoom, &Moveable::GetOnCollidedWithRoom, - -/// Set the name of the function to be called when the moveable is destroyed/killed -// @function Moveable:SetOnKilled -// @tparam string callback name of function to be called -// @usage -// LevelFuncs.baddyKilled = function(theBaddy) print("You killed a baddy!") end -// baddy:SetOnKilled("baddyKilled") ScriptReserved_SetOnKilled, &Moveable::SetOnKilled, -/// Get the name of the function called when this moveable is killed -// @function Moveable:GetOnKilled -// @treturn string name of the function - ScriptReserved_GetOnKilled, &Moveable::GetOnKilled, - /// Retrieve the object ID // @function Moveable:GetObjectID // @treturn int a number representing the ID of the object @@ -472,54 +436,63 @@ void Moveable::SetObjectID(GAME_OBJECT_ID id) m_item->ObjectNumber = id; } -void Moveable::SetOnHit(std::string const & cbName) +void SetLevelFuncCallback(TypeOrNil const & cb, std::string const & callerName, Moveable & mov, std::string & toModify) { - m_item->LuaCallbackOnHitName = cbName; -} - -void Moveable::SetOnKilled(std::string const & cbName) -{ - m_item->LuaCallbackOnKilledName = cbName; -} - -void Moveable::SetOnCollidedWithObject(std::string const & cbName) -{ - m_item->LuaCallbackOnCollidedWithObjectName = cbName; - - if(cbName.empty()) - dynamic_cast(g_GameScriptEntities)->TryRemoveColliding(m_num); + if (std::holds_alternative(cb)) + { + toModify = std::get(cb).m_funcName; + dynamic_cast(g_GameScriptEntities)->TryAddColliding(mov.m_num); + } + else if (std::holds_alternative(cb)) + { + toModify = std::string{}; + dynamic_cast(g_GameScriptEntities)->TryRemoveColliding(mov.m_num); + } else - dynamic_cast(g_GameScriptEntities)->TryAddColliding(m_num); + { + ScriptAssert(false, "Tried giving " + mov.m_item->LuaName + + " a non-LevelFunc object as an arg to " + + callerName); + } + } -void Moveable::SetOnCollidedWithRoom(std::string const & cbName) +/// Set the name of the function to be called when the moveable is shot by Lara +// Note that this will be triggered twice when shot with both pistols at once. +// @function Moveable:SetOnHit +// @tparam function callback function in LevelFuncs hierarchy to call when moveable is shot +void Moveable::SetOnHit(TypeOrNil const & cb) { - m_item->LuaCallbackOnCollidedWithRoomName = cbName; - - if(cbName.empty()) - dynamic_cast(g_GameScriptEntities)->TryRemoveColliding(m_num); - else - dynamic_cast(g_GameScriptEntities)->TryAddColliding(m_num); + SetLevelFuncCallback(cb, ScriptReserved_SetOnHit, *this, m_item->LuaCallbackOnHitName); } -std::string Moveable::GetOnHit() const +/// Set the name of the function to be called when the moveable is destroyed/killed +// Note that enemy death often occurs at the end of an animation, and not at the exact moment +// the enemy's HP becomes zero. +// @function Moveable:SetOnKilled +// @tparam function callback function in LevelFuncs hierarchy to call when enemy is killed +// @usage +// LevelFuncs.baddyKilled = function(theBaddy) print("You killed a baddy!") end +// baddy:SetOnKilled(LevelFuncs.baddyKilled) +void Moveable::SetOnKilled(TypeOrNil const & cb) { - return m_item->LuaCallbackOnHitName; + SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->LuaCallbackOnKilledName); } -std::string Moveable::GetOnKilled() const +/// Set the function to be called called when this moveable collides with another moveable +// @function Moveable:SetOnCollidedWithObject +// @tparam function func callback function to be called (must be in LevelFuncs hierarchy) +void Moveable::SetOnCollidedWithObject(TypeOrNil const & cb) { - return m_item->LuaCallbackOnKilledName; + SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->LuaCallbackOnCollidedWithObjectName); } -std::string Moveable::GetOnCollidedWithObject() const +/// Set the function called when this moveable collides with room geometry (e.g. a wall or floor) +// @function Moveable:SetOnCollidedWithRoom +// @tparam function func callback function to be called (must be in LevelFuncs hierarchy) +void Moveable::SetOnCollidedWithRoom(TypeOrNil const & cb) { - return m_item->LuaCallbackOnCollidedWithObjectName; -} - -std::string Moveable::GetOnCollidedWithRoom() const -{ - return m_item->LuaCallbackOnCollidedWithRoomName; + SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithRoom, *this, m_item->LuaCallbackOnCollidedWithRoomName); } std::string Moveable::GetName() const @@ -608,7 +581,7 @@ void Moveable::SetRot(Rotation const& rot) short Moveable::GetHP() const { - return(m_item->HitPoints); + return m_item->HitPoints; } void Moveable::SetHP(short hp) From 14e78d7a68ebe09c065dcf52cb7f8d14c9c97734 Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 6 Sep 2022 21:38:40 +0100 Subject: [PATCH 073/106] Fix up MoveableObject header with new callback type --- .../TEN/Objects/Moveable/MoveableObject.h | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h index ee488e82a..cf6ea4807 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.h @@ -1,7 +1,10 @@ #pragma once +#include "ScriptUtil.h" #include "Objects/NamedBase.h" +class LevelFunc; + namespace sol { class state; template struct as_table_t; @@ -96,20 +99,18 @@ public: void Explode(); void Shatter(); - [[nodiscard]] std::string GetOnHit() const; - void SetOnHit(std::string const &); - [[nodiscard]] std::string GetOnKilled() const; - void SetOnKilled(std::string const &); - [[nodiscard]] std::string GetOnCollidedWithObject() const; - void SetOnCollidedWithObject(std::string const &); - [[nodiscard]] std::string GetOnCollidedWithRoom() const; - void SetOnCollidedWithRoom(std::string const &); + void SetOnHit(TypeOrNil const& cb); + void SetOnKilled(TypeOrNil const& cb); + void SetOnCollidedWithObject(TypeOrNil const& cb); + void SetOnCollidedWithRoom(TypeOrNil const& 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); + private: ItemInfo* m_item; short m_num; From 5ffe5bf06790e2b52e4060a784779e95fa33d51d Mon Sep 17 00:00:00 2001 From: hispidence Date: Tue, 6 Sep 2022 21:50:06 +0100 Subject: [PATCH 074/106] Rename TEN folder to Engine --- Scripts/{TEN => Engine}/EventSequence.lua | 0 Scripts/{TEN => Engine}/Timer.lua | 0 Scripts/{TEN => Engine}/Util.lua | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename Scripts/{TEN => Engine}/EventSequence.lua (100%) rename Scripts/{TEN => Engine}/Timer.lua (100%) rename Scripts/{TEN => Engine}/Util.lua (100%) diff --git a/Scripts/TEN/EventSequence.lua b/Scripts/Engine/EventSequence.lua similarity index 100% rename from Scripts/TEN/EventSequence.lua rename to Scripts/Engine/EventSequence.lua diff --git a/Scripts/TEN/Timer.lua b/Scripts/Engine/Timer.lua similarity index 100% rename from Scripts/TEN/Timer.lua rename to Scripts/Engine/Timer.lua diff --git a/Scripts/TEN/Util.lua b/Scripts/Engine/Util.lua similarity index 100% rename from Scripts/TEN/Util.lua rename to Scripts/Engine/Util.lua From cabbe2f85bf01baf3c56699c2204add9ab4b8c12 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 7 Sep 2022 19:45:35 +0100 Subject: [PATCH 075/106] Update Timer and EventSequence to work with new subtables system. --- Scripts/Engine/EventSequence.lua | 41 ++++++++++++------------ Scripts/Engine/Timer.lua | 53 +++++++++++++++++--------------- 2 files changed, 49 insertions(+), 45 deletions(-) diff --git a/Scripts/Engine/EventSequence.lua b/Scripts/Engine/EventSequence.lua index 8e99b9257..ae1646195 100644 --- a/Scripts/Engine/EventSequence.lua +++ b/Scripts/Engine/EventSequence.lua @@ -4,7 +4,7 @@ -- Works atop the Timer, and so is updated automatically pre-OnControlPhase, and saved automatically when the game is saved. -- -- Example usage: --- local EventSequence = require("EventSequence") +-- local EventSequence = require("Engine.EventSequence") -- -- -- These will be called by the sequence -- LevelFuncs.HealLara = function() @@ -26,13 +26,13 @@ -- false, -- does not loop -- {seconds = true, deciseconds = true}, -- timer format, see Timer for details -- 6, -- seconds until call the function specified in next arg --- "HealLara", -- first function to call. If we don't need to pass any arguments, we can just give the func name as a string +-- LevelFuncs.HealLara, -- first function to call. If we don't need to pass any arguments, we can just pass the function -- 2.1, -- seconds until the next function, after the previous one has been called --- {"SpawnBaddy", TEN.Objects.ObjID.BADDY1, "steve", posSteve}, -- if we DO want to pass arguments to the function to be called, we give a table with the name of the function ("SpawnBaddy" in this case) followed by the args to pass to it +-- {LevelFuncs.SpawnBaddy, TEN.Objects.ObjID.BADDY1, "steve", posSteve}, -- if we DO want to pass arguments to the function to be called, we give a table with the function (LevelFuncs.SpawnBaddy in this case) followed by the args to pass to it -- 0.5, --- {"SpawnBaddy", TEN.Objects.ObjID.SAS_CAIRO, "chris", posChris}, +-- {LevelFuncs.SpawnBaddy, TEN.Objects.ObjID.SAS_CAIRO, "chris", posChris}, -- 1, --- "HealLara") +-- LevelFuncs.HealLara) -- -- -- event sequences are inactive to begin with and so need to be started -- mySeq:Start() @@ -44,11 +44,12 @@ local Timer = require("Timer") local EventSequence -LevelVars.__TEN_eventSequence = {sequences = {}} +LevelFuncs.Engine.EventSequence = {} +LevelVars.Engine.EventSequence = {sequences = {}} -LevelFuncs.__TEN_eventSequence_callNext = function(sequenceName, nextTimerName, func, ...) - local thisES = LevelVars.__TEN_eventSequence.sequences[sequenceName] - LevelFuncs[func](...) +LevelFuncs.Engine.EventSequence.CallNext = function(sequenceName, nextTimerName, func, ...) + local thisES = LevelVars.Engine.EventSequence.sequences[sequenceName] + func(...) thisES.currentTimer = thisES.currentTimer + 1 if thisES.currentTimer <= #thisES.timers then @@ -80,9 +81,8 @@ EventSequence = { setmetatable(obj, mt) obj.name = name - - LevelVars.__TEN_eventSequence.sequences[name] = {} - local thisES = LevelVars.__TEN_eventSequence.sequences[name] + LevelVars.Engine.EventSequence.sequences[name] = {} + local thisES = LevelVars.Engine.EventSequence.sequences[name] thisES.name = name thisES.timesFuncsAndArgs = {...} thisES.loop = loop @@ -97,7 +97,6 @@ EventSequence = { local nextTimer = i + 2 local timerIndex = #thisES.timers + 1 - local funcName = "__TEN_eventSequence_" .. name .. "_func" .. timerIndex local timerName = "__TEN_eventSequence_" .. name .. "_timer" .. timerIndex local nextTimerName = "__TEN_eventSequence_" .. name .. "_timer" .. timerIndex + 1 @@ -108,7 +107,7 @@ EventSequence = { thisES.firstTimerName = timerName end - if type(funcAndArgs) == "string" then + if type(funcAndArgs) == "userdata" then -- we only have a function func = funcAndArgs funcAndArgs = {} @@ -121,7 +120,7 @@ EventSequence = { tfa[i], -- time false, timerFormat, - "__TEN_eventSequence_callNext", + LevelFuncs.Engine.EventSequence.CallNext, name, nextTimerName, func, @@ -138,7 +137,7 @@ EventSequence = { -- @string name The label that was given to the sequence when it was created -- @return The sequence Get = function(name) - if LevelVars.__TEN_eventSequence.sequences[name] then + if LevelVars.Engine.EventSequence.sequences[name] then local obj = {} local mt = {} mt.__index = EventSequence @@ -153,7 +152,7 @@ EventSequence = { -- @function mySequence:SetPaused -- @bool p if true, the sequence will be paused; if false, it will be unpaused SetPaused = function(t, p) - local thisES = LevelVars.__TEN_eventSequence.sequences[t.name] + local thisES = LevelVars.Engine.EventSequence.sequences[t.name] Timer.Get(thisES.timers[thisES.currentTimer]):SetPaused(p) end; @@ -161,21 +160,21 @@ EventSequence = { -- @function mySequence:IsPaused -- @return true if the timer is paused, false if otherwise IsPaused = function(t) - local thisES = LevelVars.__TEN_eventSequence.sequences[t.name] + local thisES = LevelVars.Engine.EventSequence.sequences[t.name] return Timer.Get(thisES.timers[thisES.currentTimer]):IsPaused() end; --- Begin or unpause a sequence. If showing the remaining time on-screen, its color will be set to white. -- @function mySequence:Start Start = function(t) - local thisES = LevelVars.__TEN_eventSequence.sequences[t.name] + local thisES = LevelVars.Engine.EventSequence.sequences[t.name] Timer.Get(thisES.timers[thisES.currentTimer]):Start() end; --- Stop the sequence. --@function mySequence:Stop Stop = function(t) - local thisES = LevelVars.__TEN_eventSequence.sequences[t.name] + local thisES = LevelVars.Engine.EventSequence.sequences[t.name] Timer.Get(thisES.timers[thisES.currentTimer]):Stop() end; @@ -183,7 +182,7 @@ EventSequence = { -- @function mySequence:IsActive -- @return true if the sequence is active, false if otherwise IsActive = function(t) - local thisES = LevelVars.__TEN_eventSequence.sequences[t.name] + local thisES = LevelVars.Engine.EventSequence.sequences[t.name] return Timer.Get(thisES.timers[thisES.currentTimer]):IsActive() end; } diff --git a/Scripts/Engine/Timer.lua b/Scripts/Engine/Timer.lua index 99eb821cf..65f6981e9 100644 --- a/Scripts/Engine/Timer.lua +++ b/Scripts/Engine/Timer.lua @@ -4,7 +4,7 @@ -- Timers are updated automatically every frame before OnControlPhase. -- -- Example usage: --- local Timer = require("Timer") +-- local Timer = require("Engine.Timer") -- -- -- This will be called when the timer runs out -- LevelFuncs.FinishTimer = function(healthWhenStarted, victoryMessage) @@ -18,7 +18,7 @@ -- 5.0, -- false, -- {minutes = false, seconds = true, deciseconds = true}, --- "FinishTimer", +-- LevelFuncs.FinishTimer, -- Lara:GetHP(), -- "Well done!") -- myTimer:Start() @@ -26,7 +26,8 @@ -- -- @luautil Timer -LevelVars.__TEN_timer = {timers = {}} +LevelFuncs.Engine.Timer = {} +LevelVars.Engine.Timer = {timers = {}} local Timer @@ -62,7 +63,7 @@ Timer = { -- @number totalTime The duration of the timer, in seconds -- @bool loop if true, the timer will start again immediately after the time has elapsed -- @tparam ?table|bool timerFormat If a table is given, the remaining time will be shown as a string, formatted according to the values in the table. If true, the remaining seconds, rounded up, will show at the bottom of the screen. If false, the remaining time will not be shown on screen. - -- @string func The name of the LevelFunc member to call when the time is upssss + -- @function func The LevelFunc function to call when the time is up -- @param[opt] ... a variable number of arguments with which the above function will be called -- @return The timer in its paused state -- @@ -73,8 +74,13 @@ Timer = { setmetatable(obj, mt) obj.name = name - LevelVars.__TEN_timer.timers[name] ={} - local thisTimer = LevelVars.__TEN_timer.timers[name] + + if LevelVars.Engine.Timer.timers[name] then + print("Warning: a timer with name " .. name .. " already exists.") + end + + LevelVars.Engine.Timer.timers[name] ={} + local thisTimer = LevelVars.Engine.Timer.timers[name] thisTimer.name = name thisTimer.totalTime = totalTime thisTimer.remainingTime = totalTime @@ -95,7 +101,7 @@ Timer = { -- @string name The label that was given to the timer when it was created -- @return The timer Get = function(name) - if LevelVars.__TEN_timer.timers[name] then + if LevelVars.Engine.Timer.timers[name] then local obj = {} local mt = {} mt.__index = Timer @@ -112,8 +118,7 @@ Timer = { t.remainingTime = t.remainingTime - dt if t.remainingTime <= 0 then - LevelFuncs[t.func](table.unpack(t.funcArgs)) - + t.func(table.unpack(t.funcArgs)) if not t.loop then t.active = false else @@ -196,10 +201,10 @@ Timer = { --- Give the timer a new function and args -- @function myTimer:SetFunction - -- @string func The name of the LevelFunc member to call when the time is up + -- @tparam function func The LevelFunc member to call when the time is up -- @param[opt] ... a variable number of arguments with which the above function will be called SetFunction = function(t, func, ...) - local thisTimer = LevelVars.__TEN_timer.timers[t.name] + local thisTimer = LevelVars.Engine.Timer.timers[t.name] thisTimer.func = func thisTimer.funcArgs = {...} end; @@ -207,7 +212,7 @@ Timer = { --- Begin or unpause a timer. If showing the remaining time on-screen, its color will be set to white. -- @function myTimer:Start Start = function(t) - local thisTimer = LevelVars.__TEN_timer.timers[t.name] + local thisTimer = LevelVars.Engine.Timer.timers[t.name] if not thisTimer.active then thisTimer.active = true end @@ -222,21 +227,21 @@ Timer = { --- Stop the timer. -- @function myTimer:Stop Stop = function(t) - LevelVars.__TEN_timer.timers[t.name].active = false + LevelVars.Engine.Timer.timers[t.name].active = false end; --- Get whether or not the timer is active -- @function myTimer:IsActive -- @return true if the timer is active, false if otherwise IsActive = function(t) - return LevelVars.__TEN_timer.timers[t.name].active + return LevelVars.Engine.Timer.timers[t.name].active end; --- Pause or unpause the timer. If showing the remaining time on-screen, its color will be set to yellow (paused) or white (unpaused). -- @function myTimer:SetPaused -- @bool p if true, the timer will be paused; if false, it would be unpaused SetPaused = function(t, p) - local thisTimer = LevelVars.__TEN_timer.timers[t.name] + local thisTimer = LevelVars.Engine.Timer.timers[t.name] thisTimer.paused = p if thisTimer.timerFormat then if p then @@ -251,21 +256,21 @@ Timer = { -- @function myTimer:IsPaused -- @return true if the timer is paused, false if otherwise IsPaused = function(t) - return LevelVars.__TEN_timer.timers[t.name].paused + return LevelVars.Engine.Timer.timers[t.name].paused end; --- Get the remaining time for a timer. -- @function myTimer:GetRemainingTime -- @return the time in seconds remaining on the clock GetRemainingTime = function(t) - return LevelVars.__TEN_timer.timers[t.name].remainingTime + return LevelVars.Engine.Timer.timers[t.name].remainingTime end; --- Set the remaining time for a timer -- @function myTimer:SetRemainingTime -- @number remainingTime the new time remaining for the timer SetRemainingTime = function(t, remainingTime) - LevelVars.__TEN_timer.timers[t.name].remainingTime = remainingTime + LevelVars.Engine.Timer.timers[t.name].remainingTime = remainingTime end; --- Get the total time for a timer. @@ -273,31 +278,31 @@ Timer = { -- @function myTimer:GetRemainingTime -- @return the timer's total time GetTotalTime = function(t) - return LevelVars.__TEN_timer.timers[t.name].totalTime + return LevelVars.Engine.Timer.timers[t.name].totalTime end; --- Set the total time for a timer -- @function myTimer:SetTotalTime -- @number totalTime timer's new total time SetTotalTime = function(t, totalTime) - LevelVars.__TEN_timer.timers[t.name].totalTime = totalTime + LevelVars.Engine.Timer.timers[t.name].totalTime = totalTime end; --- Set whether or not the timer loops -- @function myTimer:SetLooping -- @bool looping whether or not the timer loops SetLooping = function(t, looping) - LevelVars.__TEN_timer.timers[t.name].loop = looping + LevelVars.Engine.Timer.timers[t.name].loop = looping end; } -LevelFuncs.__TEN_timer_updateAll = function(dt) - for _, t in pairs(LevelVars.__TEN_timer.timers) do +LevelFuncs.Engine.Timer.UpdateAll = function(dt) + for _, t in pairs(LevelVars.Engine.Timer.timers) do Timer.Update(t, dt) end end -TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "__TEN_timer_updateAll") +TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, LevelFuncs.Engine.Timer.UpdateAll) return Timer From 44dce8a2860039a76e058167f539944eda0f2065 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 7 Sep 2022 20:52:54 +0100 Subject: [PATCH 076/106] Make sure LevelFuncs.Engine, LevelVars.Engine and GameVars.Engine get created. Move error handling to CallLevelFunc. --- .../Scripting/Internal/ReservedScriptNames.h | 2 +- .../Internal/TEN/Logic/LogicHandler.cpp | 67 +++++++++++-------- 2 files changed, 40 insertions(+), 29 deletions(-) diff --git a/TombEngine/Scripting/Internal/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h index 82688572d..8273b8340 100644 --- a/TombEngine/Scripting/Internal/ReservedScriptNames.h +++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h @@ -169,4 +169,4 @@ static constexpr char ScriptReserved_CallbackPoint[] = "CallbackPoint"; static constexpr char ScriptReserved_LevelVars[] = "LevelVars"; static constexpr char ScriptReserved_GameVars[] = "GameVars"; static constexpr char ScriptReserved_LevelFuncs[] = "LevelFuncs"; - +static constexpr char ScriptReserved_Engine[] = "Engine"; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 6aaf56f69..51e33c0b3 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -31,7 +31,7 @@ static const std::unordered_map kCallbackPoints {"POSTCONTROLPHASE", CallbackPoint::PostControl}, }; -using LevelFuncsTable = std::pair; +static constexpr char const* strKey = "__internal_name"; void SetVariable(sol::table tab, sol::object key, sol::object value) { @@ -96,7 +96,10 @@ LogicHandler::LogicHandler(sol::state* lua, sol::table & parent) : m_handler{ lu void LogicHandler::ResetGameTables() { - MakeSpecialTable(m_handler.GetState(), ScriptReserved_GameVars, &GetVariable, &SetVariable); + auto state = m_handler.GetState(); + MakeSpecialTable(state, ScriptReserved_GameVars, &GetVariable, &SetVariable); + + (*state)[ScriptReserved_GameVars][ScriptReserved_Engine] = sol::table{ *state, sol::create }; } /*** Register a function as a callback. @@ -153,10 +156,12 @@ void LogicHandler::RemoveCallback(CallbackPoint point, LevelFunc const & lf) } } - static constexpr char const* strKey = "__internal_name"; void LogicHandler::ResetLevelTables() { - MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelVars, &GetVariable, &SetVariable); + auto state = m_handler.GetState(); + MakeSpecialTable(state, ScriptReserved_LevelVars, &GetVariable, &SetVariable); + + (*state)[ScriptReserved_LevelVars][ScriptReserved_Engine] = sol::table{ *state, sol::create }; } sol::object LogicHandler::GetLevelFuncsMember(sol::table tab, std::string const& luaName) @@ -177,13 +182,24 @@ sol::object LogicHandler::GetLevelFuncsMember(sol::table tab, std::string const& void LogicHandler::CallLevelFunc(std::string const & name, float dt) { sol::protected_function f = m_levelFuncs_luaFunctions[name]; - f.call(dt); + auto r = f.call(dt); + + if (!r.valid()) + { + sol::error err = r; + ScriptAssertF(false, "Could not execute function {}: {}", name, err.what()); + } } void LogicHandler::CallLevelFunc(std::string const & name, sol::variadic_args va) { sol::protected_function f = m_levelFuncs_luaFunctions[name]; - f.call(va); + auto r = f.call(va); + if (!r.valid()) + { + sol::error err = r; + ScriptAssertF(false, "Could not execute function {}: {}", name, err.what()); + } } bool LogicHandler::SetLevelFuncsMember(sol::table tab, std::string const& luaName, sol::object value) @@ -274,14 +290,14 @@ void LogicHandler::ResetScripts(bool clearGameVars) void LogicHandler::FreeLevelScripts() { - //m_levelFuncs.clear(); - //m_levelFuncs = m_levelFuncs = MakeSpecialTable(m_handler.GetState(), ScriptReserved_LevelFuncs, &LogicHandler::GetLevelFuncsMember, &LogicHandler::SetLevelFuncsMember, this); m_levelFuncs.raw_set(strKey, ScriptReserved_LevelFuncs); + m_levelFuncs[ScriptReserved_Engine] = sol::table{ *m_handler.GetState(), sol::create }; + m_levelFuncs_tablesOfNames.clear(); m_levelFuncs_luaFunctions.clear(); - m_levelFuncs_levelFuncObjects = sol::table{ *(m_handler.GetState()), sol::create }; + m_levelFuncs_levelFuncObjects = sol::table{ *m_handler.GetState(), sol::create }; m_levelFuncs_tablesOfNames.emplace(std::make_pair(ScriptReserved_LevelFuncs, std::unordered_map{})); @@ -591,36 +607,25 @@ void LogicHandler::ExecuteScriptFile(const std::string & luaFilename) m_handler.ExecuteScript(luaFilename); } +// These wind up calling CallLevelFunc, which is where all the error checking is. void LogicHandler::ExecuteFunction(std::string const& name, short idOne, short idTwo) { - sol::protected_function_result r; sol::protected_function func = m_levelFuncs_luaFunctions[name]; - r = func(std::make_unique(idOne), std::make_unique(idTwo)); - if (!r.valid()) - { - sol::error err = r; - ScriptAssertF(false, "Could not execute function {}: {}", name, err.what()); - } + func(std::make_unique(idOne), std::make_unique(idTwo)); + } void LogicHandler::ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer triggerer, std::string const& arguments) { - sol::protected_function_result r; sol::protected_function func = (*m_handler.GetState())["LevelFuncs"][name.c_str()]; if (std::holds_alternative(triggerer)) { - r = func(std::make_unique(std::get(triggerer), true), arguments); + func(std::make_unique(std::get(triggerer), true), arguments); } else { - r = func(nullptr, arguments); - } - - if (!r.valid()) - { - sol::error err = r; - ScriptAssertF(false, "Could not execute function {}: {}", name, err.what()); + func(nullptr, arguments); } } @@ -704,6 +709,9 @@ some time later, the values `3` will be put back into `LevelVars.enemiesKilled.` __This table is emptied when a level is finished.__ If the player needs to be able to return to the level (like in the Karnak and Alexandria levels in *The Last Revelation*), you will need to use the @{GameVars} table, below. + +__LevelVars.Engine is a reserved table used internally by TombEngine's libs. Do not modify, overwrite, or add to it.__ + @table LevelVars */ @@ -724,6 +732,9 @@ And in the script file for the level with the boss, you could write: end Unlike @{LevelVars}, this table will remain intact for the entirety of the game. + +__GameVars.Engine is a reserved table used internally by TombEngine's libs. Do not modify, overwrite, or add to it.__ + @table GameVars */ @@ -750,10 +761,10 @@ You can organise functions into tables within the hierarchy: -- implementation goes here end -There are two special subtables which you should not overwrite: +There are two special subtables which you should __not__ overwrite: - LevelFuncs.TEN -- this is for 'first-party' functions, i.e. ones that come with TombEngine. - LevelFuncs.Ext -- this is for 'third-party' functions. If you write a library providing LevelFuncs functions for other builders to use in their levels, put those functions in LevelFuncs.Ext.YourLibraryNameHere + LevelFuncs.Engine -- this is for 'first-party' functions, i.e. ones that come with TombEngine. + LevelFuncs.External -- this is for 'third-party' functions. If you write a library providing LevelFuncs functions for other builders to use in their levels, put those functions in LevelFuncs.External.YourLibraryNameHere The following are the level callbacks. They are optional; if your level has no special behaviour for a particular scenario, you do not need to implement the function. For From ffbcf6601bcbe576e721e82844e3ddf054aafb48 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 7 Sep 2022 20:57:50 +0100 Subject: [PATCH 077/106] Fix documentation and some comments. --- Documentation/config.ld | 2 +- Documentation/doc/1 modules/Effects.html | 2 +- Documentation/doc/1 modules/Flow.html | 59 ++- Documentation/doc/1 modules/Inventory.html | 2 +- Documentation/doc/1 modules/Logic.html | 59 ++- Documentation/doc/1 modules/Misc.html | 2 +- Documentation/doc/1 modules/Objects.html | 2 +- Documentation/doc/1 modules/Strings.html | 2 +- .../doc/2 classes/Flow.Animations.html | 2 +- Documentation/doc/2 classes/Flow.Fog.html | 2 +- .../doc/2 classes/Flow.InventoryItem.html | 2 +- Documentation/doc/2 classes/Flow.Level.html | 2 +- Documentation/doc/2 classes/Flow.Mirror.html | 2 +- .../doc/2 classes/Flow.Settings.html | 2 +- .../doc/2 classes/Flow.SkyLayer.html | 2 +- .../doc/2 classes/Objects.AIObject.html | 2 +- .../doc/2 classes/Objects.Camera.html | 2 +- .../doc/2 classes/Objects.Moveable.html | 390 +++++++++--------- Documentation/doc/2 classes/Objects.Sink.html | 2 +- .../doc/2 classes/Objects.SoundSource.html | 2 +- .../doc/2 classes/Objects.Static.html | 51 ++- .../doc/2 classes/Strings.DisplayString.html | 2 +- .../doc/3 primitive classes/Color.html | 2 +- .../doc/3 primitive classes/Rotation.html | 2 +- .../doc/3 primitive classes/Vec3.html | 2 +- .../doc/4 enums/Effects.BlendID.html | 2 +- Documentation/doc/4 enums/Flow.InvID.html | 2 +- Documentation/doc/4 enums/Objects.ObjID.html | 2 +- .../5 lua utility modules/EventSequence.html | 12 +- .../doc/5 lua utility modules/Timer.html | 21 +- .../doc/5 lua utility modules/Util.html | 2 +- Documentation/doc/index.html | 4 +- .../Internal/TEN/Logic/LogicHandler.h | 12 +- 33 files changed, 384 insertions(+), 274 deletions(-) diff --git a/Documentation/config.ld b/Documentation/config.ld index 7da4273b6..3be1dfb60 100644 --- a/Documentation/config.ld +++ b/Documentation/config.ld @@ -24,7 +24,7 @@ Other than the "special tables" (GameVars, LevelVars and LevelFuncs), every modu For example, to call GetMoveableByName, you would have to do: local door = TEN.Objects.GetMoveableByName("door_type4_14") To save on typing, you can put the following at the start of a Lua file: - local Util = require("TEN.Util") + local Util = require("Engine.Util") Util.ShortenTENCalls() This will put the modules and classes in the global table. In other words, it means you can do the following: local door = GetMoveableByName("door_type4_14") diff --git a/Documentation/doc/1 modules/Effects.html b/Documentation/doc/1 modules/Effects.html index 96a620603..7bf7efdbe 100644 --- a/Documentation/doc/1 modules/Effects.html +++ b/Documentation/doc/1 modules/Effects.html @@ -511,7 +511,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/1 modules/Flow.html b/Documentation/doc/1 modules/Flow.html index 058eb30e2..8b0d52a9b 100644 --- a/Documentation/doc/1 modules/Flow.html +++ b/Documentation/doc/1 modules/Flow.html @@ -102,6 +102,14 @@ Add a level to the Flow. + GetLevel(id) + GetLevel. + + + GetCurrentLevel() + GetCurrentLevel. + + SetIntroImagePath(path) Image to show when loading the game. @@ -173,6 +181,55 @@ ambient tracks. + +
    + + GetLevel(id) +
    +
    + GetLevel. +Returns the level indicated by the parameter id. + + +

    Parameters:

    +
      +
    • id + int + of the level +
    • +
    + +

    Returns:

    +
      + + Level + the level indicated by the id +
    + + + + +
    +
    + + GetCurrentLevel() +
    +
    + GetCurrentLevel. +Returns the level that the game control is running in that moment. + + + +

    Returns:

    +
      + + Level + the current level +
    + + + +
    @@ -353,7 +410,7 @@ Specify which translations in the strings table correspond to which languages.
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/1 modules/Inventory.html b/Documentation/doc/1 modules/Inventory.html index d1f5c39fe..06117ac3e 100644 --- a/Documentation/doc/1 modules/Inventory.html +++ b/Documentation/doc/1 modules/Inventory.html @@ -239,7 +239,7 @@ Similar to GiveItem but repla
    generated by LDoc 1.4.6 -Last updated 2022-08-24 15:00:16 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/1 modules/Logic.html b/Documentation/doc/1 modules/Logic.html index 9c1deb41d..e624351e2 100644 --- a/Documentation/doc/1 modules/Logic.html +++ b/Documentation/doc/1 modules/Logic.html @@ -98,11 +98,11 @@

    Functions

    - + - +
    AddCallback(CallbackPoint, string)AddCallback(CallbackPoint, func) Register a function as a callback.
    RemoveCallback(CallbackPoint, string)RemoveCallback(CallbackPoint, LevelFunc) Deregister a function as a callback.
    @@ -125,7 +125,7 @@ LevelFuncs - A table with level-specific functions. + A table nested table system for level-specific functions. @@ -138,7 +138,7 @@
    - AddCallback(CallbackPoint, string) + AddCallback(CallbackPoint, func)
    Register a function as a callback. @@ -148,7 +148,9 @@ POSTCONTROLPHASE -- will be called immediately after OnControlPhase

    The order in which two functions with the same CallbackPoint are called is undefined. -i.e. if you register MyFunc and MyFunc2 with PRECONTROLPHASE, both will be called before OnControlPhase, but there is no guarantee whether MyFunc will be called before MyFunc2, or vice-versa. +i.e. if you register MyFunc and MyFunc2 with PRECONTROLPHASE, both will be called before OnControlPhase, but there is no guarantee whether MyFunc will be called before MyFunc2, or vice-versa.

    + +

    Any returned value will be discarded.

    Parameters:

    @@ -157,9 +159,9 @@ i.e. if you register MyFunc and MyFunc2 with PRE point When should the callback be called? -
  • string - func - The LevelFuncs function to be called. Will receive as an argument the time in seconds since the last frame. +
  • func + function + The function to be called (must be in the LevelFuncs hierarchy). Will receive, as an argument, the time in seconds since the last frame.
  • @@ -169,13 +171,13 @@ i.e. if you register MyFunc and MyFunc2 with PRE

    Usage:

      LevelFuncs.MyFunc = function(dt) print(dt) end
      -TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, "MyFunc")
      +TEN.Logic.AddCallback(TEN.Logic.CallbackPoint.PRECONTROLPHASE, LevelFuncs.MyFunc)
    - RemoveCallback(CallbackPoint, string) + RemoveCallback(CallbackPoint, LevelFunc)
    Deregister a function as a callback. @@ -188,9 +190,9 @@ Will have no effect if the function was not registered as a callback point The callback point the function was registered with. See AddCallback -
  • string +
  • LevelFunc func - The LevelFuncs function to remove. + the function to remove; must be in the LevelFuncs hierarchy.
  • @@ -248,7 +250,9 @@ some time later, the values 3 will be put back into LevelVars

    This table is emptied when a level is finished. If the player needs to be able to return to the level (like in the Karnak and Alexandria levels in The Last Revelation), -you will need to use the GameVars table, below. +you will need to use the GameVars table, below.

    + +

    LevelVars.Engine is a reserved table used internally by TombEngine's libs. Do not modify, overwrite, or add to it. @@ -280,7 +284,9 @@ write:

    end
    -

    Unlike LevelVars, this table will remain intact for the entirety of the game. +

    Unlike LevelVars, this table will remain intact for the entirety of the game.

    + +

    GameVars.Engine is a reserved table used internally by TombEngine's libs. Do not modify, overwrite, or add to it. @@ -295,9 +301,9 @@ end

    -

    A table with level-specific functions.

    +

    A table nested table system for level-specific functions.

    -

    This serves two purposes: it holds the level callbacks (listed below) as well as +

    This serves a few purposes: it holds the level callbacks (listed below) as well as any trigger functions you might have specified. For example, if you give a trigger a Lua name of "my_trigger" in Tomb Editor, you will have to implement it as a member of this table:

    @@ -307,6 +313,25 @@ of this table:

    end
    +

    You can organise functions into tables within the hierarchy:

    + +
    LevelFuncs.enemyFuncs = {}
    +
    +LevelFuncs.enemyFuncs.makeBaddyRunAway = function()
    +    -- implementation goes here
    +end
    +
    +LevelFuncs.enemyFuncs.makeBaddyUseMedkit = function()
    +    -- implementation goes here
    +end
    +
    + +

    There are two special subtables which you should not overwrite:

    + +
    LevelFuncs.Engine -- this is for 'first-party' functions, i.e. ones that come with TombEngine.
    +LevelFuncs.External -- this is for 'third-party' functions. If you write a library providing LevelFuncs functions for other builders to use in their levels, put those functions in LevelFuncs.External.YourLibraryNameHere
    +
    +

    The following are the level callbacks. They are optional; if your level has no special behaviour for a particular scenario, you do not need to implement the function. For example, if your level does not need any special initialisation when it is loaded, @@ -362,7 +387,7 @@ and provides the delta time (a float representing game time since last call) via

    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/1 modules/Misc.html b/Documentation/doc/1 modules/Misc.html index e49ef1a65..8880a8651 100644 --- a/Documentation/doc/1 modules/Misc.html +++ b/Documentation/doc/1 modules/Misc.html @@ -632,7 +632,7 @@ To be used with
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/1 modules/Objects.html b/Documentation/doc/1 modules/Objects.html index fbd3e71bd..7d8b1ae03 100644 --- a/Documentation/doc/1 modules/Objects.html +++ b/Documentation/doc/1 modules/Objects.html @@ -297,7 +297,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/1 modules/Strings.html b/Documentation/doc/1 modules/Strings.html index 0bc83ae5d..34beb1d6a 100644 --- a/Documentation/doc/1 modules/Strings.html +++ b/Documentation/doc/1 modules/Strings.html @@ -169,7 +169,7 @@ with a call to ShowString, or
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.Animations.html b/Documentation/doc/2 classes/Flow.Animations.html index 956dc4fca..8da244820 100644 --- a/Documentation/doc/2 classes/Flow.Animations.html +++ b/Documentation/doc/2 classes/Flow.Animations.html @@ -100,7 +100,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.Fog.html b/Documentation/doc/2 classes/Flow.Fog.html index f64efa973..42069ed14 100644 --- a/Documentation/doc/2 classes/Flow.Fog.html +++ b/Documentation/doc/2 classes/Flow.Fog.html @@ -227,7 +227,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-24 15:00:16 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.InventoryItem.html b/Documentation/doc/2 classes/Flow.InventoryItem.html index b5e5dd9c2..96426d73b 100644 --- a/Documentation/doc/2 classes/Flow.InventoryItem.html +++ b/Documentation/doc/2 classes/Flow.InventoryItem.html @@ -182,7 +182,7 @@ EXAMINE
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.Level.html b/Documentation/doc/2 classes/Flow.Level.html index 4a604d46c..63fd5278f 100644 --- a/Documentation/doc/2 classes/Flow.Level.html +++ b/Documentation/doc/2 classes/Flow.Level.html @@ -496,7 +496,7 @@ Must be at least 4.

    generated by LDoc 1.4.6 -Last updated 2022-08-24 15:00:16 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.Mirror.html b/Documentation/doc/2 classes/Flow.Mirror.html index 4f4f07877..8cc80d69e 100644 --- a/Documentation/doc/2 classes/Flow.Mirror.html +++ b/Documentation/doc/2 classes/Flow.Mirror.html @@ -100,7 +100,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.Settings.html b/Documentation/doc/2 classes/Flow.Settings.html index 6214d9b3c..99e9f061a 100644 --- a/Documentation/doc/2 classes/Flow.Settings.html +++ b/Documentation/doc/2 classes/Flow.Settings.html @@ -143,7 +143,7 @@ has an unrecoverable error, the game will close.
    generated by LDoc 1.4.6 -Last updated 2022-08-24 15:00:16 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Flow.SkyLayer.html b/Documentation/doc/2 classes/Flow.SkyLayer.html index bb74f9213..4e4d6b59f 100644 --- a/Documentation/doc/2 classes/Flow.SkyLayer.html +++ b/Documentation/doc/2 classes/Flow.SkyLayer.html @@ -199,7 +199,7 @@ Less is more. City of The Dead, for example, uses a speed value of 16.
    generated by LDoc 1.4.6 -Last updated 2022-08-24 15:00:16 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Objects.AIObject.html b/Documentation/doc/2 classes/Objects.AIObject.html index c2a673b47..c6a4ae64c 100644 --- a/Documentation/doc/2 classes/Objects.AIObject.html +++ b/Documentation/doc/2 classes/Objects.AIObject.html @@ -372,7 +372,7 @@ aiObj:SetObjectID(TEN.Objects.ObjID.AI_PATROL1)
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Objects.Camera.html b/Documentation/doc/2 classes/Objects.Camera.html index ed23fa7e6..51bd92538 100644 --- a/Documentation/doc/2 classes/Objects.Camera.html +++ b/Documentation/doc/2 classes/Objects.Camera.html @@ -260,7 +260,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Objects.Moveable.html b/Documentation/doc/2 classes/Objects.Moveable.html index a945e9401..7ea645ded 100644 --- a/Documentation/doc/2 classes/Objects.Moveable.html +++ b/Documentation/doc/2 classes/Objects.Moveable.html @@ -124,39 +124,6 @@ associated getters and setters. Get the status of object. - Moveable:SetOnHit(name) - Set the name of the function to be called when the moveable is shot by Lara - Note that this will be triggered twice when shot with both pistols at once. - - - Moveable:GetOnHit() - Get the name of the function called when this moveable is shot - - - Moveable:SetOnCollidedWithObject(name) - Set the name of the function called when this moveable collides with another moveable - - - Moveable:GetOnCollidedWithObject() - Get the name of the function called when this moveable collides with another moveable - - - Moveable:SetOnCollidedWithRoom(name) - Set the name of the function called when this moveable collides with room geometry (e.g. - - - Moveable:GetOnCollidedWithRoom() - Get the name of the function called when this moveable collides with room geometry (e.g. - - - Moveable:SetOnKilled(callback) - Set the name of the function to be called when the moveable is destroyed/killed - - - Moveable:GetOnKilled() - Get the name of the function called when this moveable is killed - - Moveable:GetObjectID() Retrieve the object ID @@ -197,6 +164,10 @@ associated getters and setters. Set current HP (hit points/health points) + Moveable:GetSlotHP(ID) + Get HP definded for that object type (hit points/health points) (Read Only). + + Moveable:GetOCB() Get OCB (object code bit) of the moveable @@ -205,6 +176,14 @@ associated getters and setters. Set OCB (object code bit) of the moveable + Moveable:GetItemFlags() + Get the value stored in ItemFlags[x] (x is the value of the parameter) + + + Moveable:SetItemFlags(value) + Stores the value of the first parameter in the ItemFlags[x] (x is the value of the second parameter) + + Moveable:GetColor() Get the moveable's color @@ -300,6 +279,25 @@ associated getters and setters. Destroy the moveable. + Moveable:SetOnHit(callback) + Set the name of the function to be called when the moveable is shot by Lara + Note that this will be triggered twice when shot with both pistols at once. + + + Moveable:SetOnKilled(callback) + Set the name of the function to be called when the moveable is destroyed/killed + Note that enemy death often occurs at the end of an animation, and not at the exact moment + the enemy's HP becomes zero. + + + Moveable:SetOnCollidedWithObject(func) + Set the function to be called called when this moveable collides with another moveable + + + Moveable:SetOnCollidedWithRoom(func) + Set the function called when this moveable collides with room geometry (e.g. + + Moveable:GetPosition() Get the object's position @@ -500,176 +498,6 @@ most can just be ignored (see usage). -
    -
    - - Moveable:SetOnHit(name) -
    -
    - Set the name of the function to be called when the moveable is shot by Lara - Note that this will be triggered twice when shot with both pistols at once. - - -

    Parameters:

    -
      -
    • name - string - of callback function to be called -
    • -
    - - - - - -
    -
    - - Moveable:GetOnHit() -
    -
    - Get the name of the function called when this moveable is shot - - - -

    Returns:

    -
      - - string - name of the function -
    - - - - -
    -
    - - Moveable:SetOnCollidedWithObject(name) -
    -
    - Set the name of the function called when this moveable collides with another moveable - - -

    Parameters:

    -
      -
    • name - string - of callback function to be called -
    • -
    - - - - - -
    -
    - - Moveable:GetOnCollidedWithObject() -
    -
    - Get the name of the function called when this moveable collides with another moveable - - - -

    Returns:

    -
      - - string - name of the function -
    - - - - -
    -
    - - Moveable:SetOnCollidedWithRoom(name) -
    -
    - Set the name of the function called when this moveable collides with room geometry (e.g. a wall or floor) - - -

    Parameters:

    -
      -
    • name - string - of callback function to be called -
    • -
    - - - - - -
    -
    - - Moveable:GetOnCollidedWithRoom() -
    -
    - Get the name of the function called when this moveable collides with room geometry (e.g. a wall or floor) - - - -

    Returns:

    -
      - - string - name of the function -
    - - - - -
    -
    - - Moveable:SetOnKilled(callback) -
    -
    - Set the name of the function to be called when the moveable is destroyed/killed - - -

    Parameters:

    -
      -
    • callback - string - name of function to be called -
    • -
    - - - - -

    Usage:

    -
      -
      LevelFuncs.baddyKilled = function(theBaddy) print("You killed a baddy!") end
      -baddy:SetOnKilled("baddyKilled")
      -
    - -
    -
    - - Moveable:GetOnKilled() -
    -
    - Get the name of the function called when this moveable is killed - - - -

    Returns:

    -
      - - string - name of the function -
    - - - -
    @@ -891,6 +719,27 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) + +
    + + Moveable:GetSlotHP(ID) +
    +
    + Get HP definded for that object type (hit points/health points) (Read Only). + + +

    Parameters:

    +
      +
    • ID + int + of the moveable slot type. +
    • +
    + + + + +
    @@ -932,6 +781,47 @@ shiva:SetObjectID(TEN.Objects.ObjID.BIGMEDI_ITEM) + +
    + + Moveable:GetItemFlags() +
    +
    + Get the value stored in ItemFlags[x] (x is the value of the parameter) + + + +

    Returns:

    +
      + + short + id of the ItemFlags array +
    + + + + +
    +
    + + Moveable:SetItemFlags(value) +
    +
    + Stores the value of the first parameter in the ItemFlags[x] (x is the value of the second parameter) + + +

    Parameters:

    +
      +
    • value + short + to store in the moveable's ItemFlags[x], short id of ItemFlags array to store the value. +
    • +
    + + + + +
    @@ -1393,6 +1283,98 @@ sas:SetAIBits({1, 0, +
    + + Moveable:SetOnHit(callback) +
    +
    + Set the name of the function to be called when the moveable is shot by Lara + Note that this will be triggered twice when shot with both pistols at once. + + +

    Parameters:

    +
      +
    • callback + function + function in LevelFuncs hierarchy to call when moveable is shot +
    • +
    + + + + + +
    +
    + + Moveable:SetOnKilled(callback) +
    +
    + Set the name of the function to be called when the moveable is destroyed/killed + Note that enemy death often occurs at the end of an animation, and not at the exact moment + the enemy's HP becomes zero. + + +

    Parameters:

    +
      +
    • callback + function + function in LevelFuncs hierarchy to call when enemy is killed +
    • +
    + + + + +

    Usage:

    +
      +
      LevelFuncs.baddyKilled = function(theBaddy) print("You killed a baddy!") end
      +baddy:SetOnKilled(LevelFuncs.baddyKilled)
      +
    + +
    +
    + + Moveable:SetOnCollidedWithObject(func) +
    +
    + Set the function to be called called when this moveable collides with another moveable + + +

    Parameters:

    +
      +
    • func + function + callback function to be called (must be in LevelFuncs hierarchy) +
    • +
    + + + + + +
    +
    + + Moveable:SetOnCollidedWithRoom(func) +
    +
    + Set the function called when this moveable collides with room geometry (e.g. a wall or floor) + + +

    Parameters:

    +
      +
    • func + function + callback function to be called (must be in LevelFuncs hierarchy) +
    • +
    + + + + +
    @@ -1498,7 +1480,7 @@ sas:SetPosition(destinationPosition, false)
    generated by LDoc 1.4.6 -Last updated 2022-08-26 00:12:28 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Objects.Sink.html b/Documentation/doc/2 classes/Objects.Sink.html index bb1d7e3f7..616bf6071 100644 --- a/Documentation/doc/2 classes/Objects.Sink.html +++ b/Documentation/doc/2 classes/Objects.Sink.html @@ -262,7 +262,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Objects.SoundSource.html b/Documentation/doc/2 classes/Objects.SoundSource.html index f75d1282c..e500057ee 100644 --- a/Documentation/doc/2 classes/Objects.SoundSource.html +++ b/Documentation/doc/2 classes/Objects.SoundSource.html @@ -260,7 +260,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Objects.Static.html b/Documentation/doc/2 classes/Objects.Static.html index 4ec87c539..5a418e622 100644 --- a/Documentation/doc/2 classes/Objects.Static.html +++ b/Documentation/doc/2 classes/Objects.Static.html @@ -112,6 +112,14 @@ Set the static's rotation + Static:GetScale() + Get the static's scale + + + Static:SetScale(scale) + Set the static's scale + + Static:GetName() Get the static's unique string identifier @@ -226,6 +234,47 @@ + +
    + + Static:GetScale() +
    +
    + Get the static's scale + + + +

    Returns:

    +
      + + float + current static scale +
    + + + + +
    +
    + + Static:SetScale(scale) +
    +
    + Set the static's scale + + +

    Parameters:

    +
      +
    • scale + Scale + the static's new scale +
    • +
    + + + + +
    @@ -358,7 +407,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/2 classes/Strings.DisplayString.html b/Documentation/doc/2 classes/Strings.DisplayString.html index 4448c7061..ff200ed44 100644 --- a/Documentation/doc/2 classes/Strings.DisplayString.html +++ b/Documentation/doc/2 classes/Strings.DisplayString.html @@ -307,7 +307,7 @@ TEN.Strings.DisplayStringOption.SHADOW -- will give the text a small shadow
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/3 primitive classes/Color.html b/Documentation/doc/3 primitive classes/Color.html index ae3beb4e4..8f3cc8700 100644 --- a/Documentation/doc/3 primitive classes/Color.html +++ b/Documentation/doc/3 primitive classes/Color.html @@ -312,7 +312,7 @@
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/3 primitive classes/Rotation.html b/Documentation/doc/3 primitive classes/Rotation.html index 8a3550d64..16168f482 100644 --- a/Documentation/doc/3 primitive classes/Rotation.html +++ b/Documentation/doc/3 primitive classes/Rotation.html @@ -250,7 +250,7 @@ All values will be clamped to [-32768, 32767].

    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/3 primitive classes/Vec3.html b/Documentation/doc/3 primitive classes/Vec3.html index 3854494cc..f4548ddf3 100644 --- a/Documentation/doc/3 primitive classes/Vec3.html +++ b/Documentation/doc/3 primitive classes/Vec3.html @@ -277,7 +277,7 @@ However, this function would return it as (0, 1, 1).
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/4 enums/Effects.BlendID.html b/Documentation/doc/4 enums/Effects.BlendID.html index e28f95e94..a9fc3635c 100644 --- a/Documentation/doc/4 enums/Effects.BlendID.html +++ b/Documentation/doc/4 enums/Effects.BlendID.html @@ -149,7 +149,7 @@ ALPHABLEND
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/4 enums/Flow.InvID.html b/Documentation/doc/4 enums/Flow.InvID.html index f8cc82a68..6730933b2 100644 --- a/Documentation/doc/4 enums/Flow.InvID.html +++ b/Documentation/doc/4 enums/Flow.InvID.html @@ -358,7 +358,7 @@ EXAMINE_ITEM8_COMBO2
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/4 enums/Objects.ObjID.html b/Documentation/doc/4 enums/Objects.ObjID.html index d7319e080..ea092e640 100644 --- a/Documentation/doc/4 enums/Objects.ObjID.html +++ b/Documentation/doc/4 enums/Objects.ObjID.html @@ -1096,7 +1096,7 @@ PANEL_MIDDLE_CORNER
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/5 lua utility modules/EventSequence.html b/Documentation/doc/5 lua utility modules/EventSequence.html index 456664b91..de2ccbfc4 100644 --- a/Documentation/doc/5 lua utility modules/EventSequence.html +++ b/Documentation/doc/5 lua utility modules/EventSequence.html @@ -96,7 +96,7 @@

    Example usage:

    -local EventSequence = require("EventSequence")
    +local EventSequence = require("Engine.EventSequence")
     
     -- These will be called by the sequence
     LevelFuncs.HealLara = function()
    @@ -118,13 +118,13 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
             false, -- does not loop
             {seconds = true, deciseconds = true}, -- timer format, see Timer for details
             6, -- seconds until call the function specified in next arg
    -        "HealLara", -- first function to call. If we don't need to pass any arguments, we can just give the func name as a string
    +        LevelFuncs.HealLara, -- first function to call. If we don't need to pass any arguments, we can just pass the function
             2.1, -- seconds until the next function, after the previous one has been called
    -        {"SpawnBaddy", TEN.Objects.ObjID.BADDY1, "steve", posSteve}, -- if we DO want to pass arguments to the function to be called, we give a table with the name of the function ("SpawnBaddy" in this case) followed by the args to pass to it
    +        {LevelFuncs.SpawnBaddy, TEN.Objects.ObjID.BADDY1, "steve", posSteve}, -- if we DO want to pass arguments to the function to be called, we give a table with the function (LevelFuncs.SpawnBaddy in this case) followed by the args to pass to it
             0.5,
    -        {"SpawnBaddy", TEN.Objects.ObjID.SAS_CAIRO, "chris", posChris},
    +        {LevelFuncs.SpawnBaddy, TEN.Objects.ObjID.SAS_CAIRO, "chris", posChris},
             1,
    -        "HealLara")
    +        LevelFuncs.HealLara)
     
         -- event sequences are inactive to begin with and so need to be started
         mySeq:Start()
    @@ -331,7 +331,7 @@ LevelFuncs.SpawnBaddy = function(baddy, name, pos)
      
     
    generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
    diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index 493b98dee..1ed60812c 100644 --- a/Documentation/doc/5 lua utility modules/Timer.html +++ b/Documentation/doc/5 lua utility modules/Timer.html @@ -96,7 +96,7 @@

    Example usage:

    -local Timer = require("Timer")
    +local Timer = require("Engine.Timer")
     
     -- This will be called when the timer runs out
     LevelFuncs.FinishTimer = function(healthWhenStarted, victoryMessage)
    @@ -110,7 +110,7 @@
             5.0,
             false,
             {minutes = false, seconds = true, deciseconds = true},
    -        "FinishTimer",
    +        LevelFuncs.FinishTimer,
             Lara:GetHP(),
             "Well done!")
         myTimer:Start()
    @@ -123,7 +123,7 @@
     

    Functions

    - + @@ -184,8 +184,8 @@
    - - Create(name, totalTime, loop, timerFormat, func[, ...]) + + func(name, totalTime, loop, timerFormat[, ...])
    Create (but do not start) a new timer.

    @@ -210,6 +210,7 @@ local myTimeFormat4 = {seconds = true}

    At any given time, only one timer can show its countdown.

    Use this sparingly; in the classics, timed challenges did not have visible countdowns. For shorter timers, the gameplay benefit from showing the remaining time might not be necessary, and could interfere with the atmosphere of the level. + The LevelFunc function to call when the time is up

    Parameters:

    @@ -230,10 +231,6 @@ local myTimeFormat4 = {seconds = true} table or bool If a table is given, the remaining time will be shown as a string, formatted according to the values in the table. If true, the remaining seconds, rounded up, will show at the bottom of the screen. If false, the remaining time will not be shown on screen. -
  • func - string - The name of the LevelFunc member to call when the time is upssss -
  • ... a variable number of arguments with which the above function will be called (optional) @@ -287,8 +284,8 @@ local myTimeFormat4 = {seconds = true}

    Parameters:

    • func - string - The name of the LevelFunc member to call when the time is up + function + The LevelFunc member to call when the time is up
    • ... a variable number of arguments with which the above function will be called @@ -497,7 +494,7 @@ local myTimeFormat4 = {seconds = true}
      generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
      diff --git a/Documentation/doc/5 lua utility modules/Util.html b/Documentation/doc/5 lua utility modules/Util.html index 4b016dc95..3d5ae7bb3 100644 --- a/Documentation/doc/5 lua utility modules/Util.html +++ b/Documentation/doc/5 lua utility modules/Util.html @@ -138,7 +138,7 @@
      generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
      diff --git a/Documentation/doc/index.html b/Documentation/doc/index.html index 99e56b692..e6d470ea8 100644 --- a/Documentation/doc/index.html +++ b/Documentation/doc/index.html @@ -90,7 +90,7 @@ For example, to call GetMoveableByName, you would have to do:

      local door = TEN.Objects.GetMoveableByName("door_type4_14")
       

      To save on typing, you can put the following at the start of a Lua file:

      -
      local Util = require("Util")
      +
      local Util = require("Engine.Util")
       Util.ShortenTENCalls()
       

      This will put the modules and classes in the global table. In other words, it means you can do the following:

      @@ -248,7 +248,7 @@ Util.ShortenTENCalls()
      generated by LDoc 1.4.6 -Last updated 2022-08-19 00:04:24 +Last updated 2022-09-07 20:56:06
      diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 81ff7fc3d..e2a2648d3 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -14,12 +14,12 @@ private: // // For example: // LevelFuncs - // |- TEN + // |- Engine // |- Timer // |- Util - // |- Ext - // |- MyLib - // |- MySecondLib + // |- External + // |- EnemiesBySteve + // |- BetterEnemiesByChris // |- SubTable // // Each of these tables can only contain other tables as well as a string with their "path". @@ -42,8 +42,8 @@ private: // of the functions to index in m_levelFuncs_luaFunctions. // Tables are non-nested, so the following are all at the base level of m_levelFuncsTables. // "LevelFuncs" - // "LevelFuncs.TEN" - // "LevelFuncs.TEN.Util" + // "LevelFuncs.Engine" + // "LevelFuncs.Engine.Util" // "LevelFuncs.MyLevel" // "LevelFuncs.MyLevel.CoolFuncs" std::unordered_map> m_levelFuncs_tablesOfNames{}; From d83ae45ba1f46243848238f514ad888402db5687 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 7 Sep 2022 21:12:02 +0100 Subject: [PATCH 078/106] Update starter scripts --- Scripts/New_Level.lua | 2 +- Scripts/Title.lua | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/New_Level.lua b/Scripts/New_Level.lua index c4e30aba4..eee9d00bf 100644 --- a/Scripts/New_Level.lua +++ b/Scripts/New_Level.lua @@ -1,7 +1,7 @@ -- New level script file. -- To include other script files, you can use require("filename") command. -local Util = require("TEN.Util") +local Util = require("Engine.Util") Util.ShortenTENCalls() -- Called when entering a level, either after leveljump, new game or loading game diff --git a/Scripts/Title.lua b/Scripts/Title.lua index 29d567b19..e6afcd88e 100644 --- a/Scripts/Title.lua +++ b/Scripts/Title.lua @@ -1,6 +1,6 @@ -- Title script file -local Util = require("TEN.Util") +local Util = require("Engine.Util") Util.ShortenTENCalls() LevelFuncs.OnLoad = function() end From 110b90aef0a2035d2600781b5b3690ed5d86b6c6 Mon Sep 17 00:00:00 2001 From: hispidence Date: Wed, 7 Sep 2022 21:13:37 +0100 Subject: [PATCH 079/106] Add script location movement to changes. --- Documentation/Changes.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index 707bed723..ed57bda6d 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -16,6 +16,7 @@ Version 1.0.2 * Fix Lara's subway train death so that she no longer slides slowly after the animation has finished. Lua API changes: +* Timer.lua, EventSequence.lua and Util.lua have been moved to a subfolder, Engine. * LevelFuncs can now contain tables as well as functions. These tables can contain functions and other tables, and so forth. * Moveable functions SetOnHit, SetOnKilled, SetOnCollidedWithObject and SetOnCollidedWithRoom no longer take strings, and instead take function objects themselves. The function still has to be in the LevelFuncs hierarchy: Before: From ecb6c864643a34e71a694aa8512e250ea84333d0 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 8 Sep 2022 02:26:06 +0300 Subject: [PATCH 080/106] Support for autogenerated node scripts (#722) * Initial Commit * Embed node scripts * Correct mistakes * Indicate node scripts loading in log file * Change path to be consistent * Update Changes.txt * Modify node catalogs script path * Add flow events * Fix EndLevel * Decopypaste shatter code, add shatter static script function * Load/save static mesh own room number instead of dummy one * More verbose logging for loading node scripts * Rename enum --- Documentation/Changes.txt | 1 + TombEngine/Game/Lara/lara_one_gun.cpp | 18 ----- TombEngine/Game/collision/collide_item.cpp | 4 -- TombEngine/Game/control/control.cpp | 6 +- TombEngine/Game/control/los.cpp | 4 -- TombEngine/Game/control/volume.cpp | 57 ++++++++++++++- TombEngine/Game/control/volume.h | 2 + TombEngine/Game/control/volumetriggerer.h | 4 +- TombEngine/Game/effects/debris.cpp | 8 +++ TombEngine/Game/room.h | 1 + TombEngine/Game/savegame.cpp | 3 +- .../Objects/TR4/Entity/tr4_knight_templar.cpp | 1 - .../Objects/TR4/Entity/tr4_skeleton.cpp | 1 - TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp | 1 - .../Objects/TR5/Entity/tr5_gladiator.cpp | 1 - TombEngine/Objects/TR5/Entity/tr5_gunship.cpp | 1 - .../Objects/TR5/Entity/tr5_roman_statue.cpp | 1 - TombEngine/Objects/TR5/Trap/tr5_explosion.cpp | 4 -- .../Scripting/Include/ScriptInterfaceGame.h | 1 + TombEngine/Scripting/Internal/LuaHandler.cpp | 2 +- .../Scripting/Internal/ReservedScriptNames.h | 4 ++ .../Internal/TEN/Flow/FlowHandler.cpp | 70 +++++++++++++++++++ .../Scripting/Internal/TEN/Flow/FlowHandler.h | 4 ++ .../Internal/TEN/Logic/LogicHandler.cpp | 38 +++------- .../Internal/TEN/Logic/LogicHandler.h | 1 + .../TEN/Objects/Static/StaticObject.cpp | 12 +++- .../TEN/Objects/Static/StaticObject.h | 1 + TombEngine/Sound/sound.cpp | 2 +- TombEngine/Specific/level.cpp | 13 ++-- TombEngine/Specific/level.h | 1 - 30 files changed, 181 insertions(+), 86 deletions(-) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index 49a241f14..ccfde162e 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -1,6 +1,7 @@ Version 1.0.2 ============= +* Support volume triggers made with node editor. * Adjust max turn rate of idle state. * Align Lara on slopes when crouching, crawling, and dying. * Better slope alignment for large, flat enemies (i.e. big scorpion and crocodile). diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp index c09b63b63..f2503f921 100644 --- a/TombEngine/Game/Lara/lara_one_gun.cpp +++ b/TombEngine/Game/Lara/lara_one_gun.cpp @@ -619,10 +619,6 @@ void HarpoonBoltControl(short itemNumber) auto pos = PHD_3DPOS(currentMesh->pos.Position.x, currentMesh->pos.Position.y - 128, currentMesh->pos.Position.z, 0, currentMesh->pos.Orientation.y, 0); TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0); ShatterObject(nullptr, currentMesh, -128, item->RoomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = item->RoomNumber; - SmashedMesh[SmashedMeshCount] = currentMesh; - SmashedMeshCount++; - currentMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; } } @@ -1007,10 +1003,6 @@ void GrenadeControl(short itemNumber) auto pos = PHD_3DPOS(currentMesh->pos.Position.x, currentMesh->pos.Position.y - 128, currentMesh->pos.Position.z, 0, currentMesh->pos.Orientation.y, 0); TriggerShockwave(&pos, 40, 176, 64, 0, 96, 128, 16, 0, 0); ShatterObject(nullptr, currentMesh, -128, item->RoomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = item->RoomNumber; - SmashedMesh[SmashedMeshCount] = currentMesh; - SmashedMeshCount++; - currentMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; } } @@ -1317,10 +1309,6 @@ void RocketControl(short itemNumber) auto pose = PHD_3DPOS(currentMesh->pos.Position.x, currentMesh->pos.Position.y - 128, currentMesh->pos.Position.z, 0, currentMesh->pos.Orientation.y, 0); TriggerShockwave(&pose, 40, 176, 64, 0, 96, 128, 16, 0, 0); ShatterObject(nullptr, currentMesh, -128, item->RoomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = item->RoomNumber; - SmashedMesh[SmashedMeshCount] = currentMesh; - SmashedMeshCount++; - currentMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; } } @@ -1599,13 +1587,7 @@ void CrossbowBoltControl(short itemNumber) { currentMesh->HitPoints -= Weapons[(int)LaraWeaponType::Crossbow].Damage; if (currentMesh->HitPoints <= 0) - { ShatterObject(nullptr, currentMesh, -128, item->RoomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = item->RoomNumber; - SmashedMesh[SmashedMeshCount] = currentMesh; - SmashedMeshCount++; - currentMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; - } } k++; diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 29be4477c..430d45138 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -1832,10 +1832,6 @@ void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll) { SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh); ShatterObject(nullptr, mesh, -128, laraItem->RoomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = laraItem->RoomNumber; - SmashedMesh[SmashedMeshCount] = mesh; - SmashedMeshCount++; - mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; } else if (coll->Setup.EnableObjectPush) ItemPushStatic(laraItem, mesh, coll); diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp index 68d0fd2d2..b962313aa 100644 --- a/TombEngine/Game/control/control.cpp +++ b/TombEngine/Game/control/control.cpp @@ -444,9 +444,8 @@ GameStatus DoTitle(int index, std::string const& ambient) g_Gui.SetMenuToDisplay(Menu::Title); g_Gui.SetSelectedOption(0); - // Initialise ponytails InitialiseHair(); - + InitialiseNodeScripts(); InitialiseItemBoxData(); g_GameScript->OnStart(); @@ -570,9 +569,8 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame) // Initialise flyby cameras InitSpotCamSequences(); - // Initialise ponytails InitialiseHair(); - + InitialiseNodeScripts(); InitialiseItemBoxData(); if (loadFromSavegame) diff --git a/TombEngine/Game/control/los.cpp b/TombEngine/Game/control/los.cpp index 5a4db8b71..76a221612 100644 --- a/TombEngine/Game/control/los.cpp +++ b/TombEngine/Game/control/los.cpp @@ -121,10 +121,6 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo ShatterImpactData.impactDirection = direction; ShatterImpactData.impactLocation = Vector3(mesh->pos.Position.x, mesh->pos.Position.y, mesh->pos.Position.z); ShatterObject(nullptr, mesh, 128, target2.roomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = target2.roomNumber; - SmashedMesh[SmashedMeshCount] = mesh; - ++SmashedMeshCount; - mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh); } diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp index 0f0b651b4..7a950b140 100644 --- a/TombEngine/Game/control/volume.cpp +++ b/TombEngine/Game/control/volume.cpp @@ -1,6 +1,7 @@ #include "framework.h" #include "Game/control/volume.h" +#include #include "Game/animation.h" #include "Game/items.h" #include "Game/Lara/lara.h" @@ -79,7 +80,7 @@ namespace TEN::Control::Volumes volume->Status = TriggerStatus::Entering; if (!set->OnEnter.Function.empty() && set->OnEnter.CallCounter != 0) { - g_GameScript->ExecuteFunction(set->OnEnter.Function, triggerer, set->OnEnter.Argument); + g_GameScript->ExecuteFunction(set->OnEnter.Function, triggerer, set->OnEnter.Data); if (set->OnEnter.CallCounter != NO_CALL_COUNTER) set->OnEnter.CallCounter--; } @@ -89,7 +90,7 @@ namespace TEN::Control::Volumes volume->Status = TriggerStatus::Inside; if (!set->OnInside.Function.empty() && set->OnInside.CallCounter != 0) { - g_GameScript->ExecuteFunction(set->OnInside.Function, triggerer, set->OnInside.Argument); + g_GameScript->ExecuteFunction(set->OnInside.Function, triggerer, set->OnInside.Data); if (set->OnInside.CallCounter != NO_CALL_COUNTER) set->OnInside.CallCounter--; } @@ -108,7 +109,7 @@ namespace TEN::Control::Volumes volume->Status = TriggerStatus::Leaving; if (!set->OnLeave.Function.empty() && set->OnLeave.CallCounter != 0) { - g_GameScript->ExecuteFunction(set->OnLeave.Function, triggerer, set->OnLeave.Argument); + g_GameScript->ExecuteFunction(set->OnLeave.Function, triggerer, set->OnLeave.Data); if (set->OnLeave.CallCounter != NO_CALL_COUNTER) set->OnLeave.CallCounter--; } @@ -155,4 +156,54 @@ namespace TEN::Control::Volumes else TestVolumes(item->RoomNumber, bbox, TriggerVolumeActivators::Movable, itemNumber); } + + void InitialiseNodeScripts() + { + static const std::string nodeScriptPath = "Scripts/Engine/NodeCatalogs/"; + + if (!std::filesystem::exists(nodeScriptPath)) + return; + + TENLog("Loading node scripts...", LogLevel::Info); + + bool anyScriptsFound = false; + for (auto& path : std::filesystem::recursive_directory_iterator(nodeScriptPath)) + { + if (path.path().extension() == ".lua") + { + g_GameScript->ExecuteScriptFile(path.path().string()); + anyScriptsFound = true; + } + } + + int nodeCount = 0; + for (auto& set : g_Level.EventSets) + { + if ((set.OnEnter.Mode == VolumeEventMode::Nodes) && (set.OnEnter.Data.size() > 0)) + { + g_GameScript->ExecuteString(set.OnEnter.Data); + nodeCount++; + } + + if ((set.OnInside.Mode == VolumeEventMode::Nodes) && (set.OnInside.Data.size() > 0)) + { + g_GameScript->ExecuteString(set.OnInside.Data); + nodeCount++; + } + + if ((set.OnLeave.Mode == VolumeEventMode::Nodes) && (set.OnLeave.Data.size() > 0)) + { + g_GameScript->ExecuteString(set.OnLeave.Data); + nodeCount++; + } + } + + if (nodeCount == 0) + return; + + if (!anyScriptsFound) + TENLog("Node catalogs are missing, but node scripts are present in level. Make sure node catalogs are in place.", LogLevel::Warning); + else + TENLog(std::to_string(nodeCount) + " node scripts found and loaded.", LogLevel::Info); + } } diff --git a/TombEngine/Game/control/volume.h b/TombEngine/Game/control/volume.h index c56c2c364..5cabe9baf 100644 --- a/TombEngine/Game/control/volume.h +++ b/TombEngine/Game/control/volume.h @@ -61,4 +61,6 @@ namespace TEN::Control::Volumes void TestVolumes(short itemNum); void TestVolumes(short roomNumber, MESH_INFO* mesh); void TestVolumes(CAMERA_INFO* camera); + + void InitialiseNodeScripts(); } diff --git a/TombEngine/Game/control/volumetriggerer.h b/TombEngine/Game/control/volumetriggerer.h index a88abe2f8..1050bc801 100644 --- a/TombEngine/Game/control/volumetriggerer.h +++ b/TombEngine/Game/control/volumetriggerer.h @@ -15,14 +15,14 @@ namespace TEN::Control::Volumes enum class VolumeEventMode { LevelScript, - Constructor + Nodes }; struct VolumeEvent { VolumeEventMode Mode; std::string Function; - std::string Argument; + std::string Data; int CallCounter; }; diff --git a/TombEngine/Game/effects/debris.cpp b/TombEngine/Game/effects/debris.cpp index d7409941b..4b3319063 100644 --- a/TombEngine/Game/effects/debris.cpp +++ b/TombEngine/Game/effects/debris.cpp @@ -69,11 +69,19 @@ void ShatterObject(SHATTER_ITEM* item, MESH_INFO* mesh, int num, short roomNumbe if (mesh) { + if (!(mesh->flags & StaticMeshFlags::SM_VISIBLE)) + return; + isStatic = true; meshIndex = StaticObjects[mesh->staticNumber].meshNumber; yRot = mesh->pos.Orientation.y; pos = Vector3(mesh->pos.Position.x, mesh->pos.Position.y, mesh->pos.Position.z); scale = mesh->scale; + + mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; + SmashedMeshRoom[SmashedMeshCount] = roomNumber; + SmashedMesh[SmashedMeshCount] = mesh; + SmashedMeshCount++; } else { diff --git a/TombEngine/Game/room.h b/TombEngine/Game/room.h index e5e1ab8ae..2157ed34d 100644 --- a/TombEngine/Game/room.h +++ b/TombEngine/Game/room.h @@ -42,6 +42,7 @@ struct ROOM_LIGHT struct MESH_INFO { PHD_3DPOS pos; + int roomNumber; float scale; short staticNumber; short flags; diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index 259180ced..306748fd7 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -818,7 +818,7 @@ bool SaveGame::Save(int slot) staticMesh.add_flags(room->mesh[j].flags); staticMesh.add_hit_points(room->mesh[j].HitPoints); - staticMesh.add_room_number(i); + staticMesh.add_room_number(room->mesh[j].roomNumber); staticMesh.add_number(j); staticMeshes.push_back(staticMesh.Finish()); } @@ -1235,6 +1235,7 @@ bool SaveGame::Load(int slot) int number = staticMesh->number(); room->mesh[number].pos = ToPHD(staticMesh->pose()); + room->mesh[number].roomNumber = staticMesh->room_number(); room->mesh[number].scale = staticMesh->scale(); room->mesh[number].color = ToVector4(staticMesh->color()); diff --git a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp index f211923c9..372bc1fea 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_knight_templar.cpp @@ -198,7 +198,6 @@ namespace TEN::Entities::TR4 ShatterObject(nullptr, mesh, -64, LaraItem->RoomNumber, 0); SoundEffect(SFX_TR4_SMASH_ROCK, &item->Pose); - mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; currentFloor->Stopper = false; TestTriggers(pos.x, pos.y, pos.z, item->RoomNumber, true); diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp index 5f3e68d0c..6cf745cad 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp @@ -633,7 +633,6 @@ namespace TEN::Entities::TR4 { ShatterObject(0, staticMesh, -128, LaraItem->RoomNumber, 0); SoundEffect(SFX_TR4_SMASH_ROCK, &item->Pose); - staticMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; floor->Stopper = false; TestTriggers(item, true); break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp index 6d309dca1..d8aab5f4b 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sphinx.cpp @@ -103,7 +103,6 @@ namespace TEN::Entities::TR4 ShatterObject(nullptr, mesh, -64, item->RoomNumber, 0); SoundEffect(SFX_TR4_SMASH_ROCK, &item->Pose); - mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; probe.Block = false; TestTriggers(x, y, z, item->RoomNumber, true); diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index abe2c8b45..6b74ada21 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -361,7 +361,6 @@ namespace TEN::Entities::TR5 { ShatterObject(0, mesh, -64, LaraItem->RoomNumber, 0); //SoundEffect(ShatterSounds[gfCurrentLevel - 5][*(v28 + 18)], v28); - mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; TestTriggers(pos.x, pos.y, pos.z, item->RoomNumber, true); } diff --git a/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp b/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp index 782e180bf..4e9ef5aea 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gunship.cpp @@ -107,7 +107,6 @@ namespace TEN::Entities::TR5 if (StaticObjects[hitMesh->staticNumber].shatterType != SHT_NONE) { ShatterObject(0, hitMesh, 64, end.roomNumber, 0); - hitMesh->flags &= ~StaticMeshFlags::SM_VISIBLE; TestTriggers(hitMesh->pos.Position.x, hitMesh->pos.Position.y, hitMesh->pos.Position.z, end.roomNumber, true); SoundEffect(GetShatterSound(hitMesh->staticNumber), &hitMesh->pos); } diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp index a7d242b5e..410af7fd6 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp @@ -595,7 +595,6 @@ namespace TEN::Entities::TR5 ShatterObject(0, mesh, -64, LaraItem->RoomNumber, 0); SoundEffect(GetShatterSound(mesh->staticNumber), (PHD_3DPOS*)mesh); - mesh->flags &= ~StaticMeshFlags::SM_VISIBLE; floor->Stopper = false; TestTriggers(pos.x, pos.y, pos.z, item->RoomNumber, true); diff --git a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp index 16f2e1ce2..ee9ad7597 100644 --- a/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp +++ b/TombEngine/Objects/TR5/Trap/tr5_explosion.cpp @@ -153,10 +153,6 @@ void ExplosionControl(short itemNumber) CollidedMeshes[i]->pos.Position.y += 128; SoundEffect(GetShatterSound(CollidedMeshes[i]->staticNumber), &CollidedMeshes[i]->pos); ShatterObject(NULL, CollidedMeshes[i], -128, item->RoomNumber, 0); - SmashedMeshRoom[SmashedMeshCount] = item->RoomNumber; - SmashedMesh[SmashedMeshCount] = CollidedMeshes[i]; - ++SmashedMeshCount; - CollidedMeshes[i]->flags &= ~StaticMeshFlags::SM_VISIBLE; } ++i; diff --git a/TombEngine/Scripting/Include/ScriptInterfaceGame.h b/TombEngine/Scripting/Include/ScriptInterfaceGame.h index 33b7b3344..4442d1ff2 100644 --- a/TombEngine/Scripting/Include/ScriptInterfaceGame.h +++ b/TombEngine/Scripting/Include/ScriptInterfaceGame.h @@ -36,6 +36,7 @@ public: virtual void FreeLevelScripts() = 0; virtual void ResetScripts(bool clearGameVars) = 0; virtual void ExecuteScriptFile(std::string const& luaFileName) = 0; + virtual void ExecuteString(std::string const& command) = 0; virtual void ExecuteFunction(std::string const& luaFuncName, TEN::Control::Volumes::VolumeTriggerer, std::string const& arguments) = 0; virtual void ExecuteFunction(std::string const& luaFuncName, short idOne, short idTwo = 0) = 0; diff --git a/TombEngine/Scripting/Internal/LuaHandler.cpp b/TombEngine/Scripting/Internal/LuaHandler.cpp index 6b5b73aba..5ddb604fe 100644 --- a/TombEngine/Scripting/Internal/LuaHandler.cpp +++ b/TombEngine/Scripting/Internal/LuaHandler.cpp @@ -26,7 +26,7 @@ void LuaHandler::ExecuteScript(std::string const& luaFilename) { } } -void LuaHandler::ExecuteString(std::string const & command) { +void LuaHandler::ExecuteString(std::string const& 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/ReservedScriptNames.h b/TombEngine/Scripting/Internal/ReservedScriptNames.h index 830593fb1..929894f07 100644 --- a/TombEngine/Scripting/Internal/ReservedScriptNames.h +++ b/TombEngine/Scripting/Internal/ReservedScriptNames.h @@ -99,6 +99,10 @@ static constexpr char ScriptReserved_SetTitleScreenImagePath[] = "SetTitleScreen static constexpr char ScriptReserved_SetFarView[] = "SetFarView"; static constexpr char ScriptReserved_SetSettings[] = "SetSettings"; static constexpr char ScriptReserved_SetAnimations[] = "SetAnimations"; +static constexpr char ScriptReserved_EndLevel[] = "EndLevel"; +static constexpr char ScriptReserved_GetSecretCount[] = "GetSecretCount"; +static constexpr char ScriptReserved_SetSecretCount[] = "SetSecretCount"; +static constexpr char ScriptReserved_AddSecret[] = "AddSecret"; // Flow Functions static constexpr char ScriptReserved_SetStrings[] = "SetStrings"; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp index d80965a6a..b46d43d7d 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.cpp @@ -61,6 +61,35 @@ Returns the level that the game control is running in that moment. */ table_flow.set_function(ScriptReserved_GetCurrentLevel, &FlowHandler::GetCurrentLevel, this); +/*** EndLevel. +Finish level, with optional level index provided. If level index is not provided or is zero, jumps +to next level. If level index is more than level count, jumps to title. +@function EndLevel +@tparam int index (optional) level index. +*/ + table_flow.set_function(ScriptReserved_EndLevel, &FlowHandler::EndLevel, this); + +/*** GetSecretCount. +Returns current game secret count. +@function GetSecretCount +@treturn Current game secret count. +*/ + table_flow.set_function(ScriptReserved_GetSecretCount, &FlowHandler::GetSecretCount, this); + +/*** SetSecretCount. +Sets current secret count, overwriting existing one. +@function SetSecretCount +@tparam int count new secret count. +*/ + table_flow.set_function(ScriptReserved_SetSecretCount, &FlowHandler::SetSecretCount, this); + +/*** AddSecret. +Adds one secret to game secret count and also plays secret music track. +@function AddSecret +@tparam int index an index of current level's secret (must be from 0 to 7). +*/ + table_flow.set_function(ScriptReserved_AddSecret, &FlowHandler::AddSecret, this); + /*** Image to show when loading the game. Must be a .jpg or .png image. @function SetIntroImagePath @@ -231,6 +260,47 @@ int FlowHandler::GetLevelNumber(std::string const& fileName) return -1; } +void FlowHandler::EndLevel(std::optional nextLevel) +{ + int index = (nextLevel.has_value() && nextLevel.value() != 0) ? nextLevel.value() : CurrentLevel + 1; + LevelComplete = index; +} + +int FlowHandler::GetSecretCount() const +{ + return Statistics.Game.Secrets; +} + +void FlowHandler::SetSecretCount(int secretsNum) +{ + if (secretsNum > UCHAR_MAX) + return; + + Statistics.Game.Secrets = secretsNum; +} + +void FlowHandler::AddSecret(int levelSecretIndex) +{ + if (levelSecretIndex > 7) + { + TENLog("Current maximum amount of secrets per level is 7.", LogLevel::Warning); + return; + } + + if (!(Statistics.Level.Secrets & (1 << levelSecretIndex))) + { + if (Statistics.Game.Secrets >= UCHAR_MAX) + { + TENLog("Maximum amount of game secrets is already reached!", LogLevel::Warning); + return; + } + + PlaySecretTrack(); + Statistics.Level.Secrets |= (1 << levelSecretIndex); + Statistics.Game.Secrets++; + } +} + bool FlowHandler::IsFlyCheatEnabled() const { return FlyCheat; diff --git a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h index 53a510e46..e0386cfd9 100644 --- a/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Flow/FlowHandler.h @@ -49,6 +49,10 @@ public: Level* GetCurrentLevel(); int GetLevelNumber(std::string const& flieName); int GetNumLevels() const; + void EndLevel(std::optional nextLevel); + int GetSecretCount() const; + void SetSecretCount(int secretsNum); + void AddSecret(int levelSecretIndex); void SetIntroImagePath(std::string const& path); void SetTitleScreenImagePath(std::string const& path); bool IsFlyCheatEnabled() const; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 2d7f28eaf..160598eb6 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -1,6 +1,7 @@ #include "framework.h" #include "LogicHandler.h" +#include #include "ScriptAssert.h" #include "Game/savegame.h" #include "Sound/sound.h" @@ -124,10 +125,10 @@ void LogicHandler::ResetScripts(bool clearGameVars) auto currentPackage = m_handler.GetState()->get("package"); auto currentLoaded = currentPackage.get("loaded"); - for(auto & [first, second] : currentLoaded) + for (auto& [first, second] : currentLoaded) currentLoaded[first] = sol::nil; - if(clearGameVars) + if (clearGameVars) ResetGameTables(); m_handler.ResetGlobals(); @@ -145,34 +146,6 @@ void LogicHandler::FreeLevelScripts() m_handler.GetState()->collect_garbage(); } -void JumpToLevel(int levelNum) -{ - if (levelNum >= g_GameFlow->GetNumLevels()) - return; - - LevelComplete = levelNum; -} - -int GetSecretsCount() -{ - return Statistics.Level.Secrets; -} - -void SetSecretsCount(int secretsNum) -{ - if (secretsNum > 255) - return; - Statistics.Level.Secrets = secretsNum; -} - -void AddOneSecret() -{ - if (Statistics.Level.Secrets >= 255) - return; - Statistics.Level.Secrets++; - PlaySecretTrack(); -} - void LogicHandler::SetVariables(std::vector const & vars) { ResetGameTables(); @@ -369,6 +342,11 @@ void LogicHandler::ExecuteScriptFile(const std::string & luaFilename) m_handler.ExecuteScript(luaFilename); } +void LogicHandler::ExecuteString(const std::string& command) +{ + m_handler.ExecuteString(command); +} + void LogicHandler::ExecuteFunction(std::string const& name, short idOne, short idTwo) { sol::protected_function_result r; diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index db58965f6..e77913a77 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -54,6 +54,7 @@ public: sol::protected_function GetLevelFunc(sol::table tab, std::string const& luaName); void ExecuteScriptFile(const std::string& luaFilename) override; + void ExecuteString(const std::string& command) override; void ExecuteFunction(std::string const& name, TEN::Control::Volumes::VolumeTriggerer, std::string const& arguments) override; void ExecuteFunction(std::string const& name, short idOne, short idTwo) override; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp index 8e9660df3..4f24ae4cf 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp @@ -1,6 +1,7 @@ #pragma once #include "framework.h" +#include "Game/effects/debris.h" #include "ScriptAssert.h" #include "StaticObject.h" #include "Vec3/Vec3.h" @@ -87,7 +88,11 @@ void Static::Register(sol::table & parent) /// Set the static's color // @function Static:SetColor // @tparam Color color the new color of the static - ScriptReserved_SetColor, &Static::SetColor); + ScriptReserved_SetColor, &Static::SetColor, + + /// Shatter static mesh + // @function Static:Shatter + ScriptReserved_Shatter, &Static::Shatter); } Vec3 Static::GetPos() const @@ -175,4 +180,9 @@ ScriptColor Static::GetColor() const void Static::SetColor(ScriptColor const& col) { m_mesh.color = col; +} + +void Static::Shatter() +{ + ShatterObject(nullptr, &m_mesh, -128, m_mesh.roomNumber, 0); } \ No newline at end of file diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h index c5ebba767..210a35e25 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h @@ -35,6 +35,7 @@ public: void SetSlot(int slot); ScriptColor GetColor() const; void SetColor(ScriptColor const & col); + void Shatter(); private: MESH_INFO & m_mesh; diff --git a/TombEngine/Sound/sound.cpp b/TombEngine/Sound/sound.cpp index 81e14e776..1e925596c 100644 --- a/TombEngine/Sound/sound.cpp +++ b/TombEngine/Sound/sound.cpp @@ -419,7 +419,7 @@ void PlaySoundTrack(std::string track, SoundTrackType mode, QWORD position) fullTrackName = TRACKS_PATH + track + ".wav"; if (!std::filesystem::exists(fullTrackName)) { - TENLog("No soundtrack files with name '" + track + "' were found", LogLevel::Error); + TENLog("No soundtrack files with name '" + track + "' were found", LogLevel::Warning); return; } } diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 7efd7219c..4085d8af3 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -787,6 +787,7 @@ void ReadRooms() mesh.HitPoints = ReadInt16(); mesh.luaName = ReadString(); + mesh.roomNumber = i; g_GameScriptEntities->AddName(mesh.luaName, mesh); } @@ -995,17 +996,17 @@ void LoadEventSets() eventSet.OnEnter.Mode = (VolumeEventMode)ReadInt32(); eventSet.OnEnter.Function = ReadString(); - eventSet.OnEnter.Argument = ReadString(); + eventSet.OnEnter.Data = ReadString(); eventSet.OnEnter.CallCounter = ReadInt32(); eventSet.OnInside.Mode = (VolumeEventMode)ReadInt32(); eventSet.OnInside.Function = ReadString(); - eventSet.OnInside.Argument = ReadString(); + eventSet.OnInside.Data = ReadString(); eventSet.OnInside.CallCounter = ReadInt32(); eventSet.OnLeave.Mode = (VolumeEventMode)ReadInt32(); eventSet.OnLeave.Function = ReadString(); - eventSet.OnLeave.Argument = ReadString(); + eventSet.OnLeave.Data = ReadString(); eventSet.OnLeave.CallCounter = ReadInt32(); g_Level.EventSets.push_back(eventSet); @@ -1321,11 +1322,11 @@ void LoadSprites() spr->y4 = ReadFloat(); } - g_Level.NumSpritesSequences = ReadInt32(); + int numSequences = ReadInt32(); - TENLog("Num sprite sequences: " + std::to_string(g_Level.NumSpritesSequences), LogLevel::Info); + TENLog("Num sprite sequences: " + std::to_string(numSequences), LogLevel::Info); - for (int i = 0; i < g_Level.NumSpritesSequences; i++) + for (int i = 0; i < numSequences; i++) { int spriteID = ReadInt32(); short negLength = ReadInt16(); diff --git a/TombEngine/Specific/level.h b/TombEngine/Specific/level.h index 66f51f7c0..d23b7d4bb 100644 --- a/TombEngine/Specific/level.h +++ b/TombEngine/Specific/level.h @@ -117,7 +117,6 @@ struct LEVEL std::vector AnimatedTexturesSequences; std::vector EventSets; int NumItems; - int NumSpritesSequences; }; extern std::vector MoveablesIds; From 0924111dcd47769eb4a1234ece2f63fa1d2ebf1f Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Thu, 8 Sep 2022 03:13:38 +0300 Subject: [PATCH 081/106] Add static mesh enable/disable script functions, bump version --- TombEngine/Resources.rc | 8 ++++---- .../TEN/Objects/Static/StaticObject.cpp | 18 ++++++++++++++++++ .../Internal/TEN/Objects/Static/StaticObject.h | 2 ++ TombEngine/Specific/level.cpp | 2 +- 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/TombEngine/Resources.rc b/TombEngine/Resources.rc index dd1606941..4f29cb8e1 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,1,0 - PRODUCTVERSION 1,5,2,0 + FILEVERSION 1,0,2,0 + PRODUCTVERSION 1,6,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -43,12 +43,12 @@ BEGIN BLOCK "000904b0" BEGIN VALUE "CompanyName", "TRLE Dev Community" - VALUE "FileVersion", "1.0.1.0" + VALUE "FileVersion", "1.0.2.0" VALUE "InternalName", "TombEngine.exe" VALUE "LegalCopyright", "Copyright (C) 2022" VALUE "OriginalFilename", "TombEngine.exe" VALUE "ProductName", "Tomb Engine" - VALUE "ProductVersion", "1.5.2.0" + VALUE "ProductVersion", "1.6.0.0" END END BLOCK "VarFileInfo" diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp index 4f24ae4cf..7c07079fe 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp +++ b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.cpp @@ -29,6 +29,14 @@ void Static::Register(sol::table & parent) sol::meta_function::index, index_error, sol::meta_function::new_index, newindex_error, + /// Enable the static, e.g. in cases when it was shattered or manually disabled before. + // @function Static:Enable + ScriptReserved_Enable, &Static::Enable, + + /// Disable the static + // @function Static:Disable + ScriptReserved_Disable, &Static::Disable, + /// Get the static's position // @function Static:GetPosition // @treturn Vec3 a copy of the static's position @@ -95,6 +103,16 @@ void Static::Register(sol::table & parent) ScriptReserved_Shatter, &Static::Shatter); } +void Static::Enable() +{ + m_mesh.flags |= StaticMeshFlags::SM_VISIBLE; +} + +void Static::Disable() +{ + m_mesh.flags &= ~StaticMeshFlags::SM_VISIBLE; +} + Vec3 Static::GetPos() const { return Vec3{ m_mesh.pos.Position.x, m_mesh.pos.Position.y, m_mesh.pos.Position.z }; diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h index 210a35e25..265705bfe 100644 --- a/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h +++ b/TombEngine/Scripting/Internal/TEN/Objects/Static/StaticObject.h @@ -23,6 +23,8 @@ public: static void Register(sol::table & parent); + void Enable(); + void Disable(); Rotation GetRot() const; void SetRot(Rotation const& rot); Vec3 GetPos() const; diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index 4085d8af3..eb1281d70 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -1092,7 +1092,7 @@ unsigned int _stdcall LoadLevel(void* data) { if (assemblyVersion[i] < version[i]) { - TENLog("Level version is higher than TEN version. Please update TEN.", LogLevel::Warning); + TENLog("Level version is different from TEN version.", LogLevel::Warning); break; } } From 5c0e4a6c200b1902cf3dfd1586a4fcb15a315e7b Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 8 Sep 2022 17:41:34 +1000 Subject: [PATCH 082/106] Rename --- TombEngine/Game/control/box.cpp | 34 ++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index e18fe2f3b..cc335bdf4 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -92,7 +92,7 @@ void DrawNearbyPathfinding(int boxIndex) void DropEntityPickups(ItemInfo* item) { - ItemInfo* pickup = NULL; + ItemInfo* pickup = nullptr; for (short pickupNumber = item->CarriedItem; pickupNumber != NO_ITEM; pickupNumber = pickup->CarriedItem) { @@ -463,7 +463,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) else boxHeight = item->Floor; - auto oldPos = item->Pose.Position; + auto prevPos = item->Pose.Position; AnimateItem(item); @@ -478,7 +478,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) int y = item->Pose.Position.y + bounds->Y1; short roomNumber = item->RoomNumber; - GetFloor(oldPos.x, y, oldPos.z, &roomNumber); + GetFloor(prevPos.x, y, prevPos.z, &roomNumber); FloorInfo* floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber); // TODO: Check why some blocks have box = -1 assigned to them -- Lwmte, 10.11.21 @@ -507,18 +507,18 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) { xPos = item->Pose.Position.x / SECTOR(1); zPos = item->Pose.Position.z / SECTOR(1); - shiftX = oldPos.x / SECTOR(1); - shiftZ = oldPos.z / SECTOR(1); + shiftX = prevPos.x / SECTOR(1); + shiftZ = prevPos.z / SECTOR(1); if (xPos < shiftX) - item->Pose.Position.x = oldPos.x & (~(SECTOR(1) - 1)); + item->Pose.Position.x = prevPos.x & (~(SECTOR(1) - 1)); else if (xPos > shiftX) - item->Pose.Position.x = oldPos.x | (SECTOR(1) - 1); + item->Pose.Position.x = prevPos.x | (SECTOR(1) - 1); if (zPos < shiftZ) - item->Pose.Position.z = oldPos.z & (~(SECTOR(1) - 1)); + item->Pose.Position.z = prevPos.z & (~(SECTOR(1) - 1)); else if (zPos > shiftZ) - item->Pose.Position.z = oldPos.z | (SECTOR(1) - 1); + item->Pose.Position.z = prevPos.z | (SECTOR(1) - 1); floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber); height = g_Level.Boxes[floor->Box].height; @@ -670,8 +670,8 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) { if (item->Pose.Position.y + top < ceiling) { - item->Pose.Position.x = oldPos.x; - item->Pose.Position.z = oldPos.z; + item->Pose.Position.x = prevPos.x; + item->Pose.Position.z = prevPos.z; dy = LOT->Fly; } else @@ -695,8 +695,8 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) } else { - item->Pose.Position.x = oldPos.x; - item->Pose.Position.z = oldPos.z; + item->Pose.Position.x = prevPos.x; + item->Pose.Position.z = prevPos.z; dy = -LOT->Fly; } @@ -733,7 +733,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) if (item->Pose.Position.y > item->Floor) { if (item->Pose.Position.y > (item->Floor + CLICK(1))) - item->Pose.Position = oldPos; + item->Pose.Position = prevPos; else item->Pose.Position.y = item->Floor; } @@ -750,7 +750,7 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) top = bounds->Y1; // TODO: check if Y1 or Y2 if (item->Pose.Position.y + top < ceiling) - item->Pose.Position = oldPos; + item->Pose.Position = prevPos; floor = GetFloor(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, &roomNumber); item->Floor = GetFloorHeight(floor, item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z); @@ -1367,7 +1367,7 @@ void FindAITargetObject(CreatureInfo* creature, short objectNumber) if (g_Level.AIObjects.size() > 0) { - AI_OBJECT* foundObject = NULL; + AI_OBJECT* foundObject = nullptr; for (int i = 0; i < g_Level.AIObjects.size(); i++) { @@ -1394,7 +1394,7 @@ void FindAITargetObject(CreatureInfo* creature, short objectNumber) } } - if (foundObject != NULL) + if (foundObject != nullptr) { auto* aiItem = creature->AITarget; From 837fe5736e639a93a2175a7906424c60e2bc0db9 Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 8 Sep 2022 23:01:17 +1000 Subject: [PATCH 083/106] Cleanup --- TombEngine/Game/collision/collide_item.cpp | 252 +++++++++---------- TombEngine/Game/collision/collide_item.h | 8 +- TombEngine/Objects/TR3/Trap/train.cpp | 55 ++-- TombEngine/Objects/TR4/Trap/tr4_stargate.cpp | 5 +- 4 files changed, 160 insertions(+), 160 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 310b96aaf..d8e7b77a2 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -453,7 +453,7 @@ bool MoveLaraPosition(Vector3Int* offset, ItemInfo* item, ItemInfo* laraItem) { auto* lara = GetLaraInfo(laraItem); - Matrix matrix = Matrix::CreateFromYawPitchRoll( + auto matrix = Matrix::CreateFromYawPitchRoll( TO_RAD(item->Pose.Orientation.y), TO_RAD(item->Pose.Orientation.x), TO_RAD(item->Pose.Orientation.z) @@ -515,9 +515,9 @@ bool ItemNearLara(PHD_3DPOS* pos, int radius) return false; } -bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* target, int radius) +bool ItemNearTarget(PHD_3DPOS* fromPose, ItemInfo* targetEntity, int radius) { - auto pos = origin->Position - target->Pose.Position; + auto pos = fromPose->Position - targetEntity->Pose.Position; if (!ItemCollide(pos.y, ITEM_RADIUS_YMAX)) return false; @@ -528,22 +528,22 @@ bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* target, int radius) if (!ItemInRange(pos.x, pos.z, radius)) return false; - auto* bounds = GetBoundsAccurate(target); + auto* bounds = GetBoundsAccurate(targetEntity); if (pos.y >= bounds->Y1 && pos.y <= bounds->Y2) return true; return false; } -bool Move3DPosTo3DPos(PHD_3DPOS* origin, PHD_3DPOS* target, int velocity, short angleAdd) +bool Move3DPosTo3DPos(PHD_3DPOS* fromPose, PHD_3DPOS* toPose, int velocity, short angleAdd) { - auto direction = target->Position - origin->Position; + auto direction = toPose->Position - fromPose->Position; int distance = sqrt(SQUARE(direction.x) + SQUARE(direction.y) + SQUARE(direction.z)); if (velocity < distance) - origin->Position += direction * velocity / distance; + fromPose->Position += direction * velocity / distance; else - origin->Position = target->Position; + fromPose->Position = toPose->Position; if (!Lara.Control.IsMoving) { @@ -551,8 +551,8 @@ bool Move3DPosTo3DPos(PHD_3DPOS* origin, PHD_3DPOS* target, int velocity, short if (shouldAnimate && Lara.Control.WaterStatus != WaterStatus::Underwater) { - int angle = mGetAngle(target->Position.x, target->Position.z, origin->Position.x, origin->Position.z); - int direction = (GetQuadrant(angle) - GetQuadrant(target->Orientation.y)) & 3; + int angle = mGetAngle(toPose->Position.x, toPose->Position.z, fromPose->Position.x, fromPose->Position.z); + int direction = (GetQuadrant(angle) - GetQuadrant(toPose->Orientation.y)) & 3; switch (direction) { @@ -583,31 +583,31 @@ bool Move3DPosTo3DPos(PHD_3DPOS* origin, PHD_3DPOS* target, int velocity, short Lara.Control.Count.PositionAdjust = 0; } - short deltaAngle = target->Orientation.x - origin->Orientation.x; + short deltaAngle = toPose->Orientation.x - fromPose->Orientation.x; if (deltaAngle > angleAdd) - origin->Orientation.x += angleAdd; + fromPose->Orientation.x += angleAdd; else if (deltaAngle < -angleAdd) - origin->Orientation.x -= angleAdd; + fromPose->Orientation.x -= angleAdd; else - origin->Orientation.x = target->Orientation.x; + fromPose->Orientation.x = toPose->Orientation.x; - deltaAngle = target->Orientation.y - origin->Orientation.y; + deltaAngle = toPose->Orientation.y - fromPose->Orientation.y; if (deltaAngle > angleAdd) - origin->Orientation.y += angleAdd; + fromPose->Orientation.y += angleAdd; else if (deltaAngle < -angleAdd) - origin->Orientation.y -= angleAdd; + fromPose->Orientation.y -= angleAdd; else - origin->Orientation.y = target->Orientation.y; + fromPose->Orientation.y = toPose->Orientation.y; - deltaAngle = target->Orientation.z - origin->Orientation.z; + deltaAngle = toPose->Orientation.z - fromPose->Orientation.z; if (deltaAngle > angleAdd) - origin->Orientation.z += angleAdd; + fromPose->Orientation.z += angleAdd; else if (deltaAngle < -angleAdd) - origin->Orientation.z -= angleAdd; + fromPose->Orientation.z -= angleAdd; else - origin->Orientation.z = target->Orientation.z; + fromPose->Orientation.z = toPose->Orientation.z; - return (origin->Position == target->Position && origin->Orientation == target->Orientation); + return (fromPose->Position == toPose->Position && fromPose->Orientation == toPose->Orientation); } bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius) @@ -688,11 +688,7 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool spa int rx = (dx * cosY) - (dz * sinY); int rz = (dz * cosY) + (dx * sinY); - BOUNDING_BOX* bounds; - if (bigPush & 2) - bounds = &GlobalCollisionBounds; - else - bounds = (BOUNDING_BOX*)GetBestFrame(item); + auto* bounds = (bigPush & 2) ? &GlobalCollisionBounds : (BOUNDING_BOX*)GetBestFrame(item); int minX = bounds->X1; int maxX = bounds->X2; @@ -729,8 +725,8 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool spa else rz -= bottom; - item2->Pose.Position.x = item->Pose.Position.x + cosY * rx + sinY * rz; - item2->Pose.Position.z = item->Pose.Position.z + cosY * rz - sinY * rx; + item2->Pose.Position.x = item->Pose.Position.x + (rx * cosY) + (rz * sinY); + item2->Pose.Position.z = item->Pose.Position.z + (rz * cosY) - (rx * sinY); auto* lara = item2->IsLara() ? GetLaraInfo(item2) : nullptr; @@ -868,7 +864,7 @@ void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll) { auto* mesh = &g_Level.Rooms[i].mesh[j]; - // Only process meshes which are visible and solid + // Only process meshes which are visible and solid. if ((mesh->flags & StaticMeshFlags::SM_VISIBLE) && (mesh->flags & StaticMeshFlags::SM_SOLID)) { if (phd_Distance(&item->Pose, &mesh->pos) < COLLISION_CHECK_DISTANCE) @@ -886,35 +882,35 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis { bool result = false; - // Get DX static bounds in global coords + // Get DX static bounds in global coordinates. auto staticBounds = TO_DX_BBOX(pos, box); - // Get local TR bounds and DX item bounds in global coords + // Get local TR bounds and DX item bounds in global coordinates. auto itemBBox = GetBoundsAccurate(item); auto itemBounds = TO_DX_BBOX(item->Pose, itemBBox); - // Extend bounds a bit for visual testing - itemBounds.Extents = itemBounds.Extents + Vector3(WALL_SIZE); + // Extend bounds a bit for visual testing. + itemBounds.Extents = itemBounds.Extents + Vector3(SECTOR(1)); - // Filter out any further checks if static isn't nearby + // Filter out any further checks if static isn't nearby. if (!staticBounds.Intersects(itemBounds)) return false; - // Bring back extents - itemBounds.Extents = itemBounds.Extents - Vector3(WALL_SIZE); + // Bring back extents. + itemBounds.Extents = itemBounds.Extents - Vector3(SECTOR(1)); - // Draw static bounds + // Draw static bounds. g_Renderer.AddDebugBox(staticBounds, Vector4(1, 0.3f, 0, 1), RENDERER_DEBUG_PAGE::LOGIC_STATS); - // Calculate horizontal item coll bounds according to radius + // Calculate horizontal item collision bounds according to radius. BOUNDING_BOX collBox; collBox.X1 = -coll->Setup.Radius; collBox.X2 = coll->Setup.Radius; collBox.Z1 = -coll->Setup.Radius; collBox.Z2 = coll->Setup.Radius; - // Calculate vertical item coll bounds according to either height (land mode) or precise bounds (water mode). - // Water mode needs special processing because height calc in original engines is inconsistent in such cases. + // Calculate vertical item collision bounds according to either height (land mode) or precise bounds (water mode). + // Water mode needs special processing because height calculation in original engines is inconsistent in such cases. if (TestEnvironment(ENV_FLAG_WATER, item)) { collBox.Y1 = itemBBox->Y1; @@ -926,18 +922,18 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis collBox.Y2 = 0; } - // Get and test DX item coll bounds + // Get and test DX item collision bounds. auto collBounds = TO_DX_BBOX(PHD_3DPOS(item->Pose.Position), &collBox); bool intersects = staticBounds.Intersects(collBounds); - // Check if previous item horizontal position intersects bounds + // Check if previous item horizontal position intersects bounds. auto oldCollBounds = TO_DX_BBOX(PHD_3DPOS(coll->Setup.OldPosition.x, item->Pose.Position.y, coll->Setup.OldPosition.z), &collBox); bool oldHorIntersects = staticBounds.Intersects(oldCollBounds); - // Draw item coll bounds + // Draw item coll bounds. g_Renderer.AddDebugBox(collBounds, intersects ? Vector4(1, 0, 0, 1) : Vector4(0, 1, 0, 1), RENDERER_DEBUG_PAGE::LOGIC_STATS); - // Decompose static bounds into top/bottom plane vertices + // Decompose static bounds into top/bottom plane vertices. Vector3 corners[8]; staticBounds.GetCorners(corners); Vector3 planeVertices[4][3] = @@ -948,7 +944,7 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis { corners[3], corners[6], corners[2] } }; - // Determine collision box vertical dimensions + // Determine collision box vertical dimensions. auto height = collBox.Height(); auto center = item->Pose.Position.y - height / 2; @@ -960,24 +956,23 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis for (int i = 0; i < 4; i++) { - // Calculate ray direction + // Calculate ray direction. auto mxR = Matrix::CreateFromYawPitchRoll(TO_RAD(item->Pose.Orientation.y), TO_RAD(item->Pose.Orientation.x + (ANGLE(90 * i))), 0); auto mxT = Matrix::CreateTranslation(Vector3::UnitY); auto direction = (mxT * mxR).Translation(); - // Make a ray and do ray tests against all decomposed planes + // Make a ray and do ray tests against all decomposed planes. auto ray = Ray(collBounds.Center, direction); - // Determine if top/bottom planes are closest ones or not + // Determine if top/bottom planes are closest ones or not. for (int p = 0; p < 4; p++) { - // No plane intersection, quickly discard + // No plane intersection, quickly discard. float d = 0.0f; if (!ray.Intersects(planeVertices[p][0], planeVertices[p][1], planeVertices[p][2], d)) continue; - // Process plane intersection only if distance is smaller - // than already found minimum + // Process plane intersection only if distance is smaller than already found minimum. if (d < minDistance) { closestRay = ray; @@ -987,24 +982,25 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis } } - if (closestPlane != -1) // Top/bottom plane found + // Top/bottom plane found. + if (closestPlane != -1) { auto bottom = closestPlane >= 2; auto yPoint = abs((closestRay.direction * minDistance).y); auto distanceToVerticalPlane = height / 2 - yPoint; - // Correct position according to top/bottom bounds, if collided and plane is nearby + // Correct position according to top/bottom bounds, if collided and plane is nearby. if (intersects && oldHorIntersects && minDistance < height) { if (bottom) { - // HACK: additionally subtract 2 from bottom plane, or else false positives may occur. + // HACK: Additionally subtract 2 from bottom plane, otherwise false positives may occur. item->Pose.Position.y += distanceToVerticalPlane + 2; coll->CollisionType = CT_TOP; } else { - // Set collision type only if dry room (in water rooms it causes stucking) + // Set collision type only if dry room (in water rooms the player can get stuck). item->Pose.Position.y -= distanceToVerticalPlane; coll->CollisionType = (g_Level.Rooms[item->RoomNumber].flags & 1) ? coll->CollisionType : CT_CLAMP; } @@ -1020,21 +1016,21 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis if (!intersects) return false; - // Check if bounds still collide after top/bottom position correction + // Check if bounds still collide after top/bottom position correction. if (!staticBounds.Intersects(TO_DX_BBOX(PHD_3DPOS(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z), &collBox))) return result; - // Determine identity rotation/distance - auto distance = Vector3(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z) - Vector3(pos.Position.x, pos.Position.y, pos.Position.z); + // Determine identity orientation/distance. + auto distance = item->Pose.Position.ToVector3() - pos.Position.ToVector3(); auto sinY = phd_sin(pos.Orientation.y); auto cosY = phd_cos(pos.Orientation.y); - // Rotate item to collision bounds identity - auto x = round(distance.x * cosY - distance.z * sinY) + pos.Position.x; + // Rotate item to collision bounds identity. + auto x = round((distance.x * cosY) - (distance.z * sinY)) + pos.Position.x; auto y = item->Pose.Position.y; - auto z = round(distance.x * sinY + distance.z * cosY) + pos.Position.z; + auto z = round((distance.x * sinY) + (distance.z * cosY)) + pos.Position.z; - // Determine identity static collision bounds + // Determine identity static collision bounds. auto XMin = pos.Position.x + box->X1; auto XMax = pos.Position.x + box->X2; auto YMin = pos.Position.y + box->Y1; @@ -1042,7 +1038,7 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis auto ZMin = pos.Position.z + box->Z1; auto ZMax = pos.Position.z + box->Z2; - // Determine item collision bounds + // Determine item collision bounds. auto inXMin = x + collBox.X1; auto inXMax = x + collBox.X2; auto inYMin = y + collBox.Y1; @@ -1050,15 +1046,15 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis auto inZMin = z + collBox.Z1; auto inZMax = z + collBox.Z2; - // Don't calculate shifts if not in bounds + // Don't calculate shifts if not in bounds. if (inXMax <= XMin || inXMin >= XMax || inYMax <= YMin || inYMin >= YMax || inZMax <= ZMin || inZMin >= ZMax) return result; - // Calculate shifts + // Calculate shifts. - Vector3Int rawShift = {}; + auto rawShift = Vector3Int::Zero; auto shiftLeft = inXMax - XMin; auto shiftRight = XMax - inXMin; @@ -1076,12 +1072,12 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis else rawShift.z = shiftRight; - // Rotate previous collision position to identity - distance = Vector3(coll->Setup.OldPosition.x, coll->Setup.OldPosition.y, coll->Setup.OldPosition.z) - Vector3(pos.Position.x, pos.Position.y, pos.Position.z); - auto ox = round(distance.x * cosY - distance.z * sinY) + pos.Position.x; - auto oz = round(distance.x * sinY + distance.z * cosY) + pos.Position.z; + // Rotate previous collision position to identity. + distance = coll->Setup.OldPosition.ToVector3() - pos.Position.ToVector3(); + auto ox = round((distance.x * cosY) - (distance.z * sinY)) + pos.Position.x; + auto oz = round((distance.x * sinY) + (distance.z * cosY)) + pos.Position.z; - // Calculate collisison type based on identity rotation + // Calculate collisison type based on identity orientation. switch (GetQuadrant(coll->Setup.ForwardAngle - pos.Orientation.y)) { case NORTH: @@ -1173,19 +1169,19 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis break; } - // Determine final shifts rotation/distance - distance = Vector3(x + coll->Shift.x, y, z + coll->Shift.z) - Vector3(pos.Position.x, pos.Position.y, pos.Position.z); + // Determine final shifts orientation/distance. + distance = Vector3(x + coll->Shift.x, y, z + coll->Shift.z) - pos.Position.ToVector3(); sinY = phd_sin(-pos.Orientation.y); cosY = phd_cos(-pos.Orientation.y); - // Calculate final shifts rotation/distance - coll->Shift.x = (round(distance.x * cosY - distance.z * sinY) + pos.Position.x) - item->Pose.Position.x; - coll->Shift.z = (round(distance.x * sinY + distance.z * cosY) + pos.Position.z) - item->Pose.Position.z; + // Calculate final shifts orientation/distance. + coll->Shift.x = (round((distance.x * cosY) - (distance.z * sinY)) + pos.Position.x) - item->Pose.Position.x; + coll->Shift.z = (round((distance.x * sinY) + (distance.z * cosY)) + pos.Position.z) - item->Pose.Position.z; if (coll->Shift.x == 0 && coll->Shift.z == 0) - coll->CollisionType = CT_NONE; // Paranoid + coll->CollisionType = CT_NONE; // Paranoid. - // Set splat state flag if item is Lara and bounds are taller than Lara's headroom + // Set splat state flag if item is Lara and bounds are taller than Lara's headroom. if (item == LaraItem && coll->CollisionType == CT_FRONT) coll->HitTallObject = (YMin <= inYMin + LARA_HEADROOM); @@ -1197,39 +1193,39 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { auto* item = &g_Level.Items[itemNumber]; - auto prevCollResult = GetCollision(x, y, z, item->RoomNumber); - auto collResult = GetCollision(item); + auto prevPointProbe = GetCollision(x, y, z, item->RoomNumber); + auto pointProbe = GetCollision(item); auto* bounds = GetBoundsAccurate(item); int radius = bounds->Height(); item->Pose.Position.y += radius; - if (item->Pose.Position.y >= collResult.Position.Floor) + if (item->Pose.Position.y >= pointProbe.Position.Floor) { int bs = 0; - if (collResult.Position.FloorSlope && prevCollResult.Position.Floor < collResult.Position.Floor) + if (pointProbe.Position.FloorSlope && prevPointProbe.Position.Floor < pointProbe.Position.Floor) { int yAngle = (long)((unsigned short)item->Pose.Orientation.y); - if (collResult.FloorTilt.x < 0) + if (pointProbe.FloorTilt.x < 0) { if (yAngle >= ANGLE(180.0f)) bs = 1; } - else if (collResult.FloorTilt.x > 0) + else if (pointProbe.FloorTilt.x > 0) { if (yAngle <= ANGLE(180.0f)) bs = 1; } - if (collResult.FloorTilt.y < 0) + if (pointProbe.FloorTilt.y < 0) { if (yAngle >= ANGLE(90.0f) && yAngle <= ANGLE(270.0f)) bs = 1; } - else if (collResult.FloorTilt.y > 0) + else if (pointProbe.FloorTilt.y > 0) { if (yAngle <= ANGLE(90.0f) || yAngle >= ANGLE(270.0f)) bs = 1; @@ -1238,7 +1234,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, // If last position of item was also below this floor height, we've hit a wall, else we've hit a floor. - if (y > (collResult.Position.Floor + 32) && bs == 0 && + if (y > (pointProbe.Position.Floor + 32) && bs == 0 && (((x / SECTOR(1)) != (item->Pose.Position.x / SECTOR(1))) || ((z / SECTOR(1)) != (item->Pose.Position.z / SECTOR(1))))) { @@ -1246,8 +1242,8 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, long xs; - if ((x & (~(WALL_SIZE - 1))) != (item->Pose.Position.x & (~(WALL_SIZE - 1))) && // X crossed boundary? - (z & (~(WALL_SIZE - 1))) != (item->Pose.Position.z & (~(WALL_SIZE - 1)))) // Z crossed boundary as well? + if ((x & (~WALL_MASK)) != (item->Pose.Position.x & (~WALL_MASK)) && // X crossed boundary? + (z & (~WALL_MASK)) != (item->Pose.Position.z & (~WALL_MASK))) // Z crossed boundary as well? { if (abs(x - item->Pose.Position.x) < abs(z - item->Pose.Position.z)) xs = 1; // X has travelled the shortest, so (maybe) hit first. (Seems to work ok). @@ -1257,7 +1253,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, else xs = 1; - if ((x & (~(WALL_SIZE - 1))) != (item->Pose.Position.x & (~(WALL_SIZE - 1))) && xs) // X crossed boundary? + if ((x & (~WALL_MASK)) != (item->Pose.Position.x & (~WALL_MASK)) && xs) // X crossed boundary? { // Hit angle = ANGLE(270.0f). if (xv <= 0) @@ -1278,14 +1274,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, item->Pose.Position.z = z; } // Hit a steep slope? - else if (collResult.Position.FloorSlope) + else if (pointProbe.Position.FloorSlope) { // Need to know which direction the slope is. item->Animation.Velocity.z -= (item->Animation.Velocity.z / 4); // Hit angle = ANGLE(90.0f) - if (collResult.FloorTilt.x < 0 && ((abs(collResult.FloorTilt.x)) - (abs(collResult.FloorTilt.y)) >= 2)) + if (pointProbe.FloorTilt.x < 0 && ((abs(pointProbe.FloorTilt.x)) - (abs(pointProbe.FloorTilt.y)) >= 2)) { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(180.0f)) { @@ -1297,7 +1293,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z -= collResult.FloorTilt.x * 2; + item->Animation.Velocity.z -= pointProbe.FloorTilt.x * 2; if ((unsigned short)item->Pose.Orientation.y > ANGLE(90.0f) && (unsigned short)item->Pose.Orientation.y < ANGLE(270.0f)) { item->Pose.Orientation.y -= ANGLE(22.5f); @@ -1319,7 +1315,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } // Hit angle = ANGLE(270.0f) - else if (collResult.FloorTilt.x > 0 && ((abs(collResult.FloorTilt.x)) - (abs(collResult.FloorTilt.y)) >= 2)) + else if (pointProbe.FloorTilt.x > 0 && ((abs(pointProbe.FloorTilt.x)) - (abs(pointProbe.FloorTilt.y)) >= 2)) { if (((unsigned short)item->Pose.Orientation.y) < ANGLE(180.0f)) { @@ -1331,7 +1327,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z += collResult.FloorTilt.x * 2; + item->Animation.Velocity.z += pointProbe.FloorTilt.x * 2; if ((unsigned short)item->Pose.Orientation.y > ANGLE(270.0f) || (unsigned short)item->Pose.Orientation.y < ANGLE(90.0f)) { item->Pose.Orientation.y -= ANGLE(22.5f); @@ -1353,7 +1349,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } // Hit angle = 0 - else if (collResult.FloorTilt.y < 0 && ((abs(collResult.FloorTilt.y)) - (abs(collResult.FloorTilt.x)) >= 2)) + else if (pointProbe.FloorTilt.y < 0 && ((abs(pointProbe.FloorTilt.y)) - (abs(pointProbe.FloorTilt.x)) >= 2)) { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(90.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(270.0f)) { @@ -1365,7 +1361,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z -= collResult.FloorTilt.y * 2; + item->Animation.Velocity.z -= pointProbe.FloorTilt.y * 2; if ((unsigned short)item->Pose.Orientation.y < ANGLE(180.0f)) { @@ -1388,7 +1384,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } // Hit angle = ANGLE(180.0f) - else if (collResult.FloorTilt.y > 0 && ((abs(collResult.FloorTilt.y)) - (abs(collResult.FloorTilt.x)) >= 2)) + else if (pointProbe.FloorTilt.y > 0 && ((abs(pointProbe.FloorTilt.y)) - (abs(pointProbe.FloorTilt.x)) >= 2)) { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(270.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(90.0f)) { @@ -1400,7 +1396,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z += collResult.FloorTilt.y * 2; + item->Animation.Velocity.z += pointProbe.FloorTilt.y * 2; if ((unsigned short)item->Pose.Orientation.y > ANGLE(180.0f)) { @@ -1422,7 +1418,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, item->Animation.Velocity.y = 0; } } - else if (collResult.FloorTilt.x < 0 && collResult.FloorTilt.y < 0) // Hit angle = 0x2000 + else if (pointProbe.FloorTilt.x < 0 && pointProbe.FloorTilt.y < 0) // Hit angle = 0x2000 { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(135.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(315.0f)) { @@ -1434,7 +1430,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z += -collResult.FloorTilt.x + -collResult.FloorTilt.y; + item->Animation.Velocity.z += -pointProbe.FloorTilt.x + -pointProbe.FloorTilt.y; if ((unsigned short)item->Pose.Orientation.y > ANGLE(45.0f) && (unsigned short)item->Pose.Orientation.y < ANGLE(225.0f)) { item->Pose.Orientation.y -= ANGLE(22.5f); @@ -1456,7 +1452,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } // Hit angle = ANGLE(135.0f) - else if (collResult.FloorTilt.x < 0 && collResult.FloorTilt.y > 0) + else if (pointProbe.FloorTilt.x < 0 && pointProbe.FloorTilt.y > 0) { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(225.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(45.0f)) { @@ -1468,7 +1464,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z += (-collResult.FloorTilt.x) + collResult.FloorTilt.y; + item->Animation.Velocity.z += (-pointProbe.FloorTilt.x) + pointProbe.FloorTilt.y; if ((unsigned short)item->Pose.Orientation.y < ANGLE(315.0f) && (unsigned short)item->Pose.Orientation.y > ANGLE(135.0f)) { item->Pose.Orientation.y -= ANGLE(22.5f); @@ -1490,7 +1486,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } // Hit angle = ANGLE(225.5f) - else if (collResult.FloorTilt.x > 0 && collResult.FloorTilt.y > 0) + else if (pointProbe.FloorTilt.x > 0 && pointProbe.FloorTilt.y > 0) { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(315.0f) || ((unsigned short)item->Pose.Orientation.y) < ANGLE(135.0f)) { @@ -1502,7 +1498,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z += collResult.FloorTilt.x + collResult.FloorTilt.y; + item->Animation.Velocity.z += pointProbe.FloorTilt.x + pointProbe.FloorTilt.y; if ((unsigned short)item->Pose.Orientation.y < ANGLE(45.0f) || (unsigned short)item->Pose.Orientation.y > ANGLE(225.5f)) { item->Pose.Orientation.y -= ANGLE(22.5f); @@ -1524,7 +1520,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } // Hit angle = ANGLE(315.0f) - else if (collResult.FloorTilt.x > 0 && collResult.FloorTilt.y < 0) + else if (pointProbe.FloorTilt.x > 0 && pointProbe.FloorTilt.y < 0) { if (((unsigned short)item->Pose.Orientation.y) > ANGLE(45.0f) && ((unsigned short)item->Pose.Orientation.y) < ANGLE(225.5f)) { @@ -1536,7 +1532,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (item->Animation.Velocity.z < 32) { - item->Animation.Velocity.z += collResult.FloorTilt.x + (-collResult.FloorTilt.y); + item->Animation.Velocity.z += pointProbe.FloorTilt.x + (-pointProbe.FloorTilt.y); if ((unsigned short)item->Pose.Orientation.y < ANGLE(135.0f) || (unsigned short)item->Pose.Orientation.y > ANGLE(315.0f)) { item->Pose.Orientation.y -= ANGLE(22.5f); @@ -1558,7 +1554,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } - // Put item back in its last position. + // Move item back to its previous position. item->Pose.Position.x = x; item->Pose.Position.y = y; item->Pose.Position.z = z; @@ -1597,7 +1593,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } - item->Pose.Position.y = collResult.Position.Floor; + item->Pose.Position.y = pointProbe.Position.Floor; } } // Check for on top of object. @@ -1605,8 +1601,8 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, { if (yv >= 0) { - prevCollResult = GetCollision(item->Pose.Position.x, y, item->Pose.Position.z, item->RoomNumber); - collResult = GetCollision(item); + prevPointProbe = GetCollision(item->Pose.Position.x, y, item->Pose.Position.z, item->RoomNumber); + pointProbe = GetCollision(item); // Bounce off floor. @@ -1614,7 +1610,7 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, // was always set to 0 by GetHeight() function which was called before the check. // Possibly a mistake or unfinished feature by Core? -- Lwmte, 27.08.21 - if (item->Pose.Position.y >= prevCollResult.Position.Floor) + if (item->Pose.Position.y >= prevPointProbe.Position.Floor) { // Hit the floor; bounce and slow down. if (item->Animation.Velocity.y > 0) @@ -1648,17 +1644,17 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } - item->Pose.Position.y = prevCollResult.Position.Floor; + item->Pose.Position.y = prevPointProbe.Position.Floor; } } // else { // Bounce off ceiling. - collResult = GetCollision(item); + pointProbe = GetCollision(item); - if (item->Pose.Position.y < collResult.Position.Ceiling) + if (item->Pose.Position.y < pointProbe.Position.Ceiling) { - if (y < collResult.Position.Ceiling && + if (y < pointProbe.Position.Ceiling && (((x / SECTOR(1)) != (item->Pose.Position.x / SECTOR(1))) || ((z / SECTOR(1)) != (item->Pose.Position.z / SECTOR(1))))) { @@ -1681,13 +1677,13 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, else item->Animation.Velocity.z /= 2; - // Put item back in its last position. + // Move item back to its previous position. item->Pose.Position.x = x; item->Pose.Position.y = y; item->Pose.Position.z = z; } else - item->Pose.Position.y = collResult.Position.Ceiling; + item->Pose.Position.y = pointProbe.Position.Ceiling; if (item->Animation.Velocity.y < 0) item->Animation.Velocity.y = -item->Animation.Velocity.y; @@ -1695,14 +1691,14 @@ void DoProjectileDynamics(short itemNumber, int x, int y, int z, int xv, int yv, } } - collResult = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); + pointProbe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, item->RoomNumber); - if (collResult.RoomNumber != item->RoomNumber) + if (pointProbe.RoomNumber != item->RoomNumber) { - if (item->ObjectNumber == ID_GRENADE && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, collResult.RoomNumber)) + if (item->ObjectNumber == ID_GRENADE && TestEnvironment(RoomEnvFlags::ENV_FLAG_WATER, pointProbe.RoomNumber)) Splash(item); - ItemNewRoom(itemNumber, collResult.RoomNumber); + ItemNewRoom(itemNumber, pointProbe.RoomNumber); } item->Pose.Position.y -= radius; @@ -1791,8 +1787,8 @@ void DoObjectCollision(ItemInfo* laraItem, CollisionInfo* coll) else { DoDamage(item, INT_MAX); - - DoLotsOfBlood(item->Pose.Position.x, + DoLotsOfBlood( + item->Pose.Position.x, laraItem->Pose.Position.y - CLICK(1), item->Pose.Position.z, laraItem->Animation.Velocity.z, @@ -1901,7 +1897,7 @@ void CreatureCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll int rx = (frame->boundingBox.X1 + frame->boundingBox.X2) / 2; int rz = (frame->boundingBox.X2 + frame->boundingBox.Z2) / 2; - if (frame->boundingBox.Height() > STEP_SIZE) + if (frame->boundingBox.Height() > CLICK(1)) { auto* lara = GetLaraInfo(laraItem); @@ -1909,7 +1905,7 @@ void CreatureCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll lara->HitDirection = (short)angle; - // TODO: check if a second Lara.hitFrame++; is required there ! + // TODO: Check if a second Lara.hitFrame++ is required. -- TokyoSU lara->HitFrame++; if (lara->HitFrame > 30) lara->HitFrame = 30; diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index 55ce3b6ac..8afa6612a 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -2,9 +2,9 @@ #include "Specific/phd_global.h" #include "Specific/trmath.h" -struct ItemInfo; -struct CollisionInfo; class FloorInfo; +struct CollisionInfo; +struct ItemInfo; struct MESH_INFO; constexpr auto MAX_COLLIDED_OBJECTS = 1024; @@ -37,9 +37,9 @@ bool AlignLaraPosition(Vector3Int* offset, ItemInfo* item, ItemInfo* laraItem); bool MoveLaraPosition(Vector3Int* pos, ItemInfo* item, ItemInfo* laraItem); bool ItemNearLara(PHD_3DPOS* pos, int radius); -bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* target, int radius); +bool ItemNearTarget(PHD_3DPOS* fromPose, ItemInfo* targetEntity, int radius); -bool Move3DPosTo3DPos(PHD_3DPOS* origin, PHD_3DPOS* target, int velocity, short angleAdd); +bool Move3DPosTo3DPos(PHD_3DPOS* fromPose, PHD_3DPOS* toPose, int velocity, short angleAdd); bool TestBoundsCollide(ItemInfo* item, ItemInfo* laraItem, int radius); bool TestBoundsCollideStatic(ItemInfo* item, MESH_INFO* mesh, int radius); diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp index 2f3756025..aa6ac7522 100644 --- a/TombEngine/Objects/TR3/Trap/train.cpp +++ b/TombEngine/Objects/TR3/Trap/train.cpp @@ -21,14 +21,16 @@ long TrainTestHeight(ItemInfo* item, long x, long z, short* roomNumber) { - float s = phd_sin(item->Pose.Orientation.y); - float c = phd_cos(item->Pose.Orientation.y); - - Vector3Int pos; - pos.x = round(item->Pose.Position.x + z * s + x * c); - pos.y = round(item->Pose.Position.y - z * phd_sin(item->Pose.Orientation.x) + x * phd_sin(item->Pose.Orientation.z)); - pos.z = round(item->Pose.Position.z + z * c - x * s); + float sinX = phd_sin(item->Pose.Orientation.x); + float sinY = phd_sin(item->Pose.Orientation.y); + float cosY = phd_cos(item->Pose.Orientation.y); + float sinZ = phd_sin(item->Pose.Orientation.z); + auto pos = Vector3Int( + round(item->Pose.Position.x + ((z * sinY) + (x * cosY))), + round(item->Pose.Position.y - ((z * sinX) + (x * sinZ))), + round(item->Pose.Position.z + ((z * cosY) - (x * sinY))) + ); auto probe = GetCollision(pos.x, pos.y, pos.z, item->RoomNumber); *roomNumber = probe.RoomNumber; @@ -45,11 +47,11 @@ void TrainControl(short itemNumber) if (item->ItemFlags[0] == 0) item->ItemFlags[0] = item->ItemFlags[1] = TRAIN_VEL; - float s = phd_sin(item->Pose.Orientation.y); - float c = phd_cos(item->Pose.Orientation.y); + float sinY = phd_sin(item->Pose.Orientation.y); + float cozY = phd_cos(item->Pose.Orientation.y); - item->Pose.Position.x += item->ItemFlags[1] * s; - item->Pose.Position.z += item->ItemFlags[1] * c; + item->Pose.Position.x += item->ItemFlags[1] * sinY; + item->Pose.Position.z += item->ItemFlags[1] * cozY; short roomNumber; long rh = TrainTestHeight(item, 0, SECTOR(5), &roomNumber); @@ -70,7 +72,7 @@ void TrainControl(short itemNumber) item->Pose.Orientation.x = -(rh - floorHeight) * 2; - TriggerDynamicLight(item->Pose.Position.x + SECTOR(3) * s, item->Pose.Position.y, item->Pose.Position.z + SECTOR(3) * c, 16, 31, 31, 31); + TriggerDynamicLight(item->Pose.Position.x + SECTOR(3) * sinY, item->Pose.Position.y, item->Pose.Position.z + SECTOR(3) * cozY, 16, 31, 31, 31); if (item->ItemFlags[1] != TRAIN_VEL) { @@ -80,8 +82,8 @@ void TrainControl(short itemNumber) if (!UseForcedFixedCamera) { - ForcedFixedCamera.x = item->Pose.Position.x + SECTOR(8) * s; - ForcedFixedCamera.z = item->Pose.Position.z + SECTOR(8) * c; + ForcedFixedCamera.x = item->Pose.Position.x + SECTOR(8) * sinY; + ForcedFixedCamera.z = item->Pose.Position.z + SECTOR(8) * cozY; ForcedFixedCamera.y = GetCollision(ForcedFixedCamera.x, item->Pose.Position.y - CLICK(2), ForcedFixedCamera.z, item->RoomNumber).Position.Floor; @@ -95,12 +97,13 @@ void TrainControl(short itemNumber) void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) { + auto* item = &g_Level.Items[itemNumber]; auto* laraInfo = GetLaraInfo(laraItem); - auto* trainItem = &g_Level.Items[itemNumber]; - if (!TestBoundsCollide(trainItem, laraItem, coll->Setup.Radius)) + if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) return; - if (!TestCollision(trainItem, laraItem)) + + if (!TestCollision(item, laraItem)) return; SoundEffect(SFX_TR4_LARA_GENERAL_DEATH, &laraItem->Pose, SoundEnvironment::Always); @@ -111,10 +114,10 @@ void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase; // laraItem->Animation.ActiveState = EXTRA_TRAINKILL; // laraItem->Animation.TargetState = EXTRA_TRAINKILL; - laraItem->Pose.Orientation.y = trainItem->Pose.Orientation.y; - laraItem->Animation.Velocity.z = 0; - laraItem->Animation.Velocity.y = 0; laraItem->Animation.IsAirborne = false; + laraItem->Animation.Velocity.y = 0.0f; + laraItem->Animation.Velocity.z = 0.0f; + laraItem->Pose.Orientation.y = item->Pose.Orientation.y; DoDamage(laraItem, INT_MAX); @@ -126,13 +129,13 @@ void TrainCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll) laraInfo->HitDirection = -1; laraInfo->Air = -1; - trainItem->ItemFlags[1] = 160; + item->ItemFlags[1] = 160; - float s = phd_sin(trainItem->Pose.Orientation.y); - float c = phd_cos(trainItem->Pose.Orientation.y); + float sinY = phd_sin(item->Pose.Orientation.y); + float cosY = phd_cos(item->Pose.Orientation.y); - long x = laraItem->Pose.Position.x + CLICK(1) * s; - long z = laraItem->Pose.Position.z + CLICK(1) * c; + 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), trainItem->Pose.Orientation.y, laraItem->RoomNumber, 15); + DoLotsOfBlood(x, laraItem->Pose.Position.y - CLICK(2), z, SECTOR(1), item->Pose.Orientation.y, laraItem->RoomNumber, 15); } diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index 15a7c8de9..e236bb6e2 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -67,13 +67,14 @@ namespace TEN::Entities::TR4 item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 20 && // Hardcoded frame range. item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 60) { - // Blades incur damage cumulatively. + // Blades deal damage cumulatively. for (int i = 0; i < StargateHarmJoints.size(); i++) { if (item->TestBits(JointBitType::Touch, StargateHarmJoints[i])); { DoDamage(laraItem, STARGATE_HARM_DAMAGE); - DoBloodSplat((GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32, + DoBloodSplat( + (GetRandomControl() & 0x3F) + laraItem->Pose.Position.x - 32, (GetRandomControl() & 0x1F) + CreatureSpheres[i].y - 16, (GetRandomControl() & 0x3F) + laraItem->Pose.Position.z - 32, (GetRandomControl() & 3) + 2, From 93734075689cdf1548dd748a87940115ba9e6b9d Mon Sep 17 00:00:00 2001 From: Sezz Date: Thu, 8 Sep 2022 23:28:24 +1000 Subject: [PATCH 084/106] Use WALL_MASK --- TombEngine/Game/control/box.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TombEngine/Game/control/box.cpp b/TombEngine/Game/control/box.cpp index cc335bdf4..5b79c749b 100644 --- a/TombEngine/Game/control/box.cpp +++ b/TombEngine/Game/control/box.cpp @@ -511,14 +511,14 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) shiftZ = prevPos.z / SECTOR(1); if (xPos < shiftX) - item->Pose.Position.x = prevPos.x & (~(SECTOR(1) - 1)); + item->Pose.Position.x = prevPos.x & (~WALL_MASK); else if (xPos > shiftX) - item->Pose.Position.x = prevPos.x | (SECTOR(1) - 1); + item->Pose.Position.x = prevPos.x | WALL_MASK; if (zPos < shiftZ) - item->Pose.Position.z = prevPos.z & (~(SECTOR(1) - 1)); + item->Pose.Position.z = prevPos.z & (~WALL_MASK); else if (zPos > shiftZ) - item->Pose.Position.z = prevPos.z | (SECTOR(1) - 1); + item->Pose.Position.z = prevPos.z | (WALL_MASK); floor = GetFloor(item->Pose.Position.x, y, item->Pose.Position.z, &roomNumber); height = g_Level.Boxes[floor->Box].height; @@ -539,8 +539,8 @@ int CreatureAnimation(short itemNumber, short angle, short tilt) int x = item->Pose.Position.x; int z = item->Pose.Position.z; - xPos = x & (SECTOR(1) - 1); - zPos = z & (SECTOR(1) - 1); + xPos = x & WALL_MASK; + zPos = z & WALL_MASK; short radius = Objects[item->ObjectNumber].radius; shiftX = 0; shiftZ = 0; From 568019e4be24356ca3269500d377fc25d97ebac4 Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 8 Sep 2022 19:19:56 +0100 Subject: [PATCH 085/106] Add documentation for PercentToScreen --- Documentation/doc/1 modules/Misc.html | 13 ++++++++++++- .../Internal/TEN/Logic/LogicHandler.cpp | 2 +- .../Internal/TEN/Misc/Miscellanous.cpp | 17 +++++++++++++---- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/Documentation/doc/1 modules/Misc.html b/Documentation/doc/1 modules/Misc.html index 8880a8651..f525e59d3 100644 --- a/Documentation/doc/1 modules/Misc.html +++ b/Documentation/doc/1 modules/Misc.html @@ -477,6 +477,17 @@ To be used with local halfwayX, halfwayY = PercentToScreen(50, 50) +local baddy +local spawnLocationNullmesh = GetMoveableByName("position_behind_left_pillar") +local str1 = DisplayString("You spawned a baddy!", halfwayX, halfwayY, Color(255, 100, 100), false, {DisplayStringOption.SHADOW, DisplayStringOption.CENTER}) + +LevelFuncs.triggerOne = function(obj) + ShowString(str1, 4) +end
      +
  • @@ -632,7 +643,7 @@ To be used with
    generated by LDoc 1.4.6 -Last updated 2022-09-07 20:56:06 +Last updated 2022-09-08 19:16:14
    diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 51e33c0b3..ae3bf1f42 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -431,7 +431,7 @@ void LogicHandler::GetVariables(std::vector & vars) // The purpose of this is to only store each value once, and to fill our tables with // indices to the values rather than copies of the values. - auto handleNum = [&](double num) + auto handleNum = [&](double num) { auto [first, second] = numMap.insert(std::make_pair(num, nVars)); diff --git a/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp b/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp index d63c2d78b..6b44a5688 100644 --- a/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp +++ b/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp @@ -120,10 +120,10 @@ namespace Misc PlaySoundTrack(trackName, SoundTrackType::BGM); } - /// Play sound effect - //@function PlaySound - //@tparam int sound ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window. - ////@tparam[opt] Vec3 position The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional. + /// Play sound effect + //@function PlaySound + //@tparam int sound ID to play. Corresponds to the value in the sound XML file or Tomb Editor's "Sound Infos" window. + ////@tparam[opt] Vec3 position The 3D position of the sound, i.e. where the sound "comes from". If not given, the sound will not be positional. static void PlaySoundEffect(int id, sol::optional p) { SoundEffect(id, p.has_value() ? &PHD_3DPOS(p.value().x, p.value().y, p.value().z) : nullptr, SoundEnvironment::Always); @@ -178,6 +178,15 @@ namespace Misc //@tparam float y percent value to translate to y-coordinate //@treturn int x coordinate in pixels //@treturn int y coordinate in pixels + //@usage + //local halfwayX, halfwayY = PercentToScreen(50, 50) + //local baddy + //local spawnLocationNullmesh = GetMoveableByName("position_behind_left_pillar") + //local str1 = DisplayString("You spawned a baddy!", halfwayX, halfwayY, Color(255, 100, 100), false, {DisplayStringOption.SHADOW, DisplayStringOption.CENTER}) + // + //LevelFuncs.triggerOne = function(obj) + // ShowString(str1, 4) + //end static std::tuple PercentToScreen(double x, double y) { auto fWidth = static_cast(g_Configuration.Width); From 74ce2183beabd4c07a6eb4b4da422420e2f58a0b Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 8 Sep 2022 19:25:22 +0100 Subject: [PATCH 086/106] Update Timer doc to give warning about names. --- Documentation/doc/5 lua utility modules/Timer.html | 2 ++ Scripts/Engine/Timer.lua | 2 ++ 2 files changed, 4 insertions(+) diff --git a/Documentation/doc/5 lua utility modules/Timer.html b/Documentation/doc/5 lua utility modules/Timer.html index 1ed60812c..4202feb5b 100644 --- a/Documentation/doc/5 lua utility modules/Timer.html +++ b/Documentation/doc/5 lua utility modules/Timer.html @@ -209,6 +209,8 @@ local myTimeFormat4 = {seconds = true}

    At any given time, only one timer can show its countdown.

    +

    Do not give your timers a name beginning with __TEN, as this is reserved for timers used by other internal libaries.

    +

    Use this sparingly; in the classics, timed challenges did not have visible countdowns. For shorter timers, the gameplay benefit from showing the remaining time might not be necessary, and could interfere with the atmosphere of the level. The LevelFunc function to call when the time is up diff --git a/Scripts/Engine/Timer.lua b/Scripts/Engine/Timer.lua index 65f6981e9..e0ab99df2 100644 --- a/Scripts/Engine/Timer.lua +++ b/Scripts/Engine/Timer.lua @@ -57,6 +57,8 @@ Timer = { -- --__At any given time, only one timer can show its countdown__. -- + --__Do not give your timers a name beginning with __TEN, as this is reserved for timers used by other internal libaries__. + -- --Use this sparingly; in the classics, timed challenges did not have visible countdowns. For shorter timers, the gameplay benefit from showing the remaining time might not be necessary, and could interfere with the atmosphere of the level. -- -- @string name A label to give this timer; used to retrieve the timer later From 7d9d29962d46572c06ef7684cdc185abdb090aef Mon Sep 17 00:00:00 2001 From: hispidence Date: Thu, 8 Sep 2022 19:46:26 +0100 Subject: [PATCH 087/106] Fix merge mistakes --- TombEngine/Game/pickup/pickup_misc_items.cpp | 2 +- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/TombEngine/Game/pickup/pickup_misc_items.cpp b/TombEngine/Game/pickup/pickup_misc_items.cpp index b44c69a2c..e145ebcbb 100644 --- a/TombEngine/Game/pickup/pickup_misc_items.cpp +++ b/TombEngine/Game/pickup/pickup_misc_items.cpp @@ -32,7 +32,7 @@ auto LaserSightIsEquipped(LaraInfo& lara) return false; }; -static bool TryModifyMiscCount(LaraInfo & lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType) +bool TryModifyMiscCount(LaraInfo & lara, GAME_OBJECT_ID objectID, std::optional amount, ModificationType modType) { // If adding, replace the small/large waterskin with one of the requested // capacity. If removing, only remove the waterskin if it contains the given diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index 28a12e067..d2bc2d41f 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -580,6 +580,11 @@ void LogicHandler::ExecuteScriptFile(const std::string & luaFilename) m_handler.ExecuteScript(luaFilename); } +void LogicHandler::ExecuteString(const std::string& command) +{ + m_handler.ExecuteString(command); +} + // These wind up calling CallLevelFunc, which is where all the error checking is. void LogicHandler::ExecuteFunction(std::string const& name, short idOne, short idTwo) { From c9566b9f8936795e6685f7cce7d50881738457de Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 9 Sep 2022 10:21:22 +1000 Subject: [PATCH 088/106] Rename --- TombEngine/Game/collision/collide_item.cpp | 4 ++-- TombEngine/Game/collision/collide_item.h | 2 +- TombEngine/Objects/TR3/Trap/train.cpp | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index d8e7b77a2..8a94c3360 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -515,9 +515,9 @@ bool ItemNearLara(PHD_3DPOS* pos, int radius) return false; } -bool ItemNearTarget(PHD_3DPOS* fromPose, ItemInfo* targetEntity, int radius) +bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* targetEntity, int radius) { - auto pos = fromPose->Position - targetEntity->Pose.Position; + auto pos = origin->Position - targetEntity->Pose.Position; if (!ItemCollide(pos.y, ITEM_RADIUS_YMAX)) return false; diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index 8afa6612a..48b9e0396 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -37,7 +37,7 @@ bool AlignLaraPosition(Vector3Int* offset, ItemInfo* item, ItemInfo* laraItem); bool MoveLaraPosition(Vector3Int* pos, ItemInfo* item, ItemInfo* laraItem); bool ItemNearLara(PHD_3DPOS* pos, int radius); -bool ItemNearTarget(PHD_3DPOS* fromPose, ItemInfo* targetEntity, int radius); +bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* targetEntity, int radius); bool Move3DPosTo3DPos(PHD_3DPOS* fromPose, PHD_3DPOS* toPose, int velocity, short angleAdd); diff --git a/TombEngine/Objects/TR3/Trap/train.cpp b/TombEngine/Objects/TR3/Trap/train.cpp index aa6ac7522..f5832279f 100644 --- a/TombEngine/Objects/TR3/Trap/train.cpp +++ b/TombEngine/Objects/TR3/Trap/train.cpp @@ -48,10 +48,10 @@ void TrainControl(short itemNumber) item->ItemFlags[0] = item->ItemFlags[1] = TRAIN_VEL; float sinY = phd_sin(item->Pose.Orientation.y); - float cozY = phd_cos(item->Pose.Orientation.y); + float cosY = phd_cos(item->Pose.Orientation.y); item->Pose.Position.x += item->ItemFlags[1] * sinY; - item->Pose.Position.z += item->ItemFlags[1] * cozY; + item->Pose.Position.z += item->ItemFlags[1] * cosY; short roomNumber; long rh = TrainTestHeight(item, 0, SECTOR(5), &roomNumber); @@ -72,7 +72,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) * cozY, 16, 31, 31, 31); + TriggerDynamicLight(item->Pose.Position.x + SECTOR(3) * sinY, item->Pose.Position.y, item->Pose.Position.z + SECTOR(3) * cosY, 16, 31, 31, 31); if (item->ItemFlags[1] != TRAIN_VEL) { @@ -83,7 +83,7 @@ void TrainControl(short itemNumber) if (!UseForcedFixedCamera) { ForcedFixedCamera.x = item->Pose.Position.x + SECTOR(8) * sinY; - ForcedFixedCamera.z = item->Pose.Position.z + SECTOR(8) * cozY; + ForcedFixedCamera.z = item->Pose.Position.z + SECTOR(8) * cosY; ForcedFixedCamera.y = GetCollision(ForcedFixedCamera.x, item->Pose.Position.y - CLICK(2), ForcedFixedCamera.z, item->RoomNumber).Position.Floor; From 5abaa816e599c69e436986894239882d837ac163 Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 9 Sep 2022 10:49:10 +1000 Subject: [PATCH 089/106] Simplify --- TombEngine/Game/collision/collide_item.cpp | 44 +++++++++++----------- TombEngine/Game/collision/collide_item.h | 2 +- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 8a94c3360..ceede6bcf 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -878,12 +878,12 @@ void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll) } } -bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, CollisionInfo* coll) +bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pose, CollisionInfo* coll) { bool result = false; // Get DX static bounds in global coordinates. - auto staticBounds = TO_DX_BBOX(pos, box); + auto staticBounds = TO_DX_BBOX(pose, box); // Get local TR bounds and DX item bounds in global coordinates. auto itemBBox = GetBoundsAccurate(item); @@ -1021,22 +1021,22 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis return result; // Determine identity orientation/distance. - auto distance = item->Pose.Position.ToVector3() - pos.Position.ToVector3(); - auto sinY = phd_sin(pos.Orientation.y); - auto cosY = phd_cos(pos.Orientation.y); + auto distance = (item->Pose.Position - pose.Position).ToVector3(); + auto sinY = phd_sin(pose.Orientation.y); + auto cosY = phd_cos(pose.Orientation.y); // Rotate item to collision bounds identity. - auto x = round((distance.x * cosY) - (distance.z * sinY)) + pos.Position.x; + auto x = round((distance.x * cosY) - (distance.z * sinY)) + pose.Position.x; auto y = item->Pose.Position.y; - auto z = round((distance.x * sinY) + (distance.z * cosY)) + pos.Position.z; + auto z = round((distance.x * sinY) + (distance.z * cosY)) + pose.Position.z; // Determine identity static collision bounds. - auto XMin = pos.Position.x + box->X1; - auto XMax = pos.Position.x + box->X2; - auto YMin = pos.Position.y + box->Y1; - auto YMax = pos.Position.y + box->Y2; - auto ZMin = pos.Position.z + box->Z1; - auto ZMax = pos.Position.z + box->Z2; + auto XMin = pose.Position.x + box->X1; + auto XMax = pose.Position.x + box->X2; + auto YMin = pose.Position.y + box->Y1; + auto YMax = pose.Position.y + box->Y2; + auto ZMin = pose.Position.z + box->Z1; + auto ZMax = pose.Position.z + box->Z2; // Determine item collision bounds. auto inXMin = x + collBox.X1; @@ -1073,12 +1073,12 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis rawShift.z = shiftRight; // Rotate previous collision position to identity. - distance = coll->Setup.OldPosition.ToVector3() - pos.Position.ToVector3(); - auto ox = round((distance.x * cosY) - (distance.z * sinY)) + pos.Position.x; - auto oz = round((distance.x * sinY) + (distance.z * cosY)) + pos.Position.z; + distance = (coll->Setup.OldPosition - pose.Position).ToVector3(); + auto ox = round((distance.x * cosY) - (distance.z * sinY)) + pose.Position.x; + auto oz = round((distance.x * sinY) + (distance.z * cosY)) + pose.Position.z; // Calculate collisison type based on identity orientation. - switch (GetQuadrant(coll->Setup.ForwardAngle - pos.Orientation.y)) + switch (GetQuadrant(coll->Setup.ForwardAngle - pose.Orientation.y)) { case NORTH: if (rawShift.x > coll->Setup.Radius || rawShift.x < -coll->Setup.Radius) @@ -1170,13 +1170,13 @@ bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, Collis } // Determine final shifts orientation/distance. - distance = Vector3(x + coll->Shift.x, y, z + coll->Shift.z) - pos.Position.ToVector3(); - sinY = phd_sin(-pos.Orientation.y); - cosY = phd_cos(-pos.Orientation.y); + distance = Vector3(x + coll->Shift.x, y, z + coll->Shift.z) - pose.Position.ToVector3(); + sinY = phd_sin(-pose.Orientation.y); + cosY = phd_cos(-pose.Orientation.y); // Calculate final shifts orientation/distance. - coll->Shift.x = (round((distance.x * cosY) - (distance.z * sinY)) + pos.Position.x) - item->Pose.Position.x; - coll->Shift.z = (round((distance.x * sinY) + (distance.z * cosY)) + pos.Position.z) - item->Pose.Position.z; + coll->Shift.x = (round((distance.x * cosY) - (distance.z * sinY)) + pose.Position.x) - item->Pose.Position.x; + coll->Shift.z = (round((distance.x * sinY) + (distance.z * cosY)) + pose.Position.z) - item->Pose.Position.z; if (coll->Shift.x == 0 && coll->Shift.z == 0) coll->CollisionType = CT_NONE; // Paranoid. diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index 48b9e0396..3ac370547 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -46,7 +46,7 @@ bool TestBoundsCollideStatic(ItemInfo* item, MESH_INFO* mesh, int radius); bool ItemPushItem(ItemInfo* item, ItemInfo* laraItem, CollisionInfo* coll, bool spasmEnabled, char bigPush); bool ItemPushStatic(ItemInfo* laraItem, MESH_INFO* mesh, CollisionInfo* coll); -bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pos, CollisionInfo* coll); +bool CollideSolidBounds(ItemInfo* item, BOUNDING_BOX* box, PHD_3DPOS pose, CollisionInfo* coll); void CollideSolidStatics(ItemInfo* item, CollisionInfo* coll); void AIPickupCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); From 57087c14f8b42aa5caeaaac90dce8c3bd3d7d1bf Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 9 Sep 2022 11:17:16 +1000 Subject: [PATCH 090/106] Add distance methods to Vector3Int; rename --- TombEngine/Game/collision/collide_item.cpp | 14 +++++++------- TombEngine/Game/collision/collide_item.h | 2 +- TombEngine/Specific/phd_global.h | 18 ++++++++++++++---- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index ceede6bcf..01d4ba126 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -491,12 +491,12 @@ static bool ItemInRange(int x, int z, int radius) return ((SQUARE(x) + SQUARE(z)) <= SQUARE(radius)); } -bool ItemNearLara(PHD_3DPOS* pos, int radius) +bool ItemNearLara(PHD_3DPOS* origin, int radius) { auto target = GameVector( - pos->Position.x - LaraItem->Pose.Position.x, - pos->Position.y - LaraItem->Pose.Position.y, - pos->Position.z - LaraItem->Pose.Position.z + origin->Position.x - LaraItem->Pose.Position.x, + origin->Position.y - LaraItem->Pose.Position.y, + origin->Position.z - LaraItem->Pose.Position.z ); if (!ItemCollide(target.y, ITEM_RADIUS_YMAX)) @@ -538,16 +538,16 @@ bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* targetEntity, int radius) bool Move3DPosTo3DPos(PHD_3DPOS* fromPose, PHD_3DPOS* toPose, int velocity, short angleAdd) { auto direction = toPose->Position - fromPose->Position; - int distance = sqrt(SQUARE(direction.x) + SQUARE(direction.y) + SQUARE(direction.z)); + float distance = Vector3Int::Distance(fromPose->Position, toPose->Position); if (velocity < distance) - fromPose->Position += direction * velocity / distance; + fromPose->Position += direction * (velocity / distance); else fromPose->Position = toPose->Position; if (!Lara.Control.IsMoving) { - bool shouldAnimate = (distance - velocity) > (velocity * ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD); + bool shouldAnimate = ((distance - velocity) > (velocity * ANIMATED_ALIGNMENT_FRAME_COUNT_THRESHOLD)); if (shouldAnimate && Lara.Control.WaterStatus != WaterStatus::Underwater) { diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index 3ac370547..c234adb4c 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -36,7 +36,7 @@ bool TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ItemInfo* item, ItemInfo* bool AlignLaraPosition(Vector3Int* offset, ItemInfo* item, ItemInfo* laraItem); bool MoveLaraPosition(Vector3Int* pos, ItemInfo* item, ItemInfo* laraItem); -bool ItemNearLara(PHD_3DPOS* pos, int radius); +bool ItemNearLara(PHD_3DPOS* origin, int radius); bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* targetEntity, int radius); bool Move3DPosTo3DPos(PHD_3DPOS* fromPose, PHD_3DPOS* toPose, int velocity, short angleAdd); diff --git a/TombEngine/Specific/phd_global.h b/TombEngine/Specific/phd_global.h index 920331296..126c91ce4 100644 --- a/TombEngine/Specific/phd_global.h +++ b/TombEngine/Specific/phd_global.h @@ -41,11 +41,21 @@ struct Vector3Int this->z = z; } - Vector3Int(Vector3 v) + Vector3Int(Vector3 vector) { - this->x = int(v.x); - this->y = int(v.y); - this->z = int(v.z); + this->x = int(vector.x); + this->y = int(vector.y); + this->z = int(vector.z); + } + + static float Distance(const Vector3Int& origin, const Vector3Int& target) + { + return Vector3::Distance(origin.ToVector3(), target.ToVector3()); + } + + static float DistanceSquared(const Vector3Int& origin, const Vector3Int& target) + { + return Vector3::DistanceSquared(origin.ToVector3(), target.ToVector3()); } Vector3 ToVector3() const From 31959cc0ab31280a3d151928575fc5c32491794d Mon Sep 17 00:00:00 2001 From: Sezz Date: Fri, 9 Sep 2022 16:23:00 +1000 Subject: [PATCH 091/106] Cleanup --- TombEngine/Game/collision/collide_item.cpp | 12 ++++++------ TombEngine/Game/collision/collide_item.h | 2 +- TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp | 6 +++--- TombEngine/Objects/TR4/Trap/tr4_stargate.cpp | 10 +++++----- TombEngine/Objects/TR4/Trap/tr4_stargate.h | 4 ++-- TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp | 16 ++++++++-------- TombEngine/Objects/TR4/tr4_objects.cpp | 4 +++- 7 files changed, 28 insertions(+), 26 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 01d4ba126..77f4d1ae0 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -271,10 +271,10 @@ bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, Collision { auto* framePtr = GetBestFrame(laraItem); - if (item->Pose.Position.y + GlobalCollisionBounds.Y2 <= laraItem->Pose.Position.y + framePtr->boundingBox.Y1) + if ((item->Pose.Position.y + GlobalCollisionBounds.Y2) <= (laraItem->Pose.Position.y + framePtr->boundingBox.Y1)) return false; - if (item->Pose.Position.y + GlobalCollisionBounds.Y1 >= framePtr->boundingBox.Y2) + if ((item->Pose.Position.y + GlobalCollisionBounds.Y1) >= framePtr->boundingBox.Y2) return false; float sinY = phd_sin(item->Pose.Orientation.y); @@ -286,10 +286,10 @@ bool TestWithGlobalCollisionBounds(ItemInfo* item, ItemInfo* laraItem, Collision int x = (dx * cosY) - (dz * sinY); int z = (dz * cosY) + (dx * sinY); - if (x < GlobalCollisionBounds.X1 - coll->Setup.Radius || - x > GlobalCollisionBounds.X2 + coll->Setup.Radius || - z < GlobalCollisionBounds.Z1 - coll->Setup.Radius || - z > GlobalCollisionBounds.Z2 + coll->Setup.Radius) + if (x < (GlobalCollisionBounds.X1 - coll->Setup.Radius) || + x > (GlobalCollisionBounds.X2 + coll->Setup.Radius) || + z < (GlobalCollisionBounds.Z1 - coll->Setup.Radius) || + z > (GlobalCollisionBounds.Z2 + coll->Setup.Radius)) { return false; } diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index c234adb4c..01c8f3c2f 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -10,7 +10,7 @@ struct MESH_INFO; constexpr auto MAX_COLLIDED_OBJECTS = 1024; constexpr auto ITEM_RADIUS_YMAX = SECTOR(3); -constexpr auto VEHICLE_COLLISION_TERMINAL_VELOCITY = 30; +constexpr auto VEHICLE_COLLISION_TERMINAL_VELOCITY = 30.0f; extern BOUNDING_BOX GlobalCollisionBounds; extern ItemInfo* CollidedItems[MAX_COLLIDED_OBJECTS]; diff --git a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp index 6bdf4f566..ea609102e 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp @@ -15,7 +15,7 @@ namespace TEN::Entities::TR4 { auto* item = &g_Level.Items[itemNumber]; - // Set bone mutators to 0 by default + // Set bone mutators to 0 by default. for (int i = 0; i < item->Animation.Mutator.size(); i++) item->Animation.Mutator[i].Scale.y = 0.0f; @@ -24,7 +24,7 @@ namespace TEN::Entities::TR4 auto probe = GetCollision(item); - // TODO: check this optimized division + // TODO: Check this optimized division. //v6 = 1321528399i64 * ((probe.Position.Floor - probe.Position.Ceiling) << 12); //item->itemFlags[3] = (HIDWORD(v6) >> 31) + (SHIDWORD(v6) >> 10); @@ -78,7 +78,7 @@ namespace TEN::Entities::TR4 item->Pose.Orientation.y += item->ItemFlags[0]; - // Update bone mutators + // Update bone mutators. if (item->ItemFlags[1]) { for (int i = 0; i < item->Animation.Mutator.size(); i++) diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index e236bb6e2..7f2afc884 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -14,7 +14,7 @@ using std::vector; -namespace TEN::Entities::TR4 +namespace TEN::Entities::Traps { constexpr auto STARGATE_HARM_DAMAGE = 100; @@ -49,10 +49,7 @@ namespace TEN::Entities::TR4 if (item->Status == ITEM_INVISIBLE) return; - if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) - return; - - // TODO: Define bounds for collision with the border. + // TODO: Border collision. /*for (auto& bounds : StargateBounds) { GlobalCollisionBounds.X1 = bounds.x; @@ -63,6 +60,9 @@ namespace TEN::Entities::TR4 ItemPushItem(item, laraItem, coll, 0, 2); }*/ + if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) + return; + if (TriggerActive(item) && item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 20 && // Hardcoded frame range. item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 60) diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.h b/TombEngine/Objects/TR4/Trap/tr4_stargate.h index 7fe4566d3..0d64e613e 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.h +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.h @@ -1,9 +1,9 @@ #pragma once -struct ItemInfo; struct CollisionInfo; +struct ItemInfo; -namespace TEN::Entities::TR4 +namespace TEN::Entities::Traps { void StargateControl(short itemNumber); void StargateCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll); diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp index a07c64af2..1130e9806 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp @@ -13,8 +13,8 @@ namespace TEN::Entities::TR4 { - constexpr auto TEETH_SPIKE_HARM_CONSTANT = 8; - constexpr auto TEETH_SPIKE_HARM_EMERGING = 30; + constexpr auto TEETH_SPIKE_HARM_DAMAGE_CONSTANT = 8; + constexpr auto TEETH_SPIKE_HARM_DAMAGE_EMERGING = 30; constexpr auto TEETH_SPIKES_DEFAULT_INTERVAL = 64; constexpr auto TEETH_SPIKE_BOUNDS_TOLERANCE_RATIO = 0.95f; @@ -37,7 +37,7 @@ namespace TEN::Entities::TR4 auto spikeBox = TO_DX_BBOX(item->Pose, GetBoundsAccurate(item)); auto itemBox = TO_DX_BBOX(collidingItem->Pose, GetBoundsAccurate(collidingItem)); - // Make intersection a bit more forgiving by reducing spike bounds a bit. + // Make intersection more forgiving by slightly reducing spike bounds. spikeBox.Extents = spikeBox.Extents * TEETH_SPIKE_BOUNDS_TOLERANCE_RATIO; return spikeBox.Contains(itemBox); } @@ -96,16 +96,16 @@ namespace TEN::Entities::TR4 if ((item->ItemFlags[0] >= 1024 || LaraItem->Animation.IsAirborne) && (angle > PI * 0.25f && angle < PI * 0.75f)) { - if (LaraItem->Animation.Velocity.y > 6 || item->ItemFlags[0] > 1024) + if (LaraItem->Animation.Velocity.y > 6.0f || item->ItemFlags[0] > 1024) { LaraItem->HitPoints = -1; bloodCount = 20; } } // Spikes are emerging or already fully protruded (in latter case, only damage Lara if she runs). - else if ((item->TriggerFlags != 1) || LaraItem->Animation.Velocity.z >= 30) + else if ((item->TriggerFlags != 1) || LaraItem->Animation.Velocity.z >= 30.0f) { - int damage = item->ItemFlags[0] == 1024 ? TEETH_SPIKE_HARM_EMERGING : TEETH_SPIKE_HARM_CONSTANT; + int damage = item->ItemFlags[0] == 1024 ? TEETH_SPIKE_HARM_DAMAGE_EMERGING : TEETH_SPIKE_HARM_DAMAGE_CONSTANT; DoDamage(LaraItem, damage); bloodCount = (GetRandomControl() & 3) + 2; } @@ -117,15 +117,15 @@ namespace TEN::Entities::TR4 int yTop = laraBounds->Y1 + LaraItem->Pose.Position.y; int yBottom = laraBounds->Y2 + LaraItem->Pose.Position.y; + // Spikes are downward; move blood origin to top. if (angle < PI * 0.125f || angle > PI * 0.825f) { - // Spikes are downward; move blood origin to top. y1 = -bounds->Y2; y2 = -bounds->Y1; } + // Spikes are upward; leave origin as is. else { - // Spikes are upward; leave origin as is. y1 = bounds->Y1; y2 = bounds->Y2; } diff --git a/TombEngine/Objects/TR4/tr4_objects.cpp b/TombEngine/Objects/TR4/tr4_objects.cpp index 4e3b03ff3..68c5c733c 100644 --- a/TombEngine/Objects/TR4/tr4_objects.cpp +++ b/TombEngine/Objects/TR4/tr4_objects.cpp @@ -77,8 +77,10 @@ #include "tr4_teethspike.h" // Vehicles -#include "Objects/TR4/Vehicles/motorbike.h" #include "Objects/TR4/Vehicles/jeep.h" +#include "Objects/TR4/Vehicles/motorbike.h" + +using namespace TEN::Entities::Traps; namespace TEN::Entities { From 7d82d4a4bb5e21d1a28fbf9b2a80cc982bf56ebf Mon Sep 17 00:00:00 2001 From: Sezz Date: Mon, 12 Sep 2022 14:06:07 +1000 Subject: [PATCH 092/106] Convert some probability values to fractions; remove cobra flags --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 8 ++++---- TombEngine/Objects/TR1/Entity/tr1_wolf.cpp | 4 ++-- TombEngine/Objects/TR2/Entity/tr2_silencer.cpp | 2 +- TombEngine/Objects/TR2/Entity/tr2_yeti.cpp | 8 ++++---- TombEngine/Objects/TR3/Entity/tr3_cobra.cpp | 9 ++------- TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp | 10 +++++----- TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp | 4 ++-- TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp | 12 ++++++------ TombEngine/Objects/TR4/Entity/tr4_baboon.cpp | 4 ++-- TombEngine/Objects/TR4/Entity/tr4_baddy.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_dog.cpp | 8 ++++---- TombEngine/Objects/TR4/Entity/tr4_mummy.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_sas.cpp | 4 ++-- TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_troops.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_doberman.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp | 2 +- TombEngine/Objects/TR5/Entity/tr5_lion.cpp | 4 ++-- 21 files changed, 45 insertions(+), 50 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index da31a49a3..96bba9a44 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -26,10 +26,10 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 0.32f; constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 0.47f; constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 0.63f; - constexpr auto APE_RUN_JUMP_CHANCE = 0.005f; - constexpr auto APE_RUN_POUND_CHEST_CHANCE = 0.01f; - constexpr auto APE_RUN_POUND_GROUND_CHANCE = 0.015f; - constexpr auto APE_RUN_RUN_LEFT_CHANCE = 0.02f; + constexpr auto APE_RUN_JUMP_CHANCE = APE_IDLE_JUMP_CHANCE / 32; + constexpr auto APE_RUN_POUND_CHEST_CHANCE = APE_IDLE_POUND_CHEST_CHANCE / 32; + constexpr auto APE_RUN_POUND_GROUND_CHANCE = APE_IDLE_POUND_GROUND_CHANCE / 32; + constexpr auto APE_RUN_RUN_LEFT_CHANCE = APE_RUN_RUN_LEFT_CHANCE / 32; constexpr auto APE_SHIFT = 75; diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp index cdb15b63b..1e4f7a3c2 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp @@ -23,8 +23,8 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto WOLF_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); constexpr auto WOLF_STALK_RANGE = SQUARE(SECTOR(2)); - constexpr auto WOLF_WAKE_CHANCE = 0.00095f; - constexpr auto WOLF_SLEEP_CHANCE = 0.00095f; + constexpr auto WOLF_WAKE_CHANCE = 1.0f / 1000; + constexpr auto WOLF_SLEEP_CHANCE = 1.0f / 1000; constexpr auto WOLF_HOWL_CHANCE = 0.012f; constexpr auto WOLF_SLEEP_FRAME = 96; diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index 515b9f59d..25e72c891 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -236,7 +236,7 @@ namespace TEN::Entities::Creatures::TR2 } else { - if (creature->Mood == MoodType::Attack || TestProbability(0.008f)) + if (creature->Mood == MoodType::Attack || TestProbability(1.0f / 128.0f)) item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; if (!AI.ahead) diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp index 8dcd9889c..654774122 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp @@ -91,7 +91,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = item->Animation.RequiredState; else if (info->Mood == MoodType::Bored) { - if (TestProbability(0.008f) || !isLaraAlive) + if (TestProbability(1.0f / 128.0f) || !isLaraAlive) item->Animation.TargetState = 7; else if (TestProbability(0.015f)) item->Animation.TargetState = 9; @@ -119,7 +119,7 @@ namespace TEN::Entities::Creatures::TR2 { if (isLaraAlive) { - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = 2; else if (TestProbability(0.015f)) item->Animation.TargetState = 9; @@ -143,7 +143,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 2; else if (info->Mood == MoodType::Bored) { - if (TestProbability(0.008f) || !isLaraAlive) + if (TestProbability(1.0f / 128.0f) || !isLaraAlive) item->Animation.TargetState = 7; else if (TestProbability(0.015f)) item->Animation.TargetState = 2; @@ -168,7 +168,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 1; else if (info->Mood == MoodType::Bored) { - if (TestProbability(0.008f) || !isLaraAlive) + if (TestProbability(1.0f / 128.0f) || !isLaraAlive) { item->Animation.TargetState = 2; item->Animation.RequiredState = 7; diff --git a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp index 322e88500..fdd54f640 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_cobra.cpp @@ -47,11 +47,6 @@ namespace TEN::Entities::Creatures::TR3 COBRA_ANIM_DEATH = 4 }; - enum CobraFlags - { - COBRA_FLAG_ATTACKING = (1 << 0) - }; - void InitialiseCobra(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; @@ -155,12 +150,12 @@ namespace TEN::Entities::Creatures::TR3 break; case COBRA_STATE_ATTACK: - if (!(creature->Flags & COBRA_FLAG_ATTACKING) && + if (!(creature->Flags & 1) && // 1 = is attacking. item->TestBits(JointBitType::Touch, CobraAttackJoints)) { DoDamage(creature->Enemy, COBRA_BITE_ATTACK_DAMAGE); CreatureEffect(item, CobraBite, DoBloodSplat); - creature->Flags |= COBRA_FLAG_ATTACKING; + creature->Flags |= 1; // 1 = is attacking. if (creature->Enemy->IsLara()) GetLaraInfo(creature->Enemy)->PoisonPotency += COBRA_BITE_POISON_POTENCY; diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index 98b2038f7..0def0adba 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -149,7 +149,7 @@ namespace TEN::Entities::Creatures::TR3 { extraHeadRot.y = AIGuard(creature); - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = 4; break; @@ -165,9 +165,9 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = 2; } - else if (creature->Mood == MoodType::Bored && AI.ahead && TestProbability(0.008f)) + else if (creature->Mood == MoodType::Bored && AI.ahead && TestProbability(1.0f / 128.0f)) item->Animation.TargetState = 4; - else if (creature->Mood == MoodType::Attack || TestProbability(0.008f)) + else if (creature->Mood == MoodType::Attack || TestProbability(1.0f / 128.0f)) item->Animation.TargetState = 2; break; @@ -179,7 +179,7 @@ namespace TEN::Entities::Creatures::TR3 { extraHeadRot.y = AIGuard(creature); - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = 1; break; @@ -188,7 +188,7 @@ namespace TEN::Entities::Creatures::TR3 AI.distance < pow(SECTOR(4), 2) && (realEnemy != LaraItem || creature->HurtByLara) || creature->Mood != MoodType::Bored || - TestProbability(0.008f))) + TestProbability(1.0f / 128.0f))) { item->Animation.TargetState = 1; } diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index 5b912e7d1..0bc5c507f 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -421,7 +421,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = MONKEY_STATE_SIT; } else if (AI.bite && AI.distance < pow(682, 2)) diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index d7433e8c4..4de1542de 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -179,7 +179,7 @@ namespace TEN::Entities::Creatures::TR3 if (item->AIBits & GUARD) { head = AIGuard(creature); - if (TestProbability(0.004f)) + if (TestProbability(1.0f / 256.0f)) { if (item->Animation.ActiveState == MPSTICK_STATE_STOP) item->Animation.TargetState = MPSTICK_STATE_WAIT; @@ -234,7 +234,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MPSTICK_STATE_RUN; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) { item->Animation.RequiredState = MPSTICK_STATE_WAIT; item->Animation.TargetState = MPSTICK_STATE_STOP; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index 355f78f18..7e70a51af 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -152,7 +152,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn = 0; - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } else if (creature->Mood == MoodType::Escape) @@ -191,7 +191,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn = 0; - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } else if (creature->Mood == MoodType::Escape) @@ -224,7 +224,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn /= 4; - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) { if (TestProbability(0.25f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; @@ -255,7 +255,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn /= 4; - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) { if (TestProbability(0.5f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; @@ -450,7 +450,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.x = 0; extraTorsoRot.y = 0; - if (TestProbability(0.004f)) + if (TestProbability(1.0f / 256.0f)) item->Animation.TargetState = TRIBESMAN_STATE_IDLE; break; @@ -491,7 +491,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.x = 0; extraTorsoRot.y = 0; - if (TestProbability(0.004f)) + if (TestProbability(1.0f / 256.0f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp index 9232eea13..6058e1011 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp @@ -436,7 +436,7 @@ namespace TEN::Entities::TR4 { if (item->AIBits & FOLLOW) item->Animation.TargetState = BABOON_STATE_WALK_FORWARD; - else if (TestProbability(0.008f)) + else if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = BABOON_STATE_SIT_IDLE; } else if (creature->Mood == MoodType::Escape) @@ -446,7 +446,7 @@ namespace TEN::Entities::TR4 if (AI.bite && AI.distance < BABOON_ATTACK_READY_RANGE) item->Animation.TargetState = BABOON_STATE_IDLE; } - else if (TestProbability(0.008f)) + else if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = BABOON_STATE_SIT_IDLE; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp index 81e2377ef..609b9e5bd 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp @@ -1215,7 +1215,7 @@ namespace TEN::Entities::TR4 case BADDY_STATE_BLIND: if (!FlashGrenadeAftershockTimer) { - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = BADDY_STATE_IDLE; } diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp index 54113a7fc..5cbb23fb7 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp @@ -122,7 +122,7 @@ namespace TEN::Entities::TR4 angle = CreatureTurn(item, creature->MaxTurn); if (item->HitStatus || AI.distance > BIG_BEETLE_AWARE_RANGE || - TestProbability(0.008f)) + TestProbability(1.0f / 128.0f)) { creature->Flags = 0; } diff --git a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp index 707fec832..f97a3d9e8 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp @@ -169,7 +169,7 @@ namespace TEN::Entities::TR4 creature->Flags++; creature->MaxTurn = 0; - if (creature->Flags > 300 && TestProbability(0.004f)) + if (creature->Flags > 300 && TestProbability(1.0f / 256.0f)) item->Animation.TargetState = DOG_STATE_IDLE; } @@ -202,7 +202,7 @@ namespace TEN::Entities::TR4 else { if (item->Animation.ActiveState == DOG_STATE_STALK_IDLE && - TestProbability(0.004f)) + TestProbability(1.0f / 256.0f)) { item->Animation.TargetState = DOG_STATE_IDLE; break; @@ -243,7 +243,7 @@ namespace TEN::Entities::TR4 creature->MaxTurn = ANGLE(1.0f); creature->Flags = 0; - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) { if (item->AIBits & MODIFY) { @@ -279,7 +279,7 @@ namespace TEN::Entities::TR4 if (item->AIBits & PATROL1) item->Animation.TargetState = DOG_STATE_WALK_FORWARD; - else if (creature->Mood == MoodType::Bored && TestProbability(0.008f)) + else if (creature->Mood == MoodType::Bored && TestProbability(1.0f / 128.0f)) item->Animation.TargetState = DOG_STATE_IDLE; else item->Animation.TargetState = DOG_STATE_STALK; diff --git a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp index bbcf21b34..33b551ce3 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp @@ -255,7 +255,7 @@ namespace TEN::Entities::TR4 joint1 = 0; joint2 = 0; - if (AI.distance < MUMMY_ACTIVATE_RANGE || TestProbability(0.008f)) + if (AI.distance < MUMMY_ACTIVATE_RANGE || TestProbability(1.0f / 128.0f)) { item->Animation.TargetState = MUMMY_STATE_COLLAPSED_TO_IDLE; item->HitPoints = Objects[item->ObjectNumber].HitPoints; diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp index 41949f888..583cc3beb 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp @@ -629,7 +629,7 @@ namespace TEN::Entities::TR4 if (item->Animation.ActiveState == 1) { - if (TestProbability(0.008f)) + if (TestProbability(1.0f / 128.0f)) { item->Animation.TargetState = 2; AnimateItem(item); @@ -638,7 +638,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = 3; } else if (item->Animation.ActiveState == 4 && - TestProbability(0.008f)) + TestProbability(1.0f / 128.0f)) { item->Animation.TargetState = 5; AnimateItem(item); diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp index 15c8a16db..381a85ab5 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp @@ -649,7 +649,7 @@ namespace TEN::Entities::TR4 else item->Animation.TargetState = 2; } - else if (Lara.TargetEntity != item || item->MeshBits != -1 || Lara.Control.Weapon.GunType != LaraWeaponType::Shotgun || TestProbability(0.008f)) + else if (Lara.TargetEntity != item || item->MeshBits != -1 || Lara.Control.Weapon.GunType != LaraWeaponType::Shotgun || TestProbability(1.0f / 128.0f)) item->Animation.TargetState = 2; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp index 68102849d..a641fa965 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp @@ -455,7 +455,7 @@ namespace TEN::Entities::TR4 break; case TROOP_STATE_FLASHED: - if (!FlashGrenadeAftershockTimer && TestProbability(0.008f)) + if (!FlashGrenadeAftershockTimer && TestProbability(1.0f / 128.0f)) item->Animation.TargetState = TROOP_STATE_GUARD; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp index 7a10b5ef3..fdd1cb2bf 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp @@ -148,7 +148,7 @@ namespace TEN::Entities::TR4 if (AI.ahead && AI.distance) item->Animation.TargetState = BOAR_STATE_IDLE; - else if (TestProbability(0.008f)) + else if (TestProbability(1.0f / 128.0f)) item->Animation.TargetState = BOAR_STATE_IDLE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp index ca562e8fc..150553a6a 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp @@ -194,7 +194,7 @@ namespace TEN::Entities::Creatures::TR5 break; case DOBERMAN_STATE_SIT_IDLE: - if (creature->Mood != MoodType::Bored || TestProbability(0.008f)) + if (creature->Mood != MoodType::Bored || TestProbability(1.0f / 128.0f)) item->Animation.TargetState = DOBERMAN_STATE_STOP; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index 2bb89c123..078198e22 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -301,7 +301,7 @@ namespace TEN::Entities::Creatures::TR5 break; } } - else if (Lara.TargetEntity != item || TestProbability(0.008f)) + else if (Lara.TargetEntity != item || TestProbability(1.0f / 128.0f)) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp index f7dbe1196..2d2b73b49 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp @@ -142,7 +142,7 @@ namespace TEN::Entities::Creatures::TR5 if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.004f)) + if (TestProbability(1.0f / 256.0f)) { item->Animation.TargetState = LION_STATE_IDLE; item->Animation.RequiredState = LION_STATE_ROAR; @@ -165,7 +165,7 @@ namespace TEN::Entities::Creatures::TR5 item->Animation.TargetState = LION_STATE_IDLE; else if (creature->Mood != MoodType::Escape) { - if (TestProbability(0.004f)) + if (TestProbability(1.0f / 256.0f)) { item->Animation.TargetState = LION_STATE_IDLE; item->Animation.RequiredState = LION_STATE_ROAR; From b3f8cd14218dee701b476b474187ce015a3aedf6 Mon Sep 17 00:00:00 2001 From: Sezz Date: Mon, 12 Sep 2022 14:38:08 +1000 Subject: [PATCH 093/106] More fractions --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 10 +++++----- TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 96bba9a44..6b2f35625 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -22,14 +22,14 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto APE_ATTACK_RANGE = SQUARE(SECTOR(0.42f)); constexpr auto APE_PANIC_RANGE = SQUARE(SECTOR(2)); - constexpr auto APE_IDLE_JUMP_CHANCE = 0.16f; - constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 0.32f; - constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 0.47f; - constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 0.63f; + constexpr auto APE_IDLE_JUMP_CHANCE = 1.0f / 6.0f; + constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 1.0f / 3.0f; + constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 1.0f / 2.0f; + constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 1.0f / 1.5f; constexpr auto APE_RUN_JUMP_CHANCE = APE_IDLE_JUMP_CHANCE / 32; constexpr auto APE_RUN_POUND_CHEST_CHANCE = APE_IDLE_POUND_CHEST_CHANCE / 32; constexpr auto APE_RUN_POUND_GROUND_CHANCE = APE_IDLE_POUND_GROUND_CHANCE / 32; - constexpr auto APE_RUN_RUN_LEFT_CHANCE = APE_RUN_RUN_LEFT_CHANCE / 32; + constexpr auto APE_RUN_RUN_LEFT_CHANCE = APE_IDLE_RUN_LEFT_CHANCE / 32; constexpr auto APE_SHIFT = 75; diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp index 649050997..412fdadba 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp @@ -27,7 +27,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto BIG_RAT_POUNCE_ATTACK_RANGE = SQUARE(SECTOR(0.5f)); constexpr auto BIG_RAT_WATER_BITE_ATTACK_RANGE = SQUARE(SECTOR(0.3f)); - constexpr auto BIG_RAT_REAR_POSE_CHANCE = 0.008f; + constexpr auto BIG_RAT_REAR_POSE_CHANCE = 1.0f / 128.0f; constexpr auto BIG_RAT_SWIM_UP_DOWN_SPEED = 32; constexpr auto BIG_RAT_WATER_SURFACE_OFFSET = 10; diff --git a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp index e15d5e498..5039b4b4f 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_giant_mutant.cpp @@ -27,8 +27,8 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto MUTANT_CLOSE_RANGE = SQUARE(SECTOR(2.2f)); // TODO: Unused. - constexpr auto MUTANT_ATTACK_1_CHANCE = 0.33f; - constexpr auto MUTANT_ATTACK_2_CHANCE = 0.67f; + constexpr auto MUTANT_ATTACK_1_CHANCE = 1.0f / 3.0f; + constexpr auto MUTANT_ATTACK_2_CHANCE = MUTANT_ATTACK_1_CHANCE * 2; #define MUTANT_NEED_TURN ANGLE(45.0f) #define MUTANT_TURN ANGLE(3.0f) From 38e80d91ef43e3f7b41732d52990e4307c5c378e Mon Sep 17 00:00:00 2001 From: Sezz Date: Mon, 12 Sep 2022 15:05:01 +1000 Subject: [PATCH 094/106] Calculate distances properly --- TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 8 +--- TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 9 ++-- .../Objects/TR3/Entity/tr3_mp_stick.cpp | 44 ++++++++----------- TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 15 ++----- .../Objects/TR3/Entity/tr3_tribesman.cpp | 9 +--- TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp | 19 +++++--- 6 files changed, 43 insertions(+), 61 deletions(-) diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index 0bc5c507f..889c1512b 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -530,9 +530,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!creature->Flags && enemy != nullptr) { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < CLICK(1) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= CLICK(1) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < CLICK(1)) + if (Vector3Int::Distance(item->Pose.Position, enemy->Pose.Position) <= CLICK(1)) { DoDamage(enemy, 20); CreatureEffect(item, MonkeyBite, DoBloodSplat); @@ -572,9 +570,7 @@ namespace TEN::Entities::Creatures::TR3 { if (creature->Flags != 1 && enemy) { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < CLICK(1) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= CLICK(1) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < CLICK(1)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= CLICK(1)) { DoDamage(enemy, 25); CreatureEffect(item, MonkeyBite, DoBloodSplat); diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index 7d944b43f..959e9ed0f 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -310,7 +310,8 @@ namespace TEN::Entities::Creatures::TR3 } if (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 12 || - (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 1 && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 10)) + (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 1 && + item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 10)) { if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.RequiredState = MPGUN_STATE_WAIT; @@ -384,8 +385,10 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if ((item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 18 && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 17) || - (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 19 && item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 6)) + if ((item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 18 && + item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 17) || + (item->Animation.AnimNumber == Objects[ID_MP_WITH_GUN].animIndex + 19 && + item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 6)) { if (!ShotLara(item, &AI, MPGunBite, extraTorsoRot.y, 32)) item->Animation.RequiredState = MPGUN_STATE_WALK; diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index 4de1542de..e1da4525a 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -336,7 +336,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if (enemy->IsLara()) + if (creature->Enemy->IsLara()) { if (!creature->Flags && item->TestBits(JointBitType::Touch, MPStickPunchAttackJoints)) { @@ -348,11 +348,9 @@ namespace TEN::Entities::Creatures::TR3 } else { - if (!creature->Flags && enemy) + if (!creature->Flags && enemy != nullptr) { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < SECTOR(0.25f) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) { DoDamage(enemy, 5); CreatureEffect(item, MPStickBite1, DoBloodSplat); @@ -373,11 +371,11 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if (enemy->IsLara()) + if (creature->Enemy->IsLara()) { if (!creature->Flags && item->TestBits(JointBitType::Touch, MPStickPunchAttackJoints)) { - DoDamage(enemy, 80); + DoDamage(creature->Enemy, 80); CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; @@ -385,13 +383,11 @@ namespace TEN::Entities::Creatures::TR3 } else { - if (!creature->Flags && enemy) + if (!creature->Flags && creature->Enemy != nullptr) { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < SECTOR(0.25f) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) { - DoDamage(enemy, 5); + DoDamage(creature->Enemy, 5); CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; @@ -413,11 +409,11 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.y = AI.angle; } - if (enemy->IsLara()) + if (creature->Enemy->IsLara()) { if (creature->Flags != 2 && item->TestBits(JointBitType::Touch, MPStickPunchAttackJoints)) { - DoDamage(enemy, 100); + DoDamage(creature->Enemy, 100); CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(70, &item->Pose); creature->Flags = 2; @@ -425,13 +421,11 @@ namespace TEN::Entities::Creatures::TR3 } else { - if (creature->Flags != 2 && enemy) + if (creature->Flags != 2 && creature->Enemy) { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < SECTOR(0.25f) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) { - DoDamage(enemy, 6); + DoDamage(creature->Enemy, 6); CreatureEffect(item, MPStickBite1, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 2; @@ -447,12 +441,12 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) extraTorsoRot.y = AI.angle; - if (enemy->IsLara()) + if (creature->Enemy->IsLara()) { if (creature->Flags != 1 && item->TestBits(JointBitType::Touch, MPStickKickAttackJoints) && item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 8) { - DoDamage(enemy, 150); + DoDamage(creature->Enemy, 150); CreatureEffect(item, MPStickBite2, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; @@ -460,14 +454,12 @@ namespace TEN::Entities::Creatures::TR3 } else { - if (!creature->Flags != 1 && enemy && + if (!creature->Flags != 1 && creature->Enemy && item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 8) { - if (abs(enemy->Pose.Position.x - item->Pose.Position.x) < SECTOR(0.25f) && - abs(enemy->Pose.Position.y - item->Pose.Position.y) <= SECTOR(0.25f) && - abs(enemy->Pose.Position.z - item->Pose.Position.z) < SECTOR(0.25f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.25f)) { - DoDamage(enemy, 9); + DoDamage(creature->Enemy, 9); CreatureEffect(item, MPStickBite2, DoBloodSplat); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); creature->Flags = 1; diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index 2e651aaed..125a730b9 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -263,10 +263,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!(creature->Flags & 1) && creature->Enemy != nullptr) { - auto direction = creature->Enemy->Pose.Position - item->Pose.Position; - if (abs(direction.x) < SECTOR(0.5f) && - abs(direction.y) < SECTOR(0.5f) && - abs(direction.z) < SECTOR(0.5f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) { if (creature->Enemy->HitPoints <= 0) creature->Flags |= 2; @@ -303,10 +300,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!(creature->Flags & 1) && creature->Enemy != nullptr) { - auto direction = creature->Enemy->Pose.Position - item->Pose.Position; - if (abs(direction.x) < SECTOR(0.5f) && - abs(direction.y) < SECTOR(0.5f) && - abs(direction.z) < SECTOR(0.5f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) { if (creature->Enemy->HitPoints <= 0) creature->Flags |= 2; @@ -342,10 +336,7 @@ namespace TEN::Entities::Creatures::TR3 { if (!(creature->Flags & 1) && creature->Enemy != nullptr) { - auto direction = creature->Enemy->Pose.Position - item->Pose.Position; - if (abs(direction.x) < SECTOR(0.5f) && - abs(direction.y) < SECTOR(0.5f) && - abs(direction.z) < SECTOR(0.5f)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) { if (creature->Enemy->HitPoints <= 0) creature->Flags |= 2; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index 7e70a51af..1ee1acf0a 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -313,10 +313,7 @@ namespace TEN::Entities::Creatures::TR3 { if (creature->Enemy != nullptr) { - auto direction = creature->Enemy->Pose.Position - item->Pose.Position; - if (abs(direction.x) < SECTOR(0.5f) && - abs(direction.y) < SECTOR(0.5f) && - abs(direction.z) < SECTOR(0.5f) && + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f) && creature->Flags >= TribesmanAxeHit[item->Animation.ActiveState][0] && creature->Flags <= TribesmanAxeHit[item->Animation.ActiveState][1]) { @@ -608,9 +605,7 @@ namespace TEN::Entities::Creatures::TR3 { if (creature->Enemy != nullptr && !(creature->Flags & 0xf000)) { - if (abs(creature->Enemy->Pose.Position.x - item->Pose.Position.x) < pow(SECTOR(0.5f), 2) && - abs(creature->Enemy->Pose.Position.y - item->Pose.Position.y) < pow(SECTOR(0.5f), 2) && - abs(creature->Enemy->Pose.Position.z - item->Pose.Position.z) < pow(SECTOR(0.5f), 2)) + if (Vector3Int::Distance(item->Pose.Position, creature->Enemy->Pose.Position) <= SECTOR(0.5f)) { DoDamage(creature->Enemy, 5); SoundEffect(SFX_TR4_LARA_THUD, &item->Pose); diff --git a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp index bb776e024..f4e8d5fcc 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_ahmet.cpp @@ -147,14 +147,14 @@ namespace TEN::Entities::TR4 else { SetAnimation(item, AHMET_ANIM_DEATH); - Lara.InteractedItem = itemNumber; // TODO: Check if it's really required! -- TokyoSU, 3/8/2022 + Lara.InteractedItem = itemNumber; // TODO: Check if it's really required! -- TokyoSU 3/8/2022 } TriggerAhmetDeathEffect(item); } else { - if (item->AIBits != 0) // Does this entity have AI object? NOTE: Previous one checked "& ALL_AIOBJ" -- TokyoSU, 3/8/2022 + if (item->AIBits != 0) // Does this entity have AI object? NOTE: Previous one checked "& ALL_AIOBJ" -- TokyoSU 3/8/2022 GetAITarget(creature); AI_INFO AI, laraAI; @@ -167,7 +167,7 @@ namespace TEN::Entities::TR4 } else { - int dx = LaraItem->Pose.Position.x - item->Pose.Position.x; // TODO: Make ahmet to not use LaraItem global -- TokyoSU, 3/8/2022 + int dx = LaraItem->Pose.Position.x - item->Pose.Position.x; // TODO: Make ahmet to not use LaraItem global -- TokyoSU 3/8/2022 int dz = LaraItem->Pose.Position.z - item->Pose.Position.z; laraAI.angle = short(phd_atan(dx, dz)) - item->Pose.Orientation.y; laraAI.distance = SQUARE(dx) + SQUARE(dz); @@ -206,7 +206,7 @@ namespace TEN::Entities::TR4 } else if (creature->Mood == MoodType::Bored || creature->Mood == MoodType::Escape) { - if (Lara.TargetEntity == item || !AI.ahead) // TODO: Make ahmet not use LaraInfo global. -- TokyoSU, 3/8/2022 + if (Lara.TargetEntity == item || !AI.ahead) // TODO: Make ahmet not use LaraInfo global. -- TokyoSU 3/8/2022 item->Animation.TargetState = AHMET_STATE_RUN_FORWARD; else item->Animation.TargetState = AHMET_STATE_IDLE; @@ -323,7 +323,8 @@ namespace TEN::Entities::TR4 if (!(creature->Flags & 1) && item->Animation.AnimNumber == (Objects[item->ObjectNumber].animIndex + AHMET_ANIM_JUMP_BITE_ATTACK_CONTINUE)) { - if (item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 11) && item->TestBits(JointBitType::Touch, AhmetSwipeAttackLeftJoints)) + if (item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 11) && + item->TestBits(JointBitType::Touch, AhmetSwipeAttackLeftJoints)) { DoDamage(creature->Enemy, AHMET_BITE_ATTACK_DAMAGE); CreatureEffect2(item, AhmetBiteJaw, 10, -1, DoBloodSplat); @@ -351,13 +352,17 @@ namespace TEN::Entities::TR4 } else { - if (!(creature->Flags & 1) && item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 14) && item->TestBits(JointBitType::Touch, AhmetSwipeAttackLeftJoints)) + if (!(creature->Flags & 1) && + item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 14) && + item->TestBits(JointBitType::Touch, AhmetSwipeAttackLeftJoints)) { DoDamage(creature->Enemy, AHMET_SWIPE_ATTACK_DAMAGE); CreatureEffect2(item, AhmetBiteLeft, 10, -1, DoBloodSplat); creature->Flags |= 1; } - else if (!(creature->Flags & 2) && item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 22) && item->TestBits(JointBitType::Touch, AhmetSwipeAttackRightJoints)) + else if (!(creature->Flags & 2) && + item->Animation.FrameNumber > (g_Level.Anims[item->Animation.AnimNumber].frameBase + 22) && + item->TestBits(JointBitType::Touch, AhmetSwipeAttackRightJoints)) { DoDamage(creature->Enemy, AHMET_SWIPE_ATTACK_DAMAGE); CreatureEffect2(item, AhmetBiteRight, 10, -1, DoBloodSplat); From 7dd6add17f1ddcd3f96f542fb3aaeec0aa16cb9c Mon Sep 17 00:00:00 2001 From: Sezz Date: Mon, 12 Sep 2022 15:36:38 +1000 Subject: [PATCH 095/106] Remove weird casts --- TombEngine/Game/animation.cpp | 4 +++- TombEngine/Game/collision/collide_item.cpp | 12 +++++------ TombEngine/Game/collision/collide_item.h | 4 ++-- TombEngine/Game/missile.cpp | 2 +- TombEngine/Objects/Effects/enemy_missile.cpp | 2 +- TombEngine/Objects/Effects/flame_emitters.cpp | 5 ++--- TombEngine/Objects/Effects/tr4_locusts.cpp | 2 +- .../Objects/TR2/Entity/tr2_knife_thrower.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_tony.cpp | 2 +- .../Objects/TR5/Entity/tr5_submarine.cpp | 2 +- TombEngine/Objects/TR5/Object/tr5_missile.cpp | 20 +++++++++---------- 11 files changed, 29 insertions(+), 28 deletions(-) diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp index 777ccead3..29d8132f4 100644 --- a/TombEngine/Game/animation.cpp +++ b/TombEngine/Game/animation.cpp @@ -475,7 +475,9 @@ BOUNDING_BOX* GetBoundsAccurate(ItemInfo* item) InterpolatedBounds.Y2 = framePtr[0]->boundingBox.Y2 + (framePtr[1]->boundingBox.Y2 - framePtr[0]->boundingBox.Y2) * frac / rate; InterpolatedBounds.Z1 = framePtr[0]->boundingBox.Z1 + (framePtr[1]->boundingBox.Z1 - framePtr[0]->boundingBox.Z1) * frac / rate; InterpolatedBounds.Z2 = framePtr[0]->boundingBox.Z2 + (framePtr[1]->boundingBox.Z2 - framePtr[0]->boundingBox.Z2) * frac / rate; - return &InterpolatedBounds; + { + return &InterpolatedBounds; + } } } diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index 77f4d1ae0..b1c753bd2 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -491,12 +491,12 @@ static bool ItemInRange(int x, int z, int radius) return ((SQUARE(x) + SQUARE(z)) <= SQUARE(radius)); } -bool ItemNearLara(PHD_3DPOS* origin, int radius) +bool ItemNearLara(Vector3Int* origin, int radius) { auto target = GameVector( - origin->Position.x - LaraItem->Pose.Position.x, - origin->Position.y - LaraItem->Pose.Position.y, - origin->Position.z - LaraItem->Pose.Position.z + origin->x - LaraItem->Pose.Position.x, + origin->y - LaraItem->Pose.Position.y, + origin->z - LaraItem->Pose.Position.z ); if (!ItemCollide(target.y, ITEM_RADIUS_YMAX)) @@ -515,9 +515,9 @@ bool ItemNearLara(PHD_3DPOS* origin, int radius) return false; } -bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* targetEntity, int radius) +bool ItemNearTarget(Vector3Int* origin, ItemInfo* targetEntity, int radius) { - auto pos = origin->Position - targetEntity->Pose.Position; + auto pos = *origin - targetEntity->Pose.Position; if (!ItemCollide(pos.y, ITEM_RADIUS_YMAX)) return false; diff --git a/TombEngine/Game/collision/collide_item.h b/TombEngine/Game/collision/collide_item.h index 01c8f3c2f..1c7545b37 100644 --- a/TombEngine/Game/collision/collide_item.h +++ b/TombEngine/Game/collision/collide_item.h @@ -36,8 +36,8 @@ bool TestLaraPosition(OBJECT_COLLISION_BOUNDS* bounds, ItemInfo* item, ItemInfo* bool AlignLaraPosition(Vector3Int* offset, ItemInfo* item, ItemInfo* laraItem); bool MoveLaraPosition(Vector3Int* pos, ItemInfo* item, ItemInfo* laraItem); -bool ItemNearLara(PHD_3DPOS* origin, int radius); -bool ItemNearTarget(PHD_3DPOS* origin, ItemInfo* targetEntity, int radius); +bool ItemNearLara(Vector3Int* origin, int radius); +bool ItemNearTarget(Vector3Int* origin, ItemInfo* targetEntity, int radius); bool Move3DPosTo3DPos(PHD_3DPOS* fromPose, PHD_3DPOS* toPose, int velocity, short angleAdd); diff --git a/TombEngine/Game/missile.cpp b/TombEngine/Game/missile.cpp index c12ae482e..85c0021ab 100644 --- a/TombEngine/Game/missile.cpp +++ b/TombEngine/Game/missile.cpp @@ -57,7 +57,7 @@ void ControlMissile(short fxNumber) fx->pos.Position.x += velocity * phd_sin(fx->pos.Orientation.y); auto probe = GetCollision(fx->pos.Position.x, fx->pos.Position.y, fx->pos.Position.z, fx->roomNumber); - auto hitLara = ItemNearLara(&fx->pos, 200); + auto hitLara = ItemNearLara(&fx->pos.Position, 200); // Check for hitting something. if (fx->pos.Position.y >= probe.Position.Floor || diff --git a/TombEngine/Objects/Effects/enemy_missile.cpp b/TombEngine/Objects/Effects/enemy_missile.cpp index fec8ecee0..77edcf0e1 100644 --- a/TombEngine/Objects/Effects/enemy_missile.cpp +++ b/TombEngine/Objects/Effects/enemy_missile.cpp @@ -259,7 +259,7 @@ namespace TEN::Entities::Effects return; } - if (ItemNearLara(&fx->pos, 200)) + if (ItemNearLara(&fx->pos.Position, 200)) { LaraItem->HitStatus = true; if (fx->flag1 != 6) diff --git a/TombEngine/Objects/Effects/flame_emitters.cpp b/TombEngine/Objects/Effects/flame_emitters.cpp index fb2e113a9..0d81a2fb8 100644 --- a/TombEngine/Objects/Effects/flame_emitters.cpp +++ b/TombEngine/Objects/Effects/flame_emitters.cpp @@ -154,7 +154,7 @@ namespace TEN::Entities::Effects SoundEffect(SFX_TR4_LOOP_FOR_SMALL_FIRES, &item->Pose); if (!Lara.Burn && - ItemNearLara(&item->Pose, 600) && + ItemNearLara(&item->Pose.Position, 600) && (pow(LaraItem->Pose.Position.x - item->Pose.Position.x, 2) + pow(LaraItem->Pose.Position.z - item->Pose.Position.z, 2) < pow(SECTOR(0.5f), 2)) && Lara.Control.WaterStatus != WaterStatus::FlyCheat) @@ -625,8 +625,7 @@ namespace TEN::Entities::Effects TriggerDynamicLight(x, item->Pose.Position.y, z, 12, (GetRandomControl() & 0x3F) + 192, ((GetRandomControl() >> 4) & 0x1F) + 96, 0); - auto pos = PHD_3DPOS(item->Pose.Position); - + auto pos = item->Pose.Position; if (ItemNearLara(&pos, 600)) { if ((!Lara.Burn) && Lara.Control.WaterStatus != WaterStatus::FlyCheat) diff --git a/TombEngine/Objects/Effects/tr4_locusts.cpp b/TombEngine/Objects/Effects/tr4_locusts.cpp index fe66325f8..9b1bf5f34 100644 --- a/TombEngine/Objects/Effects/tr4_locusts.cpp +++ b/TombEngine/Objects/Effects/tr4_locusts.cpp @@ -191,7 +191,7 @@ namespace TEN::Entities::TR4 locust->pos.Position.y += locust->randomRotation * phd_sin(-locust->pos.Orientation.x); locust->pos.Position.z += locust->randomRotation * phd_cos(locust->pos.Orientation.x) * phd_cos(locust->pos.Orientation.y); - if (ItemNearTarget(&locust->pos, LaraItem, CLICK(1) / 2)) + if (ItemNearTarget(&locust->pos.Position, LaraItem, CLICK(1) / 2)) { TriggerBlood(locust->pos.Position.x, locust->pos.Position.y, locust->pos.Position.z, 2 * GetRandomControl(), 2); DoDamage(LaraItem, LOCUST_LARA_DAMAGE); diff --git a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp index 24867691e..2e9957b89 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_knife_thrower.cpp @@ -101,7 +101,7 @@ namespace TEN::Entities::Creatures::TR2 fx->pos.Orientation.z += ANGLE(30.0f); - if (ItemNearLara(&fx->pos, 200)) + if (ItemNearLara(&fx->pos.Position, 200)) { DoDamage(LaraItem, KNIFE_PROJECTILE_DAMAGE); diff --git a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp index 55f663cd7..e79d620fd 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tony.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tony.cpp @@ -467,7 +467,7 @@ namespace TEN::Entities::Creatures::TR3 if (!Lara.Burn) { - if (ItemNearLara(&fx->pos, 200)) + if (ItemNearLara(&fx->pos.Position, 200)) { LaraItem->HitStatus = true; KillEffect(fxNumber); diff --git a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp index bfdde4086..5ee97fef8 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_submarine.cpp @@ -531,7 +531,7 @@ namespace TEN::Entities::Creatures::TR5 item->Pose.Position.y > probe.Position.Ceiling && TestEnvironment(ENV_FLAG_WATER, probe.RoomNumber)) { - if (ItemNearLara(&item->Pose, 200)) + if (ItemNearLara(&item->Pose.Position, 200)) { LaraItem->HitStatus = true; KillItem(itemNumber); diff --git a/TombEngine/Objects/TR5/Object/tr5_missile.cpp b/TombEngine/Objects/TR5/Object/tr5_missile.cpp index 959c168cd..bb75d362d 100644 --- a/TombEngine/Objects/TR5/Object/tr5_missile.cpp +++ b/TombEngine/Objects/TR5/Object/tr5_missile.cpp @@ -21,6 +21,7 @@ int DebrisFlags; void MissileControl(short itemNumber) { auto* fx = &EffectList[itemNumber]; + if (fx->flag1 == 2) { fx->pos.Orientation.z += 16 * fx->speed; @@ -118,9 +119,9 @@ void MissileControl(short itemNumber) { TriggerExplosionSparks(x, y, z, 3, -2, 2, fx->roomNumber); fx->pos.Position.y -= 64; - TriggerShockwave((PHD_3DPOS*)fx, 48, 256, 64, 64, 128, 0, 24, 0, 1); + TriggerShockwave(&fx->pos, 48, 256, 64, 64, 128, 0, 24, 0, 1); fx->pos.Position.y -= 128; - TriggerShockwave((PHD_3DPOS*)fx, 48, 256, 48, 64, 128, 0, 24, 0, 1); + TriggerShockwave(&fx->pos, 48, 256, 48, 64, 128, 0, 24, 0, 1); } else if (fx->flag1 == 2) { @@ -131,12 +132,12 @@ void MissileControl(short itemNumber) else { TriggerExplosionSparks(x, y, z, 3, -2, 0, fx->roomNumber); - TriggerShockwave((PHD_3DPOS*)fx, 48, 240, 48, 0, 96, 128, 24, 0, 2); + TriggerShockwave(&fx->pos, 48, 240, 48, 0, 96, 128, 24, 0, 2); } KillEffect(itemNumber); } - else if (ItemNearLara((PHD_3DPOS*)fx, 200)) + else if (ItemNearLara(&fx->pos.Position, 200)) { if (fx->flag1) { @@ -145,9 +146,9 @@ void MissileControl(short itemNumber) // ROMAN_GOD hit effect TriggerExplosionSparks(x, y, z, 3, -2, 2, fx->roomNumber); fx->pos.Position.y -= 64; - TriggerShockwave((PHD_3DPOS*)fx, 48, 256, 64, 0, 128, 64, 24, 0, 1); + TriggerShockwave(&fx->pos, 48, 256, 64, 0, 128, 64, 24, 0, 1); fx->pos.Position.y -= 128; - TriggerShockwave((PHD_3DPOS*)fx, 48, 256, 48, 0, 128, 64, 24, 0, 1); + TriggerShockwave(&fx->pos, 48, 256, 48, 0, 128, 64, 24, 0, 1); KillEffect(itemNumber); DoDamage(LaraItem, 200); } @@ -170,7 +171,7 @@ void MissileControl(short itemNumber) { // HYDRA hit effect TriggerExplosionSparks(x, y, z, 3, -2, 0, fx->roomNumber); - TriggerShockwave((PHD_3DPOS*)fx, 48, 240, 48, 0, 96, 128, 24, 0, 0); + TriggerShockwave(&fx->pos, 48, 240, 48, 0, 96, 128, 24, 0, 0); if (LaraItem->HitPoints >= 500) DoDamage(LaraItem, 300); else @@ -185,8 +186,7 @@ void MissileControl(short itemNumber) if (GlobalCounter & 1) { - Vector3Int pos = { x, y, z }; - + auto pos = Vector3Int(x, y, z); int xv = x - fx->pos.Position.x; int yv = y - fx->pos.Position.y; int zv = z - fx->pos.Position.z; @@ -196,7 +196,7 @@ void MissileControl(short itemNumber) else { TriggerHydraMissileSparks(&pos, 4 * xv, 4 * yv, 4 * zv); - TriggerHydraMissileSparks((Vector3Int*)&fx, 4 * xv, 4 * yv, 4 * zv); + TriggerHydraMissileSparks(&fx->pos.Position, 4 * xv, 4 * yv, 4 * zv); } } } From b32b4e8a835091bd3505bd77b38cb33ea9bd4fce Mon Sep 17 00:00:00 2001 From: Sezz Date: Mon, 12 Sep 2022 17:01:48 +1000 Subject: [PATCH 096/106] Use "for each" loop --- TombEngine/Game/collision/collide_item.cpp | 12 +++++------- TombEngine/Specific/trmath.cpp | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/TombEngine/Game/collision/collide_item.cpp b/TombEngine/Game/collision/collide_item.cpp index b1c753bd2..85ff72ef3 100644 --- a/TombEngine/Game/collision/collide_item.cpp +++ b/TombEngine/Game/collision/collide_item.cpp @@ -331,7 +331,7 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) continue; } - if (phd_Distance(&item->Pose, &item2->Pose) < COLLISION_CHECK_DISTANCE) + if (Vector3Int::Distance(item->Pose.Position, item2->Pose.Position) < COLLISION_CHECK_DISTANCE) { auto box = TO_DX_BBOX(item2->Pose, GetBoundsAccurate(item2)); float distance; @@ -346,16 +346,14 @@ void TestForObjectOnLedge(ItemInfo* item, CollisionInfo* coll) itemNumber = item2->NextItem; } - for (int j = 0; j < g_Level.Rooms[i].mesh.size(); j++) + for (auto& mesh : g_Level.Rooms[i].mesh) { - auto* mesh = &g_Level.Rooms[i].mesh[j]; - - if (!(mesh->flags & StaticMeshFlags::SM_VISIBLE)) + if (!(mesh.flags & StaticMeshFlags::SM_VISIBLE)) continue; - if (phd_Distance(&item->Pose, &mesh->pos) < COLLISION_CHECK_DISTANCE) + if (phd_Distance(&item->Pose, &mesh.pos) < COLLISION_CHECK_DISTANCE) { - auto box = TO_DX_BBOX(mesh->pos, GetBoundsAccurate(mesh, false)); + auto box = TO_DX_BBOX(mesh.pos, GetBoundsAccurate(&mesh, false)); float distance; if (box.Intersects(origin, direction, distance) && distance < coll->Setup.Radius * 2) diff --git a/TombEngine/Specific/trmath.cpp b/TombEngine/Specific/trmath.cpp index 4733bb5af..602d7fd10 100644 --- a/TombEngine/Specific/trmath.cpp +++ b/TombEngine/Specific/trmath.cpp @@ -188,7 +188,7 @@ BoundingOrientedBox TO_DX_BBOX(PHD_3DPOS pos, BOUNDING_BOX* box) auto rotation = Quaternion::CreateFromYawPitchRoll(TO_RAD(pos.Orientation.y), TO_RAD(pos.Orientation.x), TO_RAD(pos.Orientation.z)); BoundingOrientedBox result; - BoundingOrientedBox(boxCentre, boxExtent, Vector4::UnitY).Transform(result, 1, rotation, Vector3(pos.Position.x, pos.Position.y, pos.Position.z)); + BoundingOrientedBox(boxCentre, boxExtent, Vector4::UnitY).Transform(result, 1, rotation, pos.Position.ToVector3()); return result; } From 613e70a3afd59e829687d35272018526efbce8be Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:48:30 +0300 Subject: [PATCH 097/106] Resolve ambiguity with VectorIndex and item init --- TombEngine/Game/items.cpp | 18 ++++++++++-------- TombEngine/Game/items.h | 4 +++- TombEngine/Game/savegame.cpp | 3 --- TombEngine/Specific/level.cpp | 3 --- 4 files changed, 13 insertions(+), 15 deletions(-) diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp index e8122da57..f4f2b4f8a 100644 --- a/TombEngine/Game/items.cpp +++ b/TombEngine/Game/items.cpp @@ -477,8 +477,6 @@ void InitialiseItem(short itemNumber) { auto* item = &g_Level.Items[itemNumber]; - item->VectorIndex = itemNumber; - item->Animation.AnimNumber = Objects[item->ObjectNumber].animIndex; item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase; @@ -572,16 +570,18 @@ short CreateItem() void InitialiseItemArray(int totalItem) { - auto* item = &g_Level.Items[g_Level.NumItems]; + g_Level.Items.clear(); + g_Level.Items.resize(totalItem); - NextItemActive = NO_ITEM; - NextItemFree = g_Level.NumItems; + for (int i = 0; i < totalItem; i++) + g_Level.Items[i].Index = i; + + auto* item = &g_Level.Items[g_Level.NumItems]; if (g_Level.NumItems + 1 < totalItem) { - for(int i = g_Level.NumItems + 1; i < totalItem; i++, item++) + for (int i = g_Level.NumItems + 1; i < totalItem; i++, item++) { - item->VectorIndex = i-1; item->NextItem = i; item->Active = false; item->Data = nullptr; @@ -589,6 +589,8 @@ void InitialiseItemArray(int totalItem) } item->NextItem = NO_ITEM; + NextItemActive = NO_ITEM; + NextItemFree = g_Level.NumItems; } short SpawnItem(ItemInfo* item, GAME_OBJECT_ID objectNumber) @@ -645,7 +647,7 @@ void UpdateItemRoom(ItemInfo* item, int height, int xOffset, int zOffset) item->Floor = GetFloorHeight(item->Location, x, z).value_or(NO_HEIGHT); if (item->RoomNumber != item->Location.roomNumber) - ItemNewRoom(item->VectorIndex, item->Location.roomNumber); + ItemNewRoom(item->Index, item->Location.roomNumber); } std::vector FindAllItems(short objectNumber) diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h index 8bc285f3c..78307a36e 100644 --- a/TombEngine/Game/items.h +++ b/TombEngine/Game/items.h @@ -69,10 +69,12 @@ struct EntityAnimationData //todo we need to find good "default states" for a lot of these - squidshire 25/05/2022 struct ItemInfo { - short VectorIndex = -1; GAME_OBJECT_ID ObjectNumber; + int Status; // ItemStatus enum. bool Active; + + short Index; short NextItem; short NextActive; diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp index c3b328f0b..f4840caaa 100644 --- a/TombEngine/Game/savegame.cpp +++ b/TombEngine/Game/savegame.cpp @@ -1305,9 +1305,6 @@ bool SaveGame::Load(int slot) ZeroMemory(&Lara, sizeof(LaraInfo)); - // Items - InitialiseItemArray(NUM_ITEMS); - NextItemFree = s->next_item_free(); NextItemActive = s->next_item_active(); diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp index fe2b8afd9..211ec8e68 100644 --- a/TombEngine/Specific/level.cpp +++ b/TombEngine/Specific/level.cpp @@ -163,8 +163,6 @@ void LoadItems() if (g_Level.NumItems == 0) return; - g_Level.Items.resize(NUM_ITEMS); - InitialiseItemArray(NUM_ITEMS); if (g_Level.NumItems > 0) @@ -173,7 +171,6 @@ void LoadItems() { ItemInfo* item = &g_Level.Items[i]; - item->VectorIndex = i; item->Data = ITEM_DATA{}; item->ObjectNumber = from_underlying(ReadInt16()); item->RoomNumber = ReadInt16(); From 79833da290651aed717bcc0cbe0afcb515bd3425 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 11:53:54 +0300 Subject: [PATCH 098/106] Update Changes.txt --- Documentation/Changes.txt | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index e58367c72..b937c0fbc 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -24,13 +24,10 @@ Version 1.0.2 * Fix Lara's subway train death so that she no longer slides slowly after the animation has finished. Lua API changes: + * Timer.lua, EventSequence.lua and Util.lua have been moved to a subfolder, Engine. * LevelFuncs can now contain tables as well as functions. These tables can contain functions and other tables, and so forth. -* Moveable functions SetOnHit, SetOnKilled, SetOnCollidedWithObject and SetOnCollidedWithRoom no longer take strings, and instead take function objects themselves. The function still has to be in the LevelFuncs hierarchy: -Before: -baddy:SetOnHit("HealLara") -After: -baddy:SetOnHit(LevelFuncs.HealLara) +* Moveable functions SetOnHit, SetOnKilled, SetOnCollidedWithObject and SetOnCollidedWithRoom no longer take strings, and instead take function objects themselves. * EventSequence and Timer no longer require you to call Timer.UpdateAll in OnControlPhase. * TEN.Logic.AddCallback and TEN.Logic.RemoveCallback have been added. * GiveItem, TakeItem, and SetItemCount have been reworked (e.g. SetItemCount with a value of -1 can give infinite ammo/consumables). From 2df3f5f4d5fb6baa813b4deeaf6aee9f27ee3787 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 15:10:26 +0300 Subject: [PATCH 099/106] Load node catalogs in reverse order to load files starting with _ first --- TombEngine/Game/control/volume.cpp | 31 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp index 7a950b140..2a0cf73ca 100644 --- a/TombEngine/Game/control/volume.cpp +++ b/TombEngine/Game/control/volume.cpp @@ -163,18 +163,22 @@ namespace TEN::Control::Volumes if (!std::filesystem::exists(nodeScriptPath)) return; + + std::vector nodeCatalogs; + for (auto& path : std::filesystem::recursive_directory_iterator(nodeScriptPath)) + if (path.path().extension() == ".lua") + nodeCatalogs.push_back(path.path().filename().string()); + + if (nodeCatalogs.size() == 0) + return; TENLog("Loading node scripts...", LogLevel::Info); - bool anyScriptsFound = false; - for (auto& path : std::filesystem::recursive_directory_iterator(nodeScriptPath)) - { - if (path.path().extension() == ".lua") - { - g_GameScript->ExecuteScriptFile(path.path().string()); - anyScriptsFound = true; - } - } + std::sort(nodeCatalogs.rbegin(), nodeCatalogs.rend()); + for (auto& file : nodeCatalogs) + g_GameScript->ExecuteScriptFile(nodeScriptPath + file); + + TENLog(std::to_string(nodeCatalogs.size()) + " node catalogs were found and loaded.", LogLevel::Info); int nodeCount = 0; for (auto& set : g_Level.EventSets) @@ -198,12 +202,7 @@ namespace TEN::Control::Volumes } } - if (nodeCount == 0) - return; - - if (!anyScriptsFound) - TENLog("Node catalogs are missing, but node scripts are present in level. Make sure node catalogs are in place.", LogLevel::Warning); - else - TENLog(std::to_string(nodeCount) + " node scripts found and loaded.", LogLevel::Info); + if (nodeCount != 0) + TENLog(std::to_string(nodeCount) + " node scripts were found and loaded.", LogLevel::Info); } } From 38f62f057bd65f4b6e1859ad32e1caf088c70b58 Mon Sep 17 00:00:00 2001 From: Sezz Date: Mon, 12 Sep 2022 22:20:36 +1000 Subject: [PATCH 100/106] Represent most probabilities as fractions --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 8 ++++---- TombEngine/Objects/TR1/Entity/tr1_bear.cpp | 6 +++--- TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp | 2 +- TombEngine/Objects/TR1/Entity/tr1_centaur.cpp | 2 +- .../Objects/TR1/Entity/tr1_winged_mutant.cpp | 4 ++-- TombEngine/Objects/TR1/Entity/tr1_wolf.cpp | 2 +- .../Objects/TR2/Entity/tr2_silencer.cpp | 2 +- .../Objects/TR2/Entity/tr2_spear_guardian.cpp | 12 +++++------ TombEngine/Objects/TR2/Entity/tr2_yeti.cpp | 20 +++++++++---------- .../Objects/TR3/Entity/tr3_flamethrower.cpp | 10 +++++----- TombEngine/Objects/TR3/Entity/tr3_monkey.cpp | 2 +- TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp | 4 ++-- .../Objects/TR3/Entity/tr3_mp_stick.cpp | 4 ++-- TombEngine/Objects/TR3/Entity/tr3_raptor.cpp | 6 +++--- TombEngine/Objects/TR3/Entity/tr3_tiger.cpp | 9 ++------- .../Objects/TR3/Entity/tr3_tribesman.cpp | 16 +++++++-------- TombEngine/Objects/TR4/Entity/tr4_baboon.cpp | 4 ++-- TombEngine/Objects/TR4/Entity/tr4_baddy.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_bat.cpp | 2 +- .../Objects/TR4/Entity/tr4_big_beetle.cpp | 2 +- .../Objects/TR4/Entity/tr4_crocodile.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_dog.cpp | 10 +++++----- TombEngine/Objects/TR4/Entity/tr4_mummy.cpp | 2 +- TombEngine/Objects/TR4/Entity/tr4_sas.cpp | 4 ++-- .../Objects/TR4/Entity/tr4_skeleton.cpp | 6 +++--- TombEngine/Objects/TR4/Entity/tr4_troops.cpp | 2 +- .../Objects/TR4/Entity/tr4_wild_boar.cpp | 2 +- .../Objects/TR5/Entity/tr5_doberman.cpp | 4 ++-- .../Objects/TR5/Entity/tr5_gladiator.cpp | 8 ++++---- TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 4 ++-- TombEngine/Objects/TR5/Entity/tr5_larson.cpp | 4 ++-- TombEngine/Objects/TR5/Entity/tr5_lion.cpp | 4 ++-- 32 files changed, 83 insertions(+), 88 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 6b2f35625..37a978973 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -22,10 +22,10 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto APE_ATTACK_RANGE = SQUARE(SECTOR(0.42f)); constexpr auto APE_PANIC_RANGE = SQUARE(SECTOR(2)); - constexpr auto APE_IDLE_JUMP_CHANCE = 1.0f / 6.0f; - constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 1.0f / 3.0f; - constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 1.0f / 2.0f; - constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 1.0f / 1.5f; + constexpr auto APE_IDLE_JUMP_CHANCE = 1.0f / 6; + constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 1.0f / 3; + constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 1.0f / 2; + constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 1.0f / 1; constexpr auto APE_RUN_JUMP_CHANCE = APE_IDLE_JUMP_CHANCE / 32; constexpr auto APE_RUN_POUND_CHEST_CHANCE = APE_IDLE_POUND_CHEST_CHANCE / 32; constexpr auto APE_RUN_POUND_GROUND_CHANCE = APE_IDLE_POUND_GROUND_CHANCE / 32; diff --git a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp index 709fc0a7f..5f673a50f 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_bear.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_bear.cpp @@ -27,9 +27,9 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto BEAR_REAR_SWIPE_ATTACK_RANGE = SECTOR(0.6f); constexpr auto BEAR_EAT_RANGE = CLICK(3); - constexpr auto BEAR_ROAR_CHANCE = 0.0025f; - constexpr auto BEAR_REAR_CHANCE = 0.025f; - constexpr auto BEAR_DROP_CHANCE = 0.045f; + constexpr auto BEAR_ROAR_CHANCE = 1.0f / 400; + constexpr auto BEAR_REAR_CHANCE = 1.0f / 40; + constexpr auto BEAR_DROP_CHANCE = 1.0f / 22; #define BEAR_WALK_TURN_RATE_MAX ANGLE(2.0f) #define BEAR_RUN_TURN_RATE_MAX ANGLE(5.0f) diff --git a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp index 412fdadba..54c449a61 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_big_rat.cpp @@ -27,7 +27,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto BIG_RAT_POUNCE_ATTACK_RANGE = SQUARE(SECTOR(0.5f)); constexpr auto BIG_RAT_WATER_BITE_ATTACK_RANGE = SQUARE(SECTOR(0.3f)); - constexpr auto BIG_RAT_REAR_POSE_CHANCE = 1.0f / 128.0f; + constexpr auto BIG_RAT_REAR_POSE_CHANCE = 1.0f / 128; constexpr auto BIG_RAT_SWIM_UP_DOWN_SPEED = 32; constexpr auto BIG_RAT_WATER_SURFACE_OFFSET = 10; diff --git a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp index 5bf82d856..765df9f7a 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_centaur.cpp @@ -25,7 +25,7 @@ namespace TEN::Entities::Creatures::TR1 { constexpr auto CENTAUR_REAR_DAMAGE = 200; constexpr auto CENTAUR_REAR_RANGE = SECTOR(1.5f); - constexpr auto CENTAUR_REAR_CHANCE = 0.003f; + constexpr auto CENTAUR_REAR_CHANCE = 1.0f / 340; constexpr auto CENTAUR_BOMB_VELOCITY = 20; #define CENTAUR_TURN_RATE_MAX ANGLE(4.0f) diff --git a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp index 65954e623..7cfa58e28 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_winged_mutant.cpp @@ -31,8 +31,8 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto WINGED_MUTANT_IDLE_JUMP_ATTACK_RANGE = SQUARE(SECTOR(2.5f)); constexpr auto WINGED_MUTANT_ATTACK_RANGE = SQUARE(SECTOR(3.75f)); - constexpr auto WINGED_MUTANT_POSE_CHANCE = 0.0025f; - constexpr auto WINGED_MUTANT_UNPOSE_CHANCE = 0.006f; + constexpr auto WINGED_MUTANT_POSE_CHANCE = 1.0f / 400; + constexpr auto WINGED_MUTANT_UNPOSE_CHANCE = 1.0f / 164; constexpr auto WINGED_MUTANT_FLY_VELOCITY = CLICK(1) / 8; constexpr auto WINGED_MUTANT_SHARD_VELOCITY = 250; diff --git a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp index 1e4f7a3c2..554a59c87 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_wolf.cpp @@ -25,7 +25,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto WOLF_WAKE_CHANCE = 1.0f / 1000; constexpr auto WOLF_SLEEP_CHANCE = 1.0f / 1000; - constexpr auto WOLF_HOWL_CHANCE = 0.012f; + constexpr auto WOLF_HOWL_CHANCE = 1.0f / 85; constexpr auto WOLF_SLEEP_FRAME = 96; diff --git a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp index 25e72c891..8e6a1ca5f 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_silencer.cpp @@ -236,7 +236,7 @@ namespace TEN::Entities::Creatures::TR2 } else { - if (creature->Mood == MoodType::Attack || TestProbability(1.0f / 128.0f)) + if (creature->Mood == MoodType::Attack || TestProbability(1.0f / 128)) item->Animation.TargetState = SILENCER_STATE_IDLE_FRAME; if (!AI.ahead) diff --git a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp index a425f87ac..053305727 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_spear_guardian.cpp @@ -128,9 +128,9 @@ namespace TEN::Entities::Creatures::TR2 if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.015f)) + if (TestProbability(1.0f / 64)) item->Animation.TargetState = 2; - else if (TestProbability(0.03f)) + else if (TestProbability(1.0f / 30)) item->Animation.TargetState = 3; } else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) @@ -150,9 +150,9 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 3; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.015f)) + if (TestProbability(1.0f / 64)) item->Animation.TargetState = 1; - else if (TestProbability(0.03f)) + else if (TestProbability(1.0f / 30)) item->Animation.TargetState = 3; } else if (AI.ahead && AI.distance < pow(SECTOR(1), 2)) @@ -172,9 +172,9 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 4; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.015f)) + if (TestProbability(1.0f / 64)) item->Animation.TargetState = 1; - else if (TestProbability(0.03f)) + else if (TestProbability(1.0f / 30)) item->Animation.TargetState = 2; } else if (AI.ahead && AI.distance < pow(SECTOR(2), 2)) diff --git a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp index 654774122..425414747 100644 --- a/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp +++ b/TombEngine/Objects/TR2/Entity/tr2_yeti.cpp @@ -91,9 +91,9 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = item->Animation.RequiredState; else if (info->Mood == MoodType::Bored) { - if (TestProbability(1.0f / 128.0f) || !isLaraAlive) + if (TestProbability(1.0f / 128) || !isLaraAlive) item->Animation.TargetState = 7; - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) item->Animation.TargetState = 9; else if (TestProbability(0.025f)) item->Animation.TargetState = 3; @@ -119,9 +119,9 @@ namespace TEN::Entities::Creatures::TR2 { if (isLaraAlive) { - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = 2; - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) item->Animation.TargetState = 9; else if (TestProbability(0.025f)) { @@ -130,7 +130,7 @@ namespace TEN::Entities::Creatures::TR2 } } } - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) item->Animation.TargetState = 2; break; @@ -143,9 +143,9 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 2; else if (info->Mood == MoodType::Bored) { - if (TestProbability(1.0f / 128.0f) || !isLaraAlive) + if (TestProbability(1.0f / 128) || !isLaraAlive) item->Animation.TargetState = 7; - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) item->Animation.TargetState = 2; else if (TestProbability(0.025f)) { @@ -153,7 +153,7 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.RequiredState = 3; } } - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) item->Animation.TargetState = 2; break; @@ -168,12 +168,12 @@ namespace TEN::Entities::Creatures::TR2 item->Animation.TargetState = 1; else if (info->Mood == MoodType::Bored) { - if (TestProbability(1.0f / 128.0f) || !isLaraAlive) + if (TestProbability(1.0f / 128) || !isLaraAlive) { item->Animation.TargetState = 2; item->Animation.RequiredState = 7; } - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) { item->Animation.TargetState = 2; item->Animation.RequiredState = 9; diff --git a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp index 0def0adba..02039738b 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_flamethrower.cpp @@ -149,7 +149,7 @@ namespace TEN::Entities::Creatures::TR3 { extraHeadRot.y = AIGuard(creature); - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = 4; break; @@ -165,9 +165,9 @@ namespace TEN::Entities::Creatures::TR3 else item->Animation.TargetState = 2; } - else if (creature->Mood == MoodType::Bored && AI.ahead && TestProbability(1.0f / 128.0f)) + else if (creature->Mood == MoodType::Bored && AI.ahead && TestProbability(1.0f / 128)) item->Animation.TargetState = 4; - else if (creature->Mood == MoodType::Attack || TestProbability(1.0f / 128.0f)) + else if (creature->Mood == MoodType::Attack || TestProbability(1.0f / 128)) item->Animation.TargetState = 2; break; @@ -179,7 +179,7 @@ namespace TEN::Entities::Creatures::TR3 { extraHeadRot.y = AIGuard(creature); - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = 1; break; @@ -188,7 +188,7 @@ namespace TEN::Entities::Creatures::TR3 AI.distance < pow(SECTOR(4), 2) && (realEnemy != LaraItem || creature->HurtByLara) || creature->Mood != MoodType::Bored || - TestProbability(1.0f / 128.0f))) + TestProbability(1.0f / 128))) { item->Animation.TargetState = 1; } diff --git a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp index 889c1512b..e17b60300 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_monkey.cpp @@ -421,7 +421,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MONKEY_STATE_RUN_FORWARD; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = MONKEY_STATE_SIT; } else if (AI.bite && AI.distance < pow(682, 2)) diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp index 959e9ed0f..edce48023 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_gun.cpp @@ -434,7 +434,7 @@ namespace TEN::Entities::Creatures::TR3 if (Targetable(item, &AI)) item->Animation.TargetState = MPGUN_STATE_CROUCH_AIM; - else if (item->HitStatus || !cover || (AI.ahead && TestProbability(0.03f))) + else if (item->HitStatus || !cover || (AI.ahead && TestProbability(1.0f / 30))) item->Animation.TargetState = MPGUN_STATE_STAND; else item->Animation.TargetState = MPGUN_STATE_CROUCH_WALK; @@ -472,7 +472,7 @@ namespace TEN::Entities::Creatures::TR3 if (AI.ahead) head = AI.angle; - if (Targetable(item, &AI) || item->HitStatus || !cover || (AI.ahead && TestProbability(0.03f))) + if (Targetable(item, &AI) || item->HitStatus || !cover || (AI.ahead && TestProbability(1.0f / 30))) item->Animation.TargetState = MPGUN_STATE_CROUCHED; break; diff --git a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp index e1da4525a..56c162637 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_mp_stick.cpp @@ -179,7 +179,7 @@ namespace TEN::Entities::Creatures::TR3 if (item->AIBits & GUARD) { head = AIGuard(creature); - if (TestProbability(1.0f / 256.0f)) + if (TestProbability(1.0f / 256)) { if (item->Animation.ActiveState == MPSTICK_STATE_STOP) item->Animation.TargetState = MPSTICK_STATE_WAIT; @@ -234,7 +234,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = MPSTICK_STATE_RUN; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) { item->Animation.RequiredState = MPSTICK_STATE_WAIT; item->Animation.TargetState = MPSTICK_STATE_STOP; diff --git a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp index 125a730b9..4233a7a10 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_raptor.cpp @@ -24,8 +24,8 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto RAPTOR_JUMP_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); constexpr auto RAPTOR_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); - constexpr auto RAPTOR_ROAR_CHANCE = 0.004f; - constexpr auto RAPTOR_SWITCH_TARGET_CHANCE = 0.008f; + constexpr auto RAPTOR_ROAR_CHANCE = 1.0f / 256; + constexpr auto RAPTOR_SWITCH_TARGET_CHANCE = 1.0f / 128; #define RAPTOR_WALK_TURN_RATE_MAX ANGLE(2.0f) #define RAPTOR_RUN_TURN_RATE_MAX ANGLE(2.0f) @@ -124,7 +124,7 @@ namespace TEN::Entities::Creatures::TR3 if (nearestItem != nullptr && (nearestItem->ObjectNumber != ID_RAPTOR || - (TestProbability(0.03f) && minDistance < SQUARE(SECTOR(2))))) + (TestProbability(1.0f / 30) && minDistance < SQUARE(SECTOR(2))))) { creature->Enemy = nearestItem; } diff --git a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp index d80433f11..936d50807 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tiger.cpp @@ -24,7 +24,7 @@ namespace TEN::Entities::Creatures::TR3 constexpr auto TIGER_RUN_ATTACK_RANGE = SQUARE(SECTOR(1.5f)); constexpr auto TIGER_WALK_CHANCE = 0.035f; - constexpr auto TIGER_ROAR_CHANCE = 0.003f; + constexpr auto TIGER_ROAR_CHANCE = 1.0f / 340; const auto TigerBite = BiteInfo(Vector3(19.0f, -13.0f, 3.0f), 26); const vector TigerAttackJoints = { 14, 15, 16, 18, 19, 20, 21, 22, 23, 24, 25, 26 }; @@ -63,11 +63,6 @@ namespace TEN::Entities::Creatures::TR3 TIGER_ANIM_POUNCE_ATTACK_END = 12 }; - enum TigerFlags - { - TIGER_FLAG_ATTACKING = (1 << 0) - }; - void TigerControl(short itemNumber) { if (!CreatureActive(itemNumber)) @@ -189,7 +184,7 @@ namespace TEN::Entities::Creatures::TR3 { DoDamage(creature->Enemy, TIGER_ATTACK_DAMAGE); CreatureEffect(item, TigerBite, DoBloodSplat); - creature->Flags = TIGER_FLAG_ATTACKING; + creature->Flags = 1; // 1 = is attacking. } break; diff --git a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp index 1ee1acf0a..83ce466b8 100644 --- a/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp +++ b/TombEngine/Objects/TR3/Entity/tr3_tribesman.cpp @@ -152,7 +152,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn = 0; - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } else if (creature->Mood == MoodType::Escape) @@ -191,7 +191,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn = 0; - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; } else if (creature->Mood == MoodType::Escape) @@ -224,7 +224,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn /= 4; - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) { if (TestProbability(0.25f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; @@ -255,7 +255,7 @@ namespace TEN::Entities::Creatures::TR3 { creature->MaxTurn /= 4; - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) { if (TestProbability(0.5f)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; @@ -447,7 +447,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.x = 0; extraTorsoRot.y = 0; - if (TestProbability(1.0f / 256.0f)) + if (TestProbability(1.0f / 256)) item->Animation.TargetState = TRIBESMAN_STATE_IDLE; break; @@ -467,7 +467,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = TRIBESMAN_STATE_DART_ATTACK; else if (creature->Mood == MoodType::Bored) { - if (TestProbability(0.015f)) + if (TestProbability(1.0f / 64)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; else break; @@ -488,7 +488,7 @@ namespace TEN::Entities::Creatures::TR3 extraTorsoRot.x = 0; extraTorsoRot.y = 0; - if (TestProbability(1.0f / 256.0f)) + if (TestProbability(1.0f / 256)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; break; @@ -506,7 +506,7 @@ namespace TEN::Entities::Creatures::TR3 item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; else if (Targetable(item, &AI) && AI.distance < pow(MAX_VISIBILITY_DISTANCE, 2)) item->Animation.TargetState = TRIBESMAN_STATE_CROUCH_IDLE; - else if (creature->Mood == MoodType::Bored && TestProbability(0.015f)) + else if (creature->Mood == MoodType::Bored && TestProbability(1.0f / 64)) item->Animation.TargetState = TRIBESMAN_STATE_WALK_FORWARD; else item->Animation.TargetState = TRIBESMAN_STATE_RUN_FORWARD; diff --git a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp index 6058e1011..575fc5f5f 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baboon.cpp @@ -436,7 +436,7 @@ namespace TEN::Entities::TR4 { if (item->AIBits & FOLLOW) item->Animation.TargetState = BABOON_STATE_WALK_FORWARD; - else if (TestProbability(1.0f / 128.0f)) + else if (TestProbability(1.0f / 128)) item->Animation.TargetState = BABOON_STATE_SIT_IDLE; } else if (creature->Mood == MoodType::Escape) @@ -446,7 +446,7 @@ namespace TEN::Entities::TR4 if (AI.bite && AI.distance < BABOON_ATTACK_READY_RANGE) item->Animation.TargetState = BABOON_STATE_IDLE; } - else if (TestProbability(1.0f / 128.0f)) + else if (TestProbability(1.0f / 128)) item->Animation.TargetState = BABOON_STATE_SIT_IDLE; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp index 609b9e5bd..ec5f9af76 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp @@ -1215,7 +1215,7 @@ namespace TEN::Entities::TR4 case BADDY_STATE_BLIND: if (!FlashGrenadeAftershockTimer) { - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) item->Animation.TargetState = BADDY_STATE_IDLE; } diff --git a/TombEngine/Objects/TR4/Entity/tr4_bat.cpp b/TombEngine/Objects/TR4/Entity/tr4_bat.cpp index 916f63312..b5295a7a1 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_bat.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_bat.cpp @@ -102,7 +102,7 @@ namespace TEN::Entities::TR4 break; case BAT_STATE_FLY: - if (AI.distance < BAT_ATTACK_RANGE || TestProbability(0.015f)) + if (AI.distance < BAT_ATTACK_RANGE || TestProbability(1.0f / 64)) creature->Flags = 0; if (!creature->Flags) diff --git a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp index 5cbb23fb7..011bc2aa3 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_big_beetle.cpp @@ -122,7 +122,7 @@ namespace TEN::Entities::TR4 angle = CreatureTurn(item, creature->MaxTurn); if (item->HitStatus || AI.distance > BIG_BEETLE_AWARE_RANGE || - TestProbability(1.0f / 128.0f)) + TestProbability(1.0f / 128)) { creature->Flags = 0; } diff --git a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp index 563f5a18d..6d646e16e 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_crocodile.cpp @@ -178,7 +178,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = CROC_STATE_IDLE; item->ItemFlags[0] += item->ItemFlags[1]; - if (TestProbability(0.03f)) + if (TestProbability(1.0f / 30)) { if (TestProbability(0.5f)) item->ItemFlags[1] = 0; diff --git a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp index f97a3d9e8..171ad0847 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_dog.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_dog.cpp @@ -169,7 +169,7 @@ namespace TEN::Entities::TR4 creature->Flags++; creature->MaxTurn = 0; - if (creature->Flags > 300 && TestProbability(1.0f / 256.0f)) + if (creature->Flags > 300 && TestProbability(1.0f / 256)) item->Animation.TargetState = DOG_STATE_IDLE; } @@ -202,7 +202,7 @@ namespace TEN::Entities::TR4 else { if (item->Animation.ActiveState == DOG_STATE_STALK_IDLE && - TestProbability(1.0f / 256.0f)) + TestProbability(1.0f / 256)) { item->Animation.TargetState = DOG_STATE_IDLE; break; @@ -243,7 +243,7 @@ namespace TEN::Entities::TR4 creature->MaxTurn = ANGLE(1.0f); creature->Flags = 0; - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) { if (item->AIBits & MODIFY) { @@ -258,7 +258,7 @@ namespace TEN::Entities::TR4 if (TestProbability(0.875f)) { - if (TestProbability(0.03f)) + if (TestProbability(1.0f / 30)) item->Animation.TargetState = DOG_STATE_HOWL; break; @@ -279,7 +279,7 @@ namespace TEN::Entities::TR4 if (item->AIBits & PATROL1) item->Animation.TargetState = DOG_STATE_WALK_FORWARD; - else if (creature->Mood == MoodType::Bored && TestProbability(1.0f / 128.0f)) + else if (creature->Mood == MoodType::Bored && TestProbability(1.0f / 128)) item->Animation.TargetState = DOG_STATE_IDLE; else item->Animation.TargetState = DOG_STATE_STALK; diff --git a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp index 33b551ce3..57f753546 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_mummy.cpp @@ -255,7 +255,7 @@ namespace TEN::Entities::TR4 joint1 = 0; joint2 = 0; - if (AI.distance < MUMMY_ACTIVATE_RANGE || TestProbability(1.0f / 128.0f)) + if (AI.distance < MUMMY_ACTIVATE_RANGE || TestProbability(1.0f / 128)) { item->Animation.TargetState = MUMMY_STATE_COLLAPSED_TO_IDLE; item->HitPoints = Objects[item->ObjectNumber].HitPoints; diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp index 583cc3beb..0c483217b 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp @@ -629,7 +629,7 @@ namespace TEN::Entities::TR4 if (item->Animation.ActiveState == 1) { - if (TestProbability(1.0f / 128.0f)) + if (TestProbability(1.0f / 128)) { item->Animation.TargetState = 2; AnimateItem(item); @@ -638,7 +638,7 @@ namespace TEN::Entities::TR4 item->Animation.TargetState = 3; } else if (item->Animation.ActiveState == 4 && - TestProbability(1.0f / 128.0f)) + TestProbability(1.0f / 128)) { item->Animation.TargetState = 5; AnimateItem(item); diff --git a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp index 381a85ab5..87eb62562 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_skeleton.cpp @@ -358,7 +358,7 @@ namespace TEN::Entities::TR4 creature->Flags = 0; if (item->AIBits & GUARD || - TestProbability(0.03f) && + TestProbability(1.0f / 30) && (AI.distance > pow(SECTOR(1), 2) || creature->Mood != MoodType::Attack)) { @@ -649,7 +649,7 @@ namespace TEN::Entities::TR4 else item->Animation.TargetState = 2; } - else if (Lara.TargetEntity != item || item->MeshBits != -1 || Lara.Control.Weapon.GunType != LaraWeaponType::Shotgun || TestProbability(1.0f / 128.0f)) + else if (Lara.TargetEntity != item || item->MeshBits != -1 || Lara.Control.Weapon.GunType != LaraWeaponType::Shotgun || TestProbability(1.0f / 128)) item->Animation.TargetState = 2; break; @@ -709,7 +709,7 @@ namespace TEN::Entities::TR4 if (GetCollision(item).Position.Floor <= (item->Pose.Position.y + SECTOR(1))) { - if (TestProbability(0.03f)) + if (TestProbability(1.0f / 30)) item->Animation.TargetState = 14; } else diff --git a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp index a641fa965..9d12d8ecc 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_troops.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_troops.cpp @@ -455,7 +455,7 @@ namespace TEN::Entities::TR4 break; case TROOP_STATE_FLASHED: - if (!FlashGrenadeAftershockTimer && TestProbability(1.0f / 128.0f)) + if (!FlashGrenadeAftershockTimer && TestProbability(1.0f / 128)) item->Animation.TargetState = TROOP_STATE_GUARD; break; diff --git a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp index fdd1cb2bf..1c92e02c9 100644 --- a/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp +++ b/TombEngine/Objects/TR4/Entity/tr4_wild_boar.cpp @@ -148,7 +148,7 @@ namespace TEN::Entities::TR4 if (AI.ahead && AI.distance) item->Animation.TargetState = BOAR_STATE_IDLE; - else if (TestProbability(1.0f / 128.0f)) + else if (TestProbability(1.0f / 128)) item->Animation.TargetState = BOAR_STATE_IDLE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp index 150553a6a..c6e0445db 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_doberman.cpp @@ -194,13 +194,13 @@ namespace TEN::Entities::Creatures::TR5 break; case DOBERMAN_STATE_SIT_IDLE: - if (creature->Mood != MoodType::Bored || TestProbability(1.0f / 128.0f)) + if (creature->Mood != MoodType::Bored || TestProbability(1.0f / 128)) item->Animation.TargetState = DOBERMAN_STATE_STOP; break; case DOBERMAN_STATE_STAND_IDLE: - if (creature->Mood != MoodType::Bored || TestProbability(0.015f)) + if (creature->Mood != MoodType::Bored || TestProbability(1.0f / 64)) item->Animation.TargetState = DOBERMAN_STATE_STOP; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp index 078198e22..e0adb2d22 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp @@ -152,7 +152,7 @@ namespace TEN::Entities::Creatures::TR5 creature->Flags = 0; if (item->AIBits & GUARD || - TestProbability(0.03f) && + TestProbability(1.0f / 30) && (AI.distance > pow(SECTOR(1), 2) || creature->Mood != MoodType::Attack)) { joint2 = AIGuard(creature); @@ -178,7 +178,7 @@ namespace TEN::Entities::Creatures::TR5 { if (item->Animation.RequiredState) item->Animation.TargetState = item->Animation.RequiredState; - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -235,7 +235,7 @@ namespace TEN::Entities::Creatures::TR5 else if (!AI.ahead || AI.distance > pow(SECTOR(1.5f), 2)) item->Animation.TargetState = GLADIATOR_STATE_RUN_FORWARD; } - else if (TestProbability(0.015f)) + else if (TestProbability(1.0f / 64)) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; @@ -301,7 +301,7 @@ namespace TEN::Entities::Creatures::TR5 break; } } - else if (Lara.TargetEntity != item || TestProbability(1.0f / 128.0f)) + else if (Lara.TargetEntity != item || TestProbability(1.0f / 128)) { item->Animation.TargetState = GLADIATOR_STATE_IDLE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp index eefc48524..1d22a8734 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp @@ -863,7 +863,7 @@ namespace TEN::Entities::Creatures::TR5 break; case GUARD_STATE_SURRENDER: - if (item != Lara.TargetEntity && TestProbability(0.015f)) + if (item != Lara.TargetEntity && TestProbability(1.0f / 64)) { if (item->TriggerFlags == 7 || item->TriggerFlags == 9) item->Animation.RequiredState = GUARD_STATE_USE_COMPUTER; @@ -1052,7 +1052,7 @@ namespace TEN::Entities::Creatures::TR5 { item->Animation.TargetState = SNIPER_STATE_COVER; } - else if (TestProbability(0.03f)) + else if (TestProbability(1.0f / 30)) item->Animation.TargetState = SNIPER_STATE_FIRE; break; diff --git a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp index 89e698ca5..a7a5c964a 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_larson.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_larson.cpp @@ -202,7 +202,7 @@ namespace TEN::Entities::Creatures::TR5 if (AI.ahead) joint2 = AI.angle; - if (creature->Mood == MoodType::Bored && TestProbability(0.003f)) + if (creature->Mood == MoodType::Bored && TestProbability(1.0f / 340)) { item->Animation.TargetState = STATE_TR5_LARSON_STOP; item->Animation.RequiredState = STATE_TR5_LARSON_IDLE; @@ -298,7 +298,7 @@ namespace TEN::Entities::Creatures::TR5 item->Animation.TargetState = STATE_TR5_LARSON_STOP; else { - if (TestProbability(0.003f)) + if (TestProbability(1.0f / 340)) { item->Animation.TargetState = STATE_TR5_LARSON_STOP; item->Animation.RequiredState = STATE_TR5_LARSON_WALK; diff --git a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp index 2d2b73b49..9a2cb2bed 100644 --- a/TombEngine/Objects/TR5/Entity/tr5_lion.cpp +++ b/TombEngine/Objects/TR5/Entity/tr5_lion.cpp @@ -142,7 +142,7 @@ namespace TEN::Entities::Creatures::TR5 if (creature->Mood == MoodType::Bored) { - if (TestProbability(1.0f / 256.0f)) + if (TestProbability(1.0f / 256)) { item->Animation.TargetState = LION_STATE_IDLE; item->Animation.RequiredState = LION_STATE_ROAR; @@ -165,7 +165,7 @@ namespace TEN::Entities::Creatures::TR5 item->Animation.TargetState = LION_STATE_IDLE; else if (creature->Mood != MoodType::Escape) { - if (TestProbability(1.0f / 256.0f)) + if (TestProbability(1.0f / 256)) { item->Animation.TargetState = LION_STATE_IDLE; item->Animation.RequiredState = LION_STATE_ROAR; From d3b2304d99052d2dd2015b5025facf9e6bde923e Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 16:38:25 +0300 Subject: [PATCH 101/106] Fix LevelFuncs not being able to return any value --- TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h | 8 ++++---- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp | 8 ++++++-- TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h | 4 ++-- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h b/TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h index a525a8f0f..e7399e1ee 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LevelFunc.h @@ -16,13 +16,13 @@ class LevelFunc { public: std::string m_funcName; LogicHandler* m_handler; - void Call(sol::variadic_args vs) + sol::protected_function_result Call(sol::variadic_args vs) { - m_handler->CallLevelFunc(m_funcName, vs); + return m_handler->CallLevelFunc(m_funcName, vs); } - void CallDT(float dt) + sol::protected_function_result CallDT(float dt) { - m_handler->CallLevelFunc(m_funcName, dt); + return m_handler->CallLevelFunc(m_funcName, dt); } static void Register(sol::table & parent) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp index d2bc2d41f..4338ca1b4 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.cpp @@ -180,7 +180,7 @@ sol::object LogicHandler::GetLevelFuncsMember(sol::table tab, std::string const& return sol::nil; } -void LogicHandler::CallLevelFunc(std::string const & name, float dt) +sol::protected_function_result LogicHandler::CallLevelFunc(std::string const & name, float dt) { sol::protected_function f = m_levelFuncs_luaFunctions[name]; auto r = f.call(dt); @@ -190,9 +190,11 @@ void LogicHandler::CallLevelFunc(std::string const & name, float dt) sol::error err = r; ScriptAssertF(false, "Could not execute function {}: {}", name, err.what()); } + + return r; } -void LogicHandler::CallLevelFunc(std::string const & name, sol::variadic_args va) +sol::protected_function_result LogicHandler::CallLevelFunc(std::string const & name, sol::variadic_args va) { sol::protected_function f = m_levelFuncs_luaFunctions[name]; auto r = f.call(va); @@ -201,6 +203,8 @@ void LogicHandler::CallLevelFunc(std::string const & name, sol::variadic_args va sol::error err = r; ScriptAssertF(false, "Could not execute function {}: {}", name, err.what()); } + + return r; } bool LogicHandler::SetLevelFuncsMember(sol::table tab, std::string const& luaName, sol::object value) diff --git a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h index 694c3cb44..24a4a74bf 100644 --- a/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h +++ b/TombEngine/Scripting/Internal/TEN/Logic/LogicHandler.h @@ -64,8 +64,8 @@ private: public: LogicHandler(sol::state* lua, sol::table & parent); - void CallLevelFunc(std::string const &, sol::variadic_args); - void CallLevelFunc(std::string const &, float dt); + sol::protected_function_result CallLevelFunc(std::string const &, sol::variadic_args); + sol::protected_function_result CallLevelFunc(std::string const &, float dt); void FreeLevelScripts() override; From 7e73c6f472b422fee80357f0784bb1c8d0887c2f Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 17:03:40 +0300 Subject: [PATCH 102/106] Fix ape run left chance --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 37a978973..779d87ec3 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -25,7 +25,7 @@ namespace TEN::Entities::Creatures::TR1 constexpr auto APE_IDLE_JUMP_CHANCE = 1.0f / 6; constexpr auto APE_IDLE_POUND_CHEST_CHANCE = 1.0f / 3; constexpr auto APE_IDLE_POUND_GROUND_CHANCE = 1.0f / 2; - constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 1.0f / 1; + constexpr auto APE_IDLE_RUN_LEFT_CHANCE = 1.0f / 2; constexpr auto APE_RUN_JUMP_CHANCE = APE_IDLE_JUMP_CHANCE / 32; constexpr auto APE_RUN_POUND_CHEST_CHANCE = APE_IDLE_POUND_CHEST_CHANCE / 32; constexpr auto APE_RUN_POUND_GROUND_CHANCE = APE_IDLE_POUND_GROUND_CHANCE / 32; From 5b962351dfb1e60ce446a19bf69e898468174ec7 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 17:06:42 +0300 Subject: [PATCH 103/106] Update Changes.txt --- Documentation/Changes.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt index b937c0fbc..dcf38bfd1 100644 --- a/Documentation/Changes.txt +++ b/Documentation/Changes.txt @@ -21,7 +21,9 @@ Version 1.0.2 * Fix occasional leave event calls when moving closer to volumes. * Fix incorrect viewport size in windowed mode. * Fix late landing animation dispatch in rare cases. -* Fix Lara's subway train death so that she no longer slides slowly after the animation has finished. +* Fix Lara's subway train death so that she no longer slides slowly after the animation has finished. +* Fix horseman's axe attack using his left foot as the damaging joint. +* Fix stargate blades needlessly pushing the player around while hardly doing any damage. Lua API changes: From 299ae7a0058d97d24bbe0cd7b0cc31a09f7e98cf Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Mon, 12 Sep 2022 17:26:49 +0300 Subject: [PATCH 104/106] Fix warnings --- TombEngine/Objects/TR1/Entity/tr1_ape.cpp | 2 -- TombEngine/Objects/TR4/Trap/tr4_stargate.cpp | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp index 779d87ec3..c0c62dbcb 100644 --- a/TombEngine/Objects/TR1/Entity/tr1_ape.cpp +++ b/TombEngine/Objects/TR1/Entity/tr1_ape.cpp @@ -188,8 +188,6 @@ namespace TEN::Entities::Creatures::TR1 if (item->HitStatus || AI.distance < APE_PANIC_RANGE) creatureInfo->Flags |= APE_FLAG_ATTACK; - short random; - switch (item->Animation.ActiveState) { case APE_STATE_IDLE: diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index 7f2afc884..4e0a56858 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -70,7 +70,7 @@ namespace TEN::Entities::Traps // Blades deal damage cumulatively. for (int i = 0; i < StargateHarmJoints.size(); i++) { - if (item->TestBits(JointBitType::Touch, StargateHarmJoints[i])); + if (item->TestBits(JointBitType::Touch, StargateHarmJoints[i])) { DoDamage(laraItem, STARGATE_HARM_DAMAGE); DoBloodSplat( From bd2c003b879ea364d09002f0058e428b329d3ee3 Mon Sep 17 00:00:00 2001 From: Lwmte <3331699+Lwmte@users.noreply.github.com> Date: Tue, 13 Sep 2022 02:24:57 +0300 Subject: [PATCH 105/106] Account for objects in lua LOS tests --- .../Scripting/Internal/TEN/Misc/Miscellanous.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp b/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp index 6b44a5688..00feff3f5 100644 --- a/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp +++ b/TombEngine/Scripting/Internal/TEN/Misc/Miscellanous.cpp @@ -48,10 +48,16 @@ namespace Misc pos1.StoreInGameVector(vec1); vec1.roomNumber = roomNumber1; pos2.StoreInGameVector(vec2); - return LOS(&vec1, &vec2); + + MESH_INFO* mesh; + Vector3Int vector; + return LOS(&vec1, &vec2) && (ObjectOnLOS2(&vec1, &vec2, &vector, &mesh) == NO_LOS_ITEM); } - + ///Vibrate game controller, if function is available and setting is on. + //@function Vibrate + //@tparam float strength Strength of the vibration + //@tparam float time __(default 0.3)__ Time of the vibration, in seconds static void Vibrate(float strength, sol::optional time) { Rumble(strength, time.value_or(0.3f), RumbleMode::Both); From a4b329aff45de6de050c1e5d39234db34f90ce54 Mon Sep 17 00:00:00 2001 From: Sezz Date: Tue, 13 Sep 2022 11:12:52 +1000 Subject: [PATCH 106/106] Fix stargate again --- TombEngine/Objects/TR4/Trap/tr4_stargate.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp index 4e0a56858..92e570fd7 100644 --- a/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp +++ b/TombEngine/Objects/TR4/Trap/tr4_stargate.cpp @@ -63,7 +63,8 @@ namespace TEN::Entities::Traps if (!TestBoundsCollide(item, laraItem, coll->Setup.Radius)) return; - if (TriggerActive(item) && + if (TestCollision(item, laraItem) && + TriggerActive(item) && item->Animation.FrameNumber > g_Level.Anims[item->Animation.AnimNumber].frameBase + 20 && // Hardcoded frame range. item->Animation.FrameNumber < g_Level.Anims[item->Animation.AnimNumber].frameBase + 60) {

    Create(name, totalTime, loop, timerFormat, func[, ...])func(name, totalTime, loop, timerFormat[, ...]) Create (but do not start) a new timer.