From 2dff1ef90cbda678421bd7d1b2c634c66662c5b9 Mon Sep 17 00:00:00 2001
From: Kuba Bilinski <80340234+Kubsy@users.noreply.github.com>
Date: Wed, 9 Nov 2022 21:46:11 +0000
Subject: [PATCH 01/13] Fix bloke by putting it to tr4_sas file (#827)
* fix bloke by putting it to tr4_sas file
* fix spacing
* Fix regressions, fix orphaned rotation setter
* Naming consistency
* Test for volumes as well
* Revert additional test for volumes
Co-authored-by: Lwmte <3331699+Lwmte@users.noreply.github.com>
---
TombEngine/Game/control/volume.cpp | 2 +-
TombEngine/Game/control/volume.h | 2 +-
TombEngine/Objects/TR4/Entity/tr4_sas.cpp | 91 +++++++++----------
.../Objects/TR4/Object/tr4_sas_drag_bloke.cpp | 79 ----------------
.../Objects/TR4/Object/tr4_sas_drag_bloke.h | 6 --
TombEngine/Objects/TR4/tr4_objects.cpp | 3 +-
TombEngine/TombEngine.vcxproj | 2 -
7 files changed, 48 insertions(+), 137 deletions(-)
delete mode 100644 TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.cpp
delete mode 100644 TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.h
diff --git a/TombEngine/Game/control/volume.cpp b/TombEngine/Game/control/volume.cpp
index dea98a9ff..2cf8e658d 100644
--- a/TombEngine/Game/control/volume.cpp
+++ b/TombEngine/Game/control/volume.cpp
@@ -154,7 +154,7 @@ namespace TEN::Control::Volumes
else if (Objects[item->ObjectNumber].intelligent)
TestVolumes(item->RoomNumber, bBox, TriggerVolumeActivators::NPC, itemNumber);
else
- TestVolumes(item->RoomNumber, bBox, TriggerVolumeActivators::Movable, itemNumber);
+ TestVolumes(item->RoomNumber, bBox, TriggerVolumeActivators::Moveable, itemNumber);
}
void InitialiseNodeScripts()
diff --git a/TombEngine/Game/control/volume.h b/TombEngine/Game/control/volume.h
index 5cabe9baf..7ebd16d2b 100644
--- a/TombEngine/Game/control/volume.h
+++ b/TombEngine/Game/control/volume.h
@@ -29,7 +29,7 @@ enum TriggerVolumeActivators
{
Player = 1,
NPC = 2,
- Movable = 4,
+ Moveable = 4,
Static = 8,
Flyby = 16,
PhysicalObject = 32 // Future-proofing for Bullet.
diff --git a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
index fd5a18e48..612c6dcd3 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_sas.cpp
@@ -5,6 +5,7 @@
#include "Game/collision/collide_item.h"
#include "Game/control/box.h"
#include "Game/control/control.h"
+#include "Game/control/volume.h"
#include "Game/effects/effects.h"
#include "Game/effects/tomb4fx.h"
#include "Game/itemdata/creature_info.h"
@@ -21,18 +22,19 @@
using namespace TEN::Input;
using namespace TEN::Math::Random;
+using namespace TEN::Control::Volumes;
namespace TEN::Entities::TR4
{
- const auto SASGunBite = BiteInfo(Vector3(0.0f, 300.0f, 64.0f), 7);
+ const auto SasGunBite = BiteInfo(Vector3(0.0f, 300.0f, 64.0f), 7);
- const auto SASDragBodyPosition = Vector3i(0, 0, -460);
- const ObjectCollisionBounds SASDragBodyBounds =
+ const auto SasDragBodyPosition = Vector3i(0, 0, -460);
+ const auto SasDragBounds = ObjectCollisionBounds
{
GameBoundingBox(
- -CLICK(1), CLICK(1),
- -CLICK(0.25f), 100,
- -200, -460
+ -BLOCK(1.0f / 4), BLOCK(1.0f / 4),
+ -100, 100,
+ -BLOCK(1.0f / 2), -460
),
std::pair(
EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), 0),
@@ -40,7 +42,7 @@ namespace TEN::Entities::TR4
)
};
- enum SASState
+ enum SasState
{
SAS_STATE_NONE = 0,
SAS_STATE_IDLE = 1,
@@ -62,7 +64,7 @@ namespace TEN::Entities::TR4
SAS_STATE_BLIND = 17
};
- enum SASAnim
+ enum SasAnim
{
SAS_ANIM_WALK = 0,
SAS_ANIM_RUN = 1,
@@ -126,7 +128,7 @@ namespace TEN::Entities::TR4
// Handle SAS firing.
if (creature->FiredWeapon)
{
- auto pos = GetJointPosition(item, SASGunBite.meshNum, Vector3i(SASGunBite.Position));
+ auto pos = GetJointPosition(item, SasGunBite.meshNum, Vector3i(SasGunBite.Position));
TriggerDynamicLight(pos.x, pos.y, pos.z, 10, 24, 16, 4);
creature->FiredWeapon--;
}
@@ -346,7 +348,7 @@ namespace TEN::Entities::TR4
}
else
item->Animation.TargetState = SAS_STATE_IDLE;
-
+
break;
case SAS_STATE_RUN:
@@ -511,7 +513,7 @@ namespace TEN::Entities::TR4
creature->Flags -= 1;
else
{
- ShotLara(item, &AI, SASGunBite, joint0, 15);
+ ShotLara(item, &AI, SasGunBite, joint0, 15);
creature->Flags = 5;
creature->FiredWeapon = 3;
}
@@ -566,7 +568,7 @@ namespace TEN::Entities::TR4
grenadeItem->ObjectNumber = ID_GRENADE;
grenadeItem->RoomNumber = item->RoomNumber;
- auto pos = GetJointPosition(item, SASGunBite.meshNum, Vector3i(SASGunBite.Position));
+ auto pos = GetJointPosition(item, SasGunBite.meshNum, Vector3i(SasGunBite.Position));
grenadeItem->Pose.Position = pos;
auto probe = GetCollision(pos.x, pos.y, pos.z, grenadeItem->RoomNumber);
@@ -649,52 +651,49 @@ namespace TEN::Entities::TR4
void SasDragBlokeCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
{
auto* item = &g_Level.Items[itemNumber];
+ auto* lara = GetLaraInfo(laraItem);
- if ((!(TrInput & IN_ACTION) ||
- laraItem->Animation.IsAirborne ||
- laraItem->Animation.ActiveState != LS_IDLE ||
- laraItem->Animation.AnimNumber != LA_STAND_IDLE ||
- Lara.Control.HandStatus != HandStatus::Free ||
- item->Flags & 0x3E00) &&
- (!(Lara.Control.IsMoving) || Lara.InteractedItem != itemNumber))
+ if ((IsHeld(In::Action) &&
+ laraItem->Animation.ActiveState == LS_IDLE &&
+ laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
+ lara->Control.HandStatus == HandStatus::Free &&
+ !laraItem->Animation.IsAirborne &&
+ !(item->Flags & IFLAG_ACTIVATION_MASK)) ||
+ lara->Control.IsMoving && lara->InteractedItem == itemNumber)
{
- if (item->Status == ITEM_ACTIVE)
+ if (TestLaraPosition(SasDragBounds, item, laraItem))
{
- if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd)
+ if (MoveLaraPosition(SasDragBodyPosition, item, laraItem))
{
- int x = laraItem->Pose.Position.x - 512 * phd_sin(laraItem->Pose.Orientation.y);
- int y = laraItem->Pose.Position.y;
- int z = laraItem->Pose.Position.z - 512 * phd_cos(laraItem->Pose.Orientation.y);
+ SetAnimation(laraItem, LA_DRAG_BODY);
+ ResetLaraFlex(laraItem);
+ laraItem->Pose.Orientation.y = item->Pose.Orientation.y;
+ lara->Control.HandStatus = HandStatus::Busy;
+ lara->Control.IsMoving = false;
- TestTriggers(x, y, z, laraItem->RoomNumber, true);
-
- RemoveActiveItem(itemNumber);
- item->Status = ITEM_NOT_ACTIVE;
+ AddActiveItem(itemNumber);
+ item->Flags |= IFLAG_ACTIVATION_MASK;
+ item->Status = ITEM_ACTIVE;
}
+ else
+ lara->InteractedItem = itemNumber;
}
-
- ObjectCollision(itemNumber, laraItem, coll);
}
else
{
- if (TestLaraPosition(SASDragBodyBounds, item, laraItem))
+ if (item->Status != ITEM_ACTIVE)
{
- if (MoveLaraPosition(SASDragBodyPosition, item, laraItem))
- {
- laraItem->Animation.AnimNumber = LA_DRAG_BODY;
- laraItem->Animation.ActiveState = LS_MISC_CONTROL;
- laraItem->Animation.FrameNumber = g_Level.Anims[laraItem->Animation.AnimNumber].frameBase;
- laraItem->Pose.Orientation.y = item->Pose.Orientation.y;
- ResetLaraFlex(laraItem);
- Lara.Control.IsMoving = false;
- Lara.Control.HandStatus = HandStatus::Busy;
- item->Flags |= 0x3E00;
- item->Status = ITEM_ACTIVE;
- AddActiveItem(itemNumber);
- }
- else
- Lara.InteractedItem = itemNumber;
+ ObjectCollision(itemNumber, laraItem, coll);
+ return;
}
+
+ if (!TestLastFrame(item))
+ return;
+
+ auto pos = GetJointPosition(item, 0);
+ TestTriggers(pos.x, pos.y, pos.z, item->RoomNumber, true);
+ RemoveActiveItem(itemNumber);
+ item->Status = ITEM_DEACTIVATED;
}
}
}
diff --git a/TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.cpp b/TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.cpp
deleted file mode 100644
index ad39b64a6..000000000
--- a/TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-#include "framework.h"
-#include "Objects/TR4/Object/tr4_sas_drag_bloke.h"
-
-#include "Game/collision/collide_item.h"
-#include "Game/health.h"
-#include "Game/items.h"
-#include "Game/Lara/lara.h"
-#include "Game/Lara/lara_helpers.h"
-#include "Game/pickup/pickup.h"
-#include "Math/Math.h"
-#include "Specific/Input/Input.h"
-#include "Specific/level.h"
-#include "Specific/setup.h"
-
-using namespace TEN::Input;
-using namespace TEN::Math;
-
-const auto DragSasPosition = Vector3i(0, 0, -460);
-const auto DragSasBounds = ObjectCollisionBounds
-{
- GameBoundingBox(
- -BLOCK(1.0f / 4), BLOCK(1.0f / 4),
- -100, 100,
- -BLOCK(1.0f / 2), -460
- ),
- std::pair(
- EulerAngles(ANGLE(-10.0f), ANGLE(-30.0f), ANGLE(-10.0f)),
- EulerAngles(ANGLE(10.0f), ANGLE(30.0f), ANGLE(10.0f))
- )
-};
-
-void DragSasCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
-{
- auto* item = &g_Level.Items[itemNumber];
- auto* lara = GetLaraInfo(laraItem);
-
- if ((IsHeld(In::Action) &&
- laraItem->Animation.ActiveState == LS_IDLE &&
- laraItem->Animation.AnimNumber == LA_STAND_IDLE &&
- !laraItem->Animation.IsAirborne &&
- lara->Control.HandStatus == HandStatus::Free &&
- !(item->Flags & IFLAG_ACTIVATION_MASK)) ||
- (lara->Control.IsMoving && lara->InteractedItem == itemNumber))
- {
- if (TestLaraPosition(DragSasBounds, item, laraItem))
- {
- if (MoveLaraPosition(DragSasPosition, item, laraItem))
- {
- AddActiveItem(itemNumber);
- item->Pose.Orientation.y;
- item->Flags |= IFLAG_ACTIVATION_MASK;
- item->Status = ITEM_ACTIVE;
-
- SetAnimation(laraItem, LA_DRAG_BODY);
- ResetLaraFlex(laraItem);
- lara->Control.HandStatus = HandStatus::Busy;
- lara->Control.IsMoving = false;
- }
- else
- lara->InteractedItem = itemNumber;
- }
- }
- else
- {
- if (item->Status != ITEM_ACTIVE)
- {
- ObjectCollision(itemNumber, laraItem, coll);
- return;
- }
-
- if (!TestLastFrame(item))
- return;
-
- auto pos = GetJointPosition(item, 0);
- TestTriggers(pos.x, pos.y, pos.z, item->RoomNumber, true);
- RemoveActiveItem(itemNumber);
- item->Status = ITEM_DEACTIVATED;
- }
-}
diff --git a/TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.h b/TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.h
deleted file mode 100644
index f084d6da6..000000000
--- a/TombEngine/Objects/TR4/Object/tr4_sas_drag_bloke.h
+++ /dev/null
@@ -1,6 +0,0 @@
-#pragma once
-
-struct CollisionInfo;
-struct ItemInfo;
-
-void DragSasCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);
diff --git a/TombEngine/Objects/TR4/tr4_objects.cpp b/TombEngine/Objects/TR4/tr4_objects.cpp
index 61445b7e9..8fd8661d5 100644
--- a/TombEngine/Objects/TR4/tr4_objects.cpp
+++ b/TombEngine/Objects/TR4/tr4_objects.cpp
@@ -46,7 +46,6 @@
#include "tr4_hammer.h"
// Objects
-#include "tr4_sas_drag_bloke.h"
#include "tr4_sarcophagus.h"
#include "tr4_senet.h"
#include "Objects/TR4/Object/tr4_clockwork_beetle.h"
@@ -853,7 +852,7 @@ namespace TEN::Entities
if (obj->loaded)
{
obj->control = AnimatingControl;
- obj->collision = DragSasCollision;
+ obj->collision = SasDragBlokeCollision;
obj->savePosition = true;
obj->saveFlags = true;
obj->saveAnim = true;
diff --git a/TombEngine/TombEngine.vcxproj b/TombEngine/TombEngine.vcxproj
index 4ec87f353..96461d368 100644
--- a/TombEngine/TombEngine.vcxproj
+++ b/TombEngine/TombEngine.vcxproj
@@ -166,7 +166,6 @@ CALL gen.bat
-
@@ -628,7 +627,6 @@ CALL gen.bat
-
From ba03030f1910a54276dc26dca6ad4be253bdbbde Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Wed, 9 Nov 2022 23:01:13 +0200
Subject: [PATCH 02/13] Update Changes.txt
---
Documentation/Changes.txt | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index cc47af595..7319c9133 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -7,7 +7,6 @@ Version 1.0.3
* Add SetNumberOfSecrets option to gameflow script to set overall amount of secrets.
* Add OCB 1 for rollingball to make it silent.
* Customize waterfall mist colour and OCB (XXYY, where XX is width, and YY is size).
-* Backport SAS_DRAG_BLOKE from TR4.
* Implement sprite instancing to speed up rendering.
* Merge portals at runtime to speed up rendering.
* Enable dynamic lights for swarm enemies (beetles, rats and bats).
@@ -28,6 +27,7 @@ Version 1.0.3
* Fix slow centaur projectile velocity.
* Fix search animations - allow chest and shelf animations to play properly.
* Fix sarcophagus and its item pickup.
+* Fix SAS_DRAG_BLOKE object interaction.
* Fix underwater door and double doors continuing to be interactable after opening.
* Fix underwater door being interactable when underwater switch is on the same square.
* Fix ability to turn when aligning to an object while standing.
From 827416f8870267de478776b3f9438dc7545ef255 Mon Sep 17 00:00:00 2001
From: Anatoly <3331699+Lwmte@users.noreply.github.com>
Date: Fri, 11 Nov 2022 14:47:20 +0200
Subject: [PATCH 03/13] Meshswap refactor (#828)
* Work
* Fix TestMeshSwapFlags
* Rename callbacks
* Revert unrelated changes
* Update items.h
---
TombEngine/Game/Lara/lara_fire.cpp | 8 +-
TombEngine/Game/Lara/lara_flare.cpp | 4 +-
TombEngine/Game/Lara/lara_initialise.cpp | 9 +-
TombEngine/Game/Lara/lara_one_gun.cpp | 4 +-
TombEngine/Game/Lara/lara_struct.h | 1 -
TombEngine/Game/Lara/lara_two_guns.cpp | 8 +-
TombEngine/Game/control/flipeffect.cpp | 22 +-
TombEngine/Game/effects/hair.cpp | 10 +-
TombEngine/Game/items.cpp | 66 ++++-
TombEngine/Game/items.h | 13 +-
TombEngine/Game/pickup/pickup.cpp | 6 +-
TombEngine/Game/savegame.cpp | 24 +-
.../Objects/Generic/Object/burning_torch.cpp | 6 +-
.../Objects/Generic/Traps/falling_block.cpp | 20 +-
TombEngine/Objects/TR2/Entity/tr2_dragon.cpp | 2 +-
TombEngine/Objects/TR3/Vehicles/kayak.cpp | 4 +-
TombEngine/Objects/TR3/Vehicles/minecart.cpp | 4 +-
TombEngine/Objects/TR4/Entity/tr4_baddy.cpp | 34 +--
TombEngine/Objects/TR4/Entity/tr4_guide.cpp | 18 +-
.../Objects/TR4/Entity/tr4_von_croy.cpp | 11 +-
.../Objects/TR4/Trap/tr4_joby_spikes.cpp | 8 +-
.../Objects/TR4/Trap/tr4_teethspike.cpp | 10 +-
TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp | 2 +-
.../Objects/TR5/Entity/tr5_gladiator.cpp | 2 +-
TombEngine/Objects/TR5/Entity/tr5_guard.cpp | 24 +-
TombEngine/Objects/TR5/Entity/tr5_imp.cpp | 4 +-
.../Objects/TR5/Entity/tr5_roman_statue.cpp | 26 +-
.../TR5/Object/tr5_expandingplatform.cpp | 6 +-
.../Objects/TR5/Object/tr5_raisingblock.cpp | 8 +-
TombEngine/Renderer/Renderer11.h | 7 +-
TombEngine/Renderer/Renderer11Draw.cpp | 17 +-
TombEngine/Renderer/Renderer11Helper.cpp | 240 +++++++++---------
TombEngine/Renderer/Renderer11Lara.cpp | 9 +-
.../TEN/Objects/Moveable/MoveableObject.cpp | 57 ++---
.../flatbuffers/ten_savegame_generated.h | 88 +++----
.../Specific/savegame/schema/ten_savegame.fbs | 6 +-
36 files changed, 415 insertions(+), 373 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp
index d531cd984..36f38380a 100644
--- a/TombEngine/Game/Lara/lara_fire.cpp
+++ b/TombEngine/Game/Lara/lara_fire.cpp
@@ -641,7 +641,7 @@ void HandleWeapon(ItemInfo* laraItem)
break;
case HandStatus::WeaponUndraw:
- lara->MeshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
+ laraItem->Model.MeshIndex[LM_HEAD] = laraItem->Model.BaseMesh + LM_HEAD;
switch (lara->Control.Weapon.GunType)
{
@@ -672,9 +672,9 @@ void HandleWeapon(ItemInfo* laraItem)
case HandStatus::WeaponReady:
if (!(TrInput & IN_ACTION))
- lara->MeshPtrs[LM_HEAD] = Objects[ID_LARA_SKIN].meshIndex + LM_HEAD;
+ laraItem->Model.MeshIndex[LM_HEAD] = laraItem->Model.BaseMesh + LM_HEAD;
else
- lara->MeshPtrs[LM_HEAD] = Objects[ID_LARA_SCREAM].meshIndex + LM_HEAD;
+ laraItem->Model.MeshIndex[LM_HEAD] = Objects[ID_LARA_SCREAM].meshIndex + LM_HEAD;
if (Camera.type != CameraType::Look &&
Camera.type != CameraType::Heavy)
@@ -747,7 +747,7 @@ void HandleWeapon(ItemInfo* laraItem)
case HandStatus::Busy:
if (lara->Control.Weapon.GunType == LaraWeaponType::Flare)
{
- if (lara->MeshPtrs[LM_LHAND] == Objects[ID_FLARE_ANIM].meshIndex + LM_LHAND)
+ if (laraItem->Model.MeshIndex[LM_LHAND] == Objects[ID_FLARE_ANIM].meshIndex + LM_LHAND)
{
lara->Flare.ControlLeft = (lara->Vehicle != NO_ITEM || TestState(laraItem->Animation.ActiveState, FlarePoseStates));
DoFlareInHand(laraItem, lara->Flare.Life);
diff --git a/TombEngine/Game/Lara/lara_flare.cpp b/TombEngine/Game/Lara/lara_flare.cpp
index a96578c7b..2d0f1f1cc 100644
--- a/TombEngine/Game/Lara/lara_flare.cpp
+++ b/TombEngine/Game/Lara/lara_flare.cpp
@@ -100,14 +100,14 @@ void UndrawFlareMeshes(ItemInfo* laraItem)
{
auto* lara = GetLaraInfo(laraItem);
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = laraItem->Model.BaseMesh + LM_LHAND;
}
void DrawFlareMeshes(ItemInfo* laraItem)
{
auto* lara = GetLaraInfo(laraItem);
- lara->MeshPtrs[LM_LHAND] = Objects[ID_FLARE_ANIM].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = Objects[ID_FLARE_ANIM].meshIndex + LM_LHAND;
}
void UndrawFlare(ItemInfo* laraItem)
diff --git a/TombEngine/Game/Lara/lara_initialise.cpp b/TombEngine/Game/Lara/lara_initialise.cpp
index 0894d3ba5..296613933 100644
--- a/TombEngine/Game/Lara/lara_initialise.cpp
+++ b/TombEngine/Game/Lara/lara_initialise.cpp
@@ -99,12 +99,11 @@ void InitialiseLaraMeshes(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
+ // Override base mesh and mesh indices to Lara skin.
+
+ item->Model.BaseMesh = Objects[ID_LARA_SKIN].meshIndex;
for (int i = 0; i < NUM_LARA_MESHES; i++)
- {
- //Meshes[i] = Meshes[MESHES(ID_LARA_SKIN, i)];
- //LARA_MESHES(ID_LARA, MESHES(ID_LARA_SKIN, i));
- lara->MeshPtrs[i] = Objects[ID_LARA_SKIN].meshIndex + i;
- }
+ item->Model.MeshIndex[i] = item->Model.BaseMesh + i;
/* Hardcoded code */
diff --git a/TombEngine/Game/Lara/lara_one_gun.cpp b/TombEngine/Game/Lara/lara_one_gun.cpp
index 01310a2f7..d3235e99d 100644
--- a/TombEngine/Game/Lara/lara_one_gun.cpp
+++ b/TombEngine/Game/Lara/lara_one_gun.cpp
@@ -430,14 +430,14 @@ void DrawShotgunMeshes(ItemInfo* laraItem, LaraWeaponType weaponType)
auto* lara = GetLaraInfo(laraItem);
lara->Control.Weapon.HolsterInfo.BackHolster = HolsterSlot::Empty;
- lara->MeshPtrs[LM_RHAND] = Objects[GetWeaponObjectMeshID(laraItem, weaponType)].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = Objects[GetWeaponObjectMeshID(laraItem, weaponType)].meshIndex + LM_RHAND;
}
void UndrawShotgunMeshes(ItemInfo* laraItem, LaraWeaponType weaponType)
{
auto* lara = GetLaraInfo(laraItem);
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
if (lara->Weapons[(int)weaponType].Present)
lara->Control.Weapon.HolsterInfo.BackHolster = GetWeaponHolsterSlot(weaponType);
diff --git a/TombEngine/Game/Lara/lara_struct.h b/TombEngine/Game/Lara/lara_struct.h
index 7c34c3b85..913e71d0f 100644
--- a/TombEngine/Game/Lara/lara_struct.h
+++ b/TombEngine/Game/Lara/lara_struct.h
@@ -1300,7 +1300,6 @@ struct LaraInfo
bool BurnSmoke;
byte Wet[NUM_LARA_MESHES];
- int MeshPtrs[NUM_LARA_MESHES];
signed char Location;
signed char HighestLocation;
signed char LocationPad;
diff --git a/TombEngine/Game/Lara/lara_two_guns.cpp b/TombEngine/Game/Lara/lara_two_guns.cpp
index a57bfc9ea..ed418027f 100644
--- a/TombEngine/Game/Lara/lara_two_guns.cpp
+++ b/TombEngine/Game/Lara/lara_two_guns.cpp
@@ -480,16 +480,16 @@ void DrawPistolMeshes(ItemInfo* laraItem, LaraWeaponType weaponType)
lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlot::Empty;
- lara->MeshPtrs[LM_RHAND] = Objects[GetWeaponObjectMeshID(laraItem, weaponType)].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = Objects[GetWeaponObjectMeshID(laraItem, weaponType)].meshIndex + LM_RHAND;
if (weaponType != LaraWeaponType::Revolver)
- lara->MeshPtrs[LM_LHAND] = Objects[GetWeaponObjectMeshID(laraItem, weaponType)].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = Objects[GetWeaponObjectMeshID(laraItem, weaponType)].meshIndex + LM_LHAND;
}
void UndrawPistolMeshRight(ItemInfo* laraItem, LaraWeaponType weaponType)
{
auto* lara = GetLaraInfo(laraItem);
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
if (lara->Weapons[(int)weaponType].Present)
lara->Control.Weapon.HolsterInfo.RightHolster = GetWeaponHolsterSlot(weaponType);
else
@@ -502,7 +502,7 @@ void UndrawPistolMeshLeft(ItemInfo* laraItem, LaraWeaponType weaponType)
if (weaponType != LaraWeaponType::Revolver)
{
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = laraItem->Model.BaseMesh + LM_LHAND;
if (lara->Weapons[(int)weaponType].Present)
lara->Control.Weapon.HolsterInfo.LeftHolster = GetWeaponHolsterSlot(weaponType);
diff --git a/TombEngine/Game/control/flipeffect.cpp b/TombEngine/Game/control/flipeffect.cpp
index 2a1e860a0..23fa488f9 100644
--- a/TombEngine/Game/control/flipeffect.cpp
+++ b/TombEngine/Game/control/flipeffect.cpp
@@ -99,14 +99,14 @@ void MeshSwapToPour(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
- lara->MeshPtrs[LM_LHAND] = Objects[item->ItemFlags[2]].meshIndex + LM_LHAND;
+ item->Model.MeshIndex[LM_LHAND] = Objects[item->ItemFlags[2]].meshIndex + LM_LHAND;
}
void MeshSwapFromPour(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
+ item->Model.MeshIndex[LM_LHAND] = item->Model.BaseMesh + LM_LHAND;
}
void Pickup(ItemInfo* item)
@@ -153,14 +153,14 @@ void DrawLeftPistol(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
- if (lara->MeshPtrs[LM_LHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_LHAND)
+ if (item->Model.MeshIndex[LM_LHAND] == item->Model.BaseMesh + LM_LHAND)
{
- lara->MeshPtrs[LM_LHAND] = Objects[GetWeaponObjectMeshID(item, LaraWeaponType::Pistol)].meshIndex + LM_LHAND;
+ item->Model.MeshIndex[LM_LHAND] = Objects[GetWeaponObjectMeshID(item, LaraWeaponType::Pistol)].meshIndex + LM_LHAND;
lara->Control.Weapon.HolsterInfo.LeftHolster = HolsterSlot::Empty;
}
else
{
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
+ item->Model.MeshIndex[LM_LHAND] = item->Model.BaseMesh + LM_LHAND;
lara->Control.Weapon.HolsterInfo.LeftHolster = GetWeaponHolsterSlot(LaraWeaponType::Pistol);
}
}
@@ -169,14 +169,14 @@ void DrawRightPistol(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
- if (lara->MeshPtrs[LM_RHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_RHAND)
+ if (item->Model.MeshIndex[LM_RHAND] == item->Model.BaseMesh + LM_RHAND)
{
- lara->MeshPtrs[LM_RHAND] = Objects[GetWeaponObjectMeshID(item, LaraWeaponType::Pistol)].meshIndex + LM_RHAND;
+ item->Model.MeshIndex[LM_RHAND] = Objects[GetWeaponObjectMeshID(item, LaraWeaponType::Pistol)].meshIndex + LM_RHAND;
lara->Control.Weapon.HolsterInfo.RightHolster = HolsterSlot::Empty;
}
else
{
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
+ item->Model.MeshIndex[LM_RHAND] = item->Model.BaseMesh + LM_RHAND;
lara->Control.Weapon.HolsterInfo.RightHolster = GetWeaponHolsterSlot(LaraWeaponType::Pistol);
}
}
@@ -263,10 +263,10 @@ void SwapCrowbar(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
- if (lara->MeshPtrs[LM_RHAND] == Objects[ID_LARA_SKIN].meshIndex + LM_RHAND)
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND;
+ if (item->Model.MeshIndex[LM_RHAND] == item->Model.BaseMesh + LM_RHAND)
+ item->Model.MeshIndex[LM_RHAND] = Objects[ID_LARA_CROWBAR_ANIM].meshIndex + LM_RHAND;
else
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
+ item->Model.MeshIndex[LM_RHAND] = item->Model.BaseMesh + LM_RHAND;
}
void ActivateKey(ItemInfo* item)
diff --git a/TombEngine/Game/effects/hair.cpp b/TombEngine/Game/effects/hair.cpp
index 518d416b3..5658d2c66 100644
--- a/TombEngine/Game/effects/hair.cpp
+++ b/TombEngine/Game/effects/hair.cpp
@@ -107,14 +107,14 @@ void HairControl(ItemInfo* item, int ponytail, AnimFrame* framePtr)
frame = framePtr;
// Get Lara's spheres in absolute coordinates for head, torso, hips, and upper arms.
- auto* mesh = &g_Level.Meshes[lara->MeshPtrs[LM_HIPS]];
+ auto* mesh = &g_Level.Meshes[item->Model.MeshIndex[LM_HIPS]];
auto pos = GetJointPosition(item, LM_HIPS, Vector3i(mesh->sphere.Center.x, mesh->sphere.Center.y, mesh->sphere.Center.z));
sphere[0].x = pos.x;
sphere[0].y = pos.y;
sphere[0].z = pos.z;
sphere[0].r = (int)mesh->sphere.Radius;
- mesh = &g_Level.Meshes[lara->MeshPtrs[LM_TORSO]];
+ mesh = &g_Level.Meshes[item->Model.MeshIndex[LM_TORSO]];
pos = GetJointPosition(item, LM_TORSO, Vector3i(mesh->sphere.Center.x - 10, mesh->sphere.Center.y, mesh->sphere.Center.z + 25));
sphere[1].x = pos.x;
sphere[1].y = pos.y;
@@ -123,21 +123,21 @@ void HairControl(ItemInfo* item, int ponytail, AnimFrame* framePtr)
if (youngLara)
sphere[1].r = sphere[1].r - ((sphere[1].r >> 2) + (sphere[1].r >> 3));
- mesh = &g_Level.Meshes[lara->MeshPtrs[LM_HEAD]];
+ mesh = &g_Level.Meshes[item->Model.MeshIndex[LM_HEAD]];
pos = GetJointPosition(item, LM_HEAD, Vector3i(mesh->sphere.Center.x - 2, mesh->sphere.Center.y, mesh->sphere.Center.z));
sphere[2].x = pos.x;
sphere[2].y = pos.y;
sphere[2].z = pos.z;
sphere[2].r = (int)mesh->sphere.Radius;
- mesh = &g_Level.Meshes[lara->MeshPtrs[LM_RINARM]];
+ mesh = &g_Level.Meshes[item->Model.MeshIndex[LM_RINARM]];
pos = GetJointPosition(item, LM_RINARM, Vector3i(mesh->sphere.Center.x, mesh->sphere.Center.y, mesh->sphere.Center.z));
sphere[3].x = pos.x;
sphere[3].y = pos.y;
sphere[3].z = pos.z;
sphere[3].r = int(4.0f * mesh->sphere.Radius / 3.0f); // Resizing sphere - from tomb5
- mesh = &g_Level.Meshes[lara->MeshPtrs[LM_LINARM]];
+ mesh = &g_Level.Meshes[item->Model.MeshIndex[LM_LINARM]];
pos = GetJointPosition(item, LM_LINARM, Vector3i(mesh->sphere.Center.x, mesh->sphere.Center.y, mesh->sphere.Center.z));
sphere[4].x = pos.x;
sphere[4].y = pos.y;
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 21794c34a..0e4060cd4 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -48,6 +48,54 @@ void ItemInfo::SetFlags(short id, short value)
ItemFlags[id] = value;
}
+bool ItemInfo::TestMeshSwapFlags(unsigned int flags)
+{
+ for (size_t i = 0; i < Model.MeshIndex.size(); i++)
+ {
+ if (flags & (1 << i))
+ {
+ if (Model.MeshIndex[i] == Model.BaseMesh + i)
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool ItemInfo::TestMeshSwapFlags(const std::vector flags)
+{
+ BitField bits = {};
+ bits.Set(flags);
+ return TestMeshSwapFlags(bits.ToPackedBits());
+}
+
+void ItemInfo::SetMeshSwapFlags(unsigned int flags, bool clear)
+{
+ bool meshSwapPresent = Objects[ObjectNumber].meshSwapSlot != -1 &&
+ Objects[Objects[ObjectNumber].meshSwapSlot].loaded;
+
+
+ for (size_t i = 0; i < Model.MeshIndex.size(); i++)
+ {
+ if (meshSwapPresent && (flags & (1 << i)))
+ {
+ if (clear)
+ Model.MeshIndex[i] = Model.BaseMesh + i;
+ else
+ Model.MeshIndex[i] = Objects[Objects[ObjectNumber].meshSwapSlot].meshIndex + i;
+ }
+ else
+ Model.MeshIndex[i] = Model.BaseMesh + i;
+ }
+}
+
+void ItemInfo::SetMeshSwapFlags(const std::vector flags, bool clear)
+{
+ BitField bits = {};
+ bits.Set(flags);
+ SetMeshSwapFlags(bits.ToPackedBits(), clear);
+}
+
bool ItemInfo::IsLara()
{
return this->Data.is();
@@ -434,7 +482,6 @@ void InitialiseItem(short itemNumber)
item->TouchBits = NO_JOINT_BITS;
item->AfterDeath = 0;
- item->MeshSwapBits = NO_JOINT_BITS;
if (item->Flags & IFLAG_INVISIBLE)
{
@@ -463,12 +510,21 @@ void InitialiseItem(short itemNumber)
if (Objects[item->ObjectNumber].nmeshes > 0)
{
- item->Animation.Mutator.resize(Objects[item->ObjectNumber].nmeshes);
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
- item->Animation.Mutator[i] = {};
+ item->Model.BaseMesh = Objects[item->ObjectNumber].meshIndex;
+
+ item->Model.MeshIndex.resize(Objects[item->ObjectNumber].nmeshes);
+ for (int i = 0; i < item->Model.MeshIndex.size(); i++)
+ item->Model.MeshIndex[i] = item->Model.BaseMesh + i;
+
+ item->Model.Mutator.resize(Objects[item->ObjectNumber].nmeshes);
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i] = {};
}
else
- item->Animation.Mutator.clear();
+ {
+ item->Model.Mutator.clear();
+ item->Model.MeshIndex.clear();
+ }
if (Objects[item->ObjectNumber].initialise != NULL)
Objects[item->ObjectNumber].initialise(itemNumber);
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index a398a3183..0b9deb815 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -66,6 +66,12 @@ struct EntityAnimationData
bool IsAirborne = false;
Vector3 Velocity = Vector3::Zero; // CONVENTION: +X = right, +Y = down, +Z = forward
+};
+
+struct EntityModelData
+{
+ int BaseMesh;
+ std::vector MeshIndex = {};
std::vector Mutator = {};
};
@@ -83,6 +89,7 @@ struct ItemInfo
ITEM_DATA Data;
EntityAnimationData Animation;
+ EntityModelData Model;
Pose StartPose;
Pose Pose;
ROOM_VECTOR Location;
@@ -101,7 +108,6 @@ struct ItemInfo
BitField TouchBits = BitField();
BitField MeshBits = BitField();
- BitField MeshSwapBits = BitField();
unsigned short Flags; // ItemFlags enum
short ItemFlags[8];
@@ -126,6 +132,11 @@ struct ItemInfo
bool TestFlags(short id, short value);
void SetFlags(short id, short value);
+ bool TestMeshSwapFlags(unsigned int flags);
+ bool TestMeshSwapFlags(const std::vector flags);
+ void SetMeshSwapFlags(unsigned int flags, bool clear = false);
+ void SetMeshSwapFlags(const std::vector flags, bool clear = false);
+
bool IsLara();
bool IsCreature();
};
diff --git a/TombEngine/Game/pickup/pickup.cpp b/TombEngine/Game/pickup/pickup.cpp
index d9aae3680..f672b0869 100644
--- a/TombEngine/Game/pickup/pickup.cpp
+++ b/TombEngine/Game/pickup/pickup.cpp
@@ -928,7 +928,7 @@ void InitialiseSearchObject(short itemNumber)
auto* item = &g_Level.Items[itemNumber];
if (item->ObjectNumber == ID_SEARCH_OBJECT1)
{
- item->MeshSwapBits = ALL_JOINT_BITS;
+ item->SetMeshSwapFlags(ALL_JOINT_BITS);
item->MeshBits = 7;
}
else if (item->ObjectNumber == ID_SEARCH_OBJECT2)
@@ -1044,12 +1044,12 @@ void SearchObjectControl(short itemNumber)
{
if (frameNumber > 0)
{
- item->MeshSwapBits = NO_JOINT_BITS;
+ item->SetMeshSwapFlags(NO_JOINT_BITS);
item->MeshBits = ALL_JOINT_BITS;
}
else
{
- item->MeshSwapBits = ALL_JOINT_BITS;
+ item->SetMeshSwapFlags(ALL_JOINT_BITS);
item->MeshBits = 7;
}
}
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index f04c2b52c..d752b25ff 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -228,11 +228,6 @@ bool SaveGame::Save(int slot)
examinesCombo.push_back(Lara.Inventory.ExaminesCombo[i]);
auto examinesComboOffset = fbb.CreateVector(examinesCombo);
- std::vector meshPtrs;
- for (int i = 0; i < 15; i++)
- meshPtrs.push_back(Lara.MeshPtrs[i]);
- auto meshPtrsOffset = fbb.CreateVector(meshPtrs);
-
std::vector wet;
for (int i = 0; i < 15; i++)
wet.push_back(Lara.Wet[i] == 1);
@@ -440,7 +435,6 @@ bool SaveGame::Save(int slot)
lara.add_left_arm(leftArmOffset);
lara.add_location(Lara.Location);
lara.add_location_pad(Lara.LocationPad);
- lara.add_mesh_ptrs(meshPtrsOffset);
lara.add_poison_potency(Lara.PoisonPotency);
lara.add_projected_floor_height(Lara.ProjectedFloorHeight);
lara.add_right_arm(rightArmOffset);
@@ -472,6 +466,11 @@ bool SaveGame::Save(int slot)
for (int i = 0; i < 7; i++)
itemFlags.push_back(itemToSerialize.ItemFlags[i]);
auto itemFlagsOffset = fbb.CreateVector(itemFlags);
+
+ std::vector meshPointers;
+ for (auto p : itemToSerialize.Model.MeshIndex)
+ meshPointers.push_back(p);
+ auto meshPointerOffset = fbb.CreateVector(meshPointers);
flatbuffers::Offset creatureOffset;
flatbuffers::Offset quadOffset;
@@ -628,6 +627,8 @@ bool SaveGame::Save(int slot)
serializedItem.add_hit_points(itemToSerialize.HitPoints);
serializedItem.add_item_flags(itemFlagsOffset);
serializedItem.add_mesh_bits(itemToSerialize.MeshBits.ToPackedBits());
+ serializedItem.add_mesh_pointers(meshPointerOffset);
+ serializedItem.add_base_mesh(itemToSerialize.Model.BaseMesh);
serializedItem.add_object_id(itemToSerialize.ObjectNumber);
serializedItem.add_pose(&FromPHD(itemToSerialize.Pose));
serializedItem.add_required_state(itemToSerialize.Animation.RequiredState);
@@ -645,7 +646,6 @@ bool SaveGame::Save(int slot)
serializedItem.add_ai_bits(itemToSerialize.AIBits);
serializedItem.add_collidable(itemToSerialize.Collidable);
serializedItem.add_looked_at(itemToSerialize.LookedAt);
- serializedItem.add_swap_mesh_flags(itemToSerialize.MeshSwapBits.ToPackedBits());
if (Objects[itemToSerialize.ObjectNumber].intelligent
&& itemToSerialize.Data.is())
@@ -1388,7 +1388,10 @@ bool SaveGame::Load(int slot)
// Mesh stuff
item->MeshBits = savedItem->mesh_bits();
- item->MeshSwapBits = savedItem->swap_mesh_flags();
+
+ item->Model.BaseMesh = savedItem->base_mesh();
+ for (int j = 0; j < savedItem->mesh_pointers()->size(); j++)
+ item->Model.MeshIndex[j] = savedItem->mesh_pointers()->Get(j);
if (item->ObjectNumber >= ID_SMASH_OBJECT1 && item->ObjectNumber <= ID_SMASH_OBJECT8 &&
(item->Flags & ONESHOT))
@@ -1702,11 +1705,6 @@ bool SaveGame::Load(int slot)
Lara.Inventory.ExaminesCombo[i] = s->lara()->inventory()->examines_combo()->Get(i);
}
- for (int i = 0; i < s->lara()->mesh_ptrs()->size(); i++)
- {
- Lara.MeshPtrs[i] = s->lara()->mesh_ptrs()->Get(i);
- }
-
for (int i = 0; i < NUM_LARA_MESHES; i++)
{
Lara.Wet[i] = s->lara()->wet()->Get(i);
diff --git a/TombEngine/Objects/Generic/Object/burning_torch.cpp b/TombEngine/Objects/Generic/Object/burning_torch.cpp
index 9f17d3b0c..a823a6776 100644
--- a/TombEngine/Objects/Generic/Object/burning_torch.cpp
+++ b/TombEngine/Objects/Generic/Object/burning_torch.cpp
@@ -129,7 +129,7 @@ namespace TEN::Entities::Generic
}
else if (lara->LeftArm.FrameNumber == 12)
{
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = laraItem->Model.BaseMesh + LM_LHAND;
CreateFlare(laraItem, ID_BURNING_TORCH_ITEM, true);
}
}
@@ -149,7 +149,7 @@ namespace TEN::Entities::Generic
}
else if (lara->LeftArm.FrameNumber == 36)
{
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = laraItem->Model.BaseMesh + LM_LHAND;
CreateFlare(laraItem, ID_BURNING_TORCH_ITEM, false);
}
}
@@ -200,7 +200,7 @@ namespace TEN::Entities::Generic
lara->LeftArm.FrameNumber = 0;
lara->LeftArm.FrameBase = g_Level.Anims[lara->LeftArm.AnimNumber].FramePtr;
- lara->MeshPtrs[LM_LHAND] = Objects[ID_LARA_TORCH_ANIM].meshIndex + LM_LHAND;
+ laraItem->Model.MeshIndex[LM_LHAND] = Objects[ID_LARA_TORCH_ANIM].meshIndex + LM_LHAND;
}
void TorchControl(short itemNumber)
diff --git a/TombEngine/Objects/Generic/Traps/falling_block.cpp b/TombEngine/Objects/Generic/Traps/falling_block.cpp
index 1df87068b..cb429654a 100644
--- a/TombEngine/Objects/Generic/Traps/falling_block.cpp
+++ b/TombEngine/Objects/Generic/Traps/falling_block.cpp
@@ -32,8 +32,8 @@ void InitialiseFallingBlock(short itemNumber)
TEN::Floordata::UpdateBridgeItem(itemNumber);
// Set mutators to 0 by default
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
- item->Animation.Mutator[i].Rotation = Vector3::Zero;
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i].Rotation = Vector3::Zero;
}
void FallingBlockCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll)
@@ -70,23 +70,23 @@ void FallingBlockControl(short itemNumber)
if (item->ItemFlags[0] < FALLINGBLOCK_DELAY)
{
// Subtly shake all meshes separately.
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
{
- item->Animation.Mutator[i].Rotation.x = RADIAN * GenerateFloat(-FALLINGBLOCK_WIBBLE, FALLINGBLOCK_WIBBLE);
- item->Animation.Mutator[i].Rotation.y = RADIAN * GenerateFloat(-FALLINGBLOCK_WIBBLE, FALLINGBLOCK_WIBBLE);
- item->Animation.Mutator[i].Rotation.z = RADIAN * GenerateFloat(-FALLINGBLOCK_WIBBLE, FALLINGBLOCK_WIBBLE);
+ item->Model.Mutator[i].Rotation.x = RADIAN * GenerateFloat(-FALLINGBLOCK_WIBBLE, FALLINGBLOCK_WIBBLE);
+ item->Model.Mutator[i].Rotation.y = RADIAN * GenerateFloat(-FALLINGBLOCK_WIBBLE, FALLINGBLOCK_WIBBLE);
+ item->Model.Mutator[i].Rotation.z = RADIAN * GenerateFloat(-FALLINGBLOCK_WIBBLE, FALLINGBLOCK_WIBBLE);
}
}
else
{
// Make rotational falling movement with some random seed.
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
{
auto rotSpeed = i % 2 ? FALLINGBLOCK_FALL_ROTATION_SPEED : -FALLINGBLOCK_FALL_ROTATION_SPEED;
rotSpeed += i % 3 ? rotSpeed / 2 : rotSpeed;
- item->Animation.Mutator[i].Rotation.x += RADIAN * rotSpeed + (RADIAN * GenerateFloat(-1, 1));
- item->Animation.Mutator[i].Rotation.y += RADIAN * rotSpeed + (RADIAN * GenerateFloat(-1, 1));
- item->Animation.Mutator[i].Rotation.z += RADIAN * rotSpeed + (RADIAN * GenerateFloat(-1, 1));
+ item->Model.Mutator[i].Rotation.x += RADIAN * rotSpeed + (RADIAN * GenerateFloat(-1, 1));
+ item->Model.Mutator[i].Rotation.y += RADIAN * rotSpeed + (RADIAN * GenerateFloat(-1, 1));
+ item->Model.Mutator[i].Rotation.z += RADIAN * rotSpeed + (RADIAN * GenerateFloat(-1, 1));
}
if (item->ItemFlags[0] == FALLINGBLOCK_DELAY)
diff --git a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp
index 410ddb389..7c668bb84 100644
--- a/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp
+++ b/TombEngine/Objects/TR2/Entity/tr2_dragon.cpp
@@ -213,7 +213,7 @@ namespace TEN::Entities::Creatures::TR2
Lara.Control.HandStatus = HandStatus::Busy;
Lara.HitDirection = -1;
- Lara.MeshPtrs[LM_RHAND] = Objects[ID_LARA_EXTRA_ANIMS].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_LARA_EXTRA_ANIMS].meshIndex + LM_RHAND;
((CreatureInfo*)g_Level.Items[(short)item->Data].Data)->Flags = -1;
diff --git a/TombEngine/Objects/TR3/Vehicles/kayak.cpp b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
index 016a298f3..5ff301cc7 100644
--- a/TombEngine/Objects/TR3/Vehicles/kayak.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/kayak.cpp
@@ -1027,7 +1027,7 @@ namespace TEN::Entities::Vehicles
!(kayak->Flags & 0x80))
{
kayak->Flags |= 0x80;
- lara->MeshPtrs[LM_RHAND] = Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_KAYAK_LARA_ANIMS].meshIndex + LM_RHAND;
laraItem->MeshBits.Clear(KayakLaraLegJoints);
}
@@ -1039,7 +1039,7 @@ namespace TEN::Entities::Vehicles
kayak->Flags & 0x80)
{
kayak->Flags &= ~0x80;
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
laraItem->MeshBits.Set(KayakLaraLegJoints);
}
diff --git a/TombEngine/Objects/TR3/Vehicles/minecart.cpp b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
index 2b4571b16..e508b4338 100644
--- a/TombEngine/Objects/TR3/Vehicles/minecart.cpp
+++ b/TombEngine/Objects/TR3/Vehicles/minecart.cpp
@@ -741,7 +741,7 @@ namespace TEN::Entities::Vehicles
if (laraItem->Animation.FrameNumber == GetFrameNumber(minecartItem, MINECART_WRENCH_MESH_TOGGLE_FRAME) &&
minecart->Flags & MINECART_FLAG_WRENCH_MESH)
{
- lara->MeshPtrs[LM_RHAND] = Objects[ID_LARA_SKIN].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = laraItem->Model.BaseMesh + LM_RHAND;
minecart->Flags &= ~MINECART_FLAG_WRENCH_MESH;
}
@@ -790,7 +790,7 @@ namespace TEN::Entities::Vehicles
if (!(minecart->Flags & MINECART_FLAG_WRENCH_MESH) &&
laraItem->Animation.FrameNumber == GetFrameNumber(minecartItem, MINECART_WRENCH_MESH_TOGGLE_FRAME))
{
- lara->MeshPtrs[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
+ laraItem->Model.MeshIndex[LM_RHAND] = Objects[ID_MINECART_LARA_ANIMS].meshIndex + LM_RHAND;
minecart->Flags |= MINECART_FLAG_WRENCH_MESH;
}
}
diff --git a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
index 65c474e75..6bb3cd697 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_baddy.cpp
@@ -216,13 +216,13 @@ namespace TEN::Entities::TR4
if (item->ObjectNumber == ID_BADDY1)
{
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_GUN;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN);
item->MeshBits = 0xFF81FFFF;
item->ItemFlags[2] = BADDY_USE_UZI;
}
else
{
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_SWORD_NINJA;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_NINJA);
item->MeshBits = ALL_JOINT_BITS;
item->ItemFlags[2] = 0;
}
@@ -645,7 +645,7 @@ namespace TEN::Entities::TR4
break;
}
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_SWORD_NINJA &&
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_NINJA) &&
item == Lara.TargetEntity &&
laraAI.ahead &&
laraAI.distance > pow(682, 2))
@@ -656,13 +656,14 @@ namespace TEN::Entities::TR4
if (Targetable(item, &AI) && item->ItemFlags[2] > 0)
{
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_GUN)
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN))
{
item->Animation.TargetState = BADDY_STATE_AIM;
break;
}
- if (item->MeshSwapBits != MESHSWAPFLAGS_BADDY_SWORD_SIMPLE && item->MeshSwapBits != MESHSWAPFLAGS_BADDY_SWORD_NINJA)
+ if (!item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_SIMPLE) &&
+ !item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_NINJA))
{
item->Animation.TargetState = BADDY_STATE_DRAW_GUN;
break;
@@ -711,7 +712,7 @@ namespace TEN::Entities::TR4
}
}
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_GUN && item->ItemFlags[2] < 1)
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN) && item->ItemFlags[2] < 1)
{
item->Animation.TargetState = BADDY_STATE_HOLSTER_GUN;
break;
@@ -722,13 +723,13 @@ namespace TEN::Entities::TR4
probe = GetCollision(item);
if (probe.Position.Ceiling == probe.Position.Floor - CLICK(6))
{
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_EMPTY)
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_EMPTY))
{
item->Animation.TargetState = BADDY_STATE_MONKEY_GRAB;
break;
}
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_GUN)
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN))
{
item->Animation.TargetState = BADDY_STATE_HOLSTER_GUN;
break;
@@ -754,7 +755,7 @@ namespace TEN::Entities::TR4
break;
}
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_EMPTY)
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_EMPTY))
{
item->Animation.TargetState = BADDY_STATE_DRAW_SWORD;
break;
@@ -765,7 +766,7 @@ namespace TEN::Entities::TR4
AI.distance < pow(SECTOR(0.5f), 2) &&
AI.verticalDistance < SECTOR(1))
{
- if (item->MeshSwapBits == MESHSWAPFLAGS_BADDY_GUN)
+ if (item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN))
item->Animation.TargetState = BADDY_STATE_HOLSTER_GUN;
else if (AI.distance >= pow(SECTOR(0.5f), 2))
item->Animation.TargetState = BADDY_STATE_SWORD_HIT_FRONT;
@@ -813,7 +814,8 @@ namespace TEN::Entities::TR4
if (item->ItemFlags[2] < 1)
{
- if (item->MeshSwapBits != MESHSWAPFLAGS_BADDY_SWORD_SIMPLE && item->MeshSwapBits != MESHSWAPFLAGS_BADDY_SWORD_NINJA)
+ if (!item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_SIMPLE) &&
+ !item->TestMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_NINJA))
{
item->Animation.TargetState = BADDY_STATE_IDLE;
break;
@@ -1170,19 +1172,19 @@ namespace TEN::Entities::TR4
case BADDY_STATE_HOLSTER_GUN:
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + FRAME_BADDY_HOLSTER_GUN)
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_EMPTY;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_EMPTY);
break;
case BADDY_STATE_DRAW_GUN:
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + FRAME_BADDY_DRAW_GUN)
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_GUN;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_GUN);
break;
case BADDY_STATE_HOLSTER_SWORD:
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + FRAME_BADDY_HOLSTER_SWORD)
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_EMPTY;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_EMPTY);
break;
@@ -1191,9 +1193,9 @@ namespace TEN::Entities::TR4
break;
if (item->ObjectNumber == ID_BADDY1)
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_SWORD_SIMPLE;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_SIMPLE);
else
- item->MeshSwapBits = MESHSWAPFLAGS_BADDY_SWORD_NINJA;
+ item->SetMeshSwapFlags(MESHSWAPFLAGS_BADDY_SWORD_NINJA);
break;
diff --git a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp
index d414ca67e..c5f540b35 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_guide.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_guide.cpp
@@ -100,7 +100,7 @@ namespace TEN::Entities::TR4
ClearItem(itemNumber);
SetAnimation(item, GUIDE_ANIM_IDLE);
- item->MeshSwapBits.Set(GuideRightHandSwapJoints);
+ item->SetMeshSwapFlags(GuideRightHandSwapJoints);
}
@@ -294,7 +294,7 @@ namespace TEN::Entities::TR4
{
if (!creature->ReachedGoal || foundEnemy)
{
- if (item->MeshSwapBits == 0x40000)
+ if (item->TestMeshSwapFlags(0x40000))
item->Animation.TargetState = GUIDE_STATE_WALK_FORWARD_NO_TORCH;
else if (foundEnemy && AI.distance < pow(SECTOR(1), 2))
{
@@ -420,7 +420,7 @@ namespace TEN::Entities::TR4
{
if (!foundEnemy ||
AI.distance >= pow(SECTOR(1.5f), 2) &&
- (item->MeshSwapBits.Test(GuideRightHandSwapJoints) || AI.distance >= pow(SECTOR(3), 2)))
+ (item->TestMeshSwapFlags(GuideRightHandSwapJoints) || AI.distance >= pow(SECTOR(3), 2)))
{
if (creature->Enemy->IsLara())
{
@@ -476,7 +476,7 @@ namespace TEN::Entities::TR4
}
else if (foundEnemy &&
(AI.distance < pow(SECTOR(1.5f), 2) ||
- !(item->MeshSwapBits.Test(GuideRightHandSwapJoints)) &&
+ !(item->TestMeshSwapFlags(GuideRightHandSwapJoints)) &&
AI.distance < pow(SECTOR(3), 2)))
{
item->Animation.TargetState = GUIDE_STATE_IDLE;
@@ -491,9 +491,9 @@ namespace TEN::Entities::TR4
random = GetRandomControl();
if (frameNumber == 32)
- item->MeshSwapBits.Set(GuideLeftFingerSwapJoints);
+ item->SetMeshSwapFlags(GuideLeftFingerSwapJoints);
else if (frameNumber == 216)
- item->MeshSwapBits.Clear(GuideLeftFingerSwapJoints);
+ item->SetMeshSwapFlags(GuideLeftFingerSwapJoints, true);
else if (frameNumber <= 79 || frameNumber >= 84)
{
if (frameNumber <= 83 || frameNumber >= 94)
@@ -663,7 +663,7 @@ namespace TEN::Entities::TR4
}
else if (item->Animation.FrameNumber == (g_Level.Anims[item->Animation.AnimNumber].frameBase + 35))
{
- item->MeshSwapBits.Clear(GuideRightHandSwapJoints);
+ item->SetMeshSwapFlags(GuideRightHandSwapJoints, true);
auto* room = &g_Level.Rooms[item->RoomNumber];
@@ -750,14 +750,14 @@ namespace TEN::Entities::TR4
flagScaryInscription)
{
item->Animation.RequiredState = GUIDE_STATE_RUN_FORWARD;
- item->MeshSwapBits.Set(GuideHeadSwapJoints);
+ item->SetMeshSwapFlags(GuideHeadSwapJoints);
SoundEffect(SFX_TR4_GUIDE_SCARE, &item->Pose);
}
if (item->Animation.FrameNumber == (g_Level.Anims[item->Animation.AnimNumber].frameBase + 185) &&
flagScaryInscription)
{
item->ItemFlags[2] &= ~(1 << 4); // Turn off 4th bit for flagScaryInscription.
- item->MeshSwapBits.Clear(GuideHeadSwapJoints);
+ item->SetMeshSwapFlags(GuideHeadSwapJoints, true);
}
}
else if ((enemy->Pose.Orientation.y - item->Pose.Orientation.y) <= ANGLE(2.0f))
diff --git a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
index ed6052443..3fc86a4ef 100644
--- a/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
+++ b/TombEngine/Objects/TR4/Entity/tr4_von_croy.cpp
@@ -142,7 +142,7 @@ namespace TEN::Entities::TR4
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.TargetState = VON_CROY_STATE_TOGGLE_KNIFE;
item->Animation.ActiveState = VON_CROY_STATE_TOGGLE_KNIFE;
- item->MeshSwapBits.Set(VonCroyKnifeSwapJoints);
+ item->SetMeshSwapFlags(VonCroyKnifeSwapJoints);
memset(VonCroyPassedWaypoints, 0, 128);
}
@@ -427,7 +427,7 @@ namespace TEN::Entities::TR4
probe = GetCollision(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, probe.RoomNumber);
if (probe.Position.Ceiling == (probe.Position.Floor - 1536))
{
- if (item->MeshSwapBits.Test(VonCroyKnifeSwapJoints))
+ if (item->TestMeshSwapFlags(VonCroyKnifeSwapJoints))
item->Animation.TargetState = VON_CROY_STATE_TOGGLE_KNIFE;
else
item->Animation.TargetState = VON_CROY_STATE_START_MONKEY;
@@ -502,7 +502,7 @@ namespace TEN::Entities::TR4
if (Lara.Location >= item->ItemFlags[3])
{
if (!foundTarget || AI.distance >= pow(SECTOR(1.5f), 2) &&
- (item->MeshSwapBits.Test(18) || AI.distance >= pow(SECTOR(3), 2)))
+ (item->TestMeshSwapFlags(18) || AI.distance >= pow(SECTOR(3), 2)))
{
if (creature->Enemy->IsLara())
{
@@ -627,10 +627,7 @@ namespace TEN::Entities::TR4
case VON_CROY_STATE_TOGGLE_KNIFE:
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase)
{
- if (!item->MeshSwapBits.Test(VonCroyKnifeSwapJoints))
- item->MeshSwapBits.Set(VonCroyKnifeSwapJoints);
- else
- item->MeshSwapBits.Clear(VonCroyKnifeSwapJoints);
+ item->SetMeshSwapFlags(VonCroyKnifeSwapJoints, item->TestMeshSwapFlags(VonCroyKnifeSwapJoints));
}
break;
diff --git a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
index d6b005e7f..ddbb31ba6 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_joby_spikes.cpp
@@ -16,8 +16,8 @@ namespace TEN::Entities::TR4
auto* item = &g_Level.Items[itemNumber];
// 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;
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i].Scale.y = 0.0f;
item->Pose.Orientation.y = GetRandomControl() * 1024;
item->ItemFlags[2] = GetRandomControl() & 1;
@@ -81,8 +81,8 @@ namespace TEN::Entities::TR4
// Update bone mutators.
if (item->ItemFlags[1])
{
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
- item->Animation.Mutator[i].Scale = Vector3(1.0f, item->ItemFlags[1] / 4096.0f, 1.0f);
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i].Scale = Vector3(1.0f, item->ItemFlags[1] / 4096.0f, 1.0f);
}
}
}
diff --git a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
index 434b23fde..6d0a112c2 100644
--- a/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
+++ b/TombEngine/Objects/TR4/Trap/tr4_teethspike.cpp
@@ -23,8 +23,8 @@ namespace TEN::Entities::TR4
auto* item = &g_Level.Items[itemNumber];
// Set mutators to 0 by default.
- for (size_t i = 0; i < item->Animation.Mutator.size(); i++)
- item->Animation.Mutator[i].Scale.y = 0.0f;
+ for (size_t i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i].Scale.y = 0.0f;
item->Status = ITEM_INVISIBLE;
item->ItemFlags[0] = 1024;
@@ -210,13 +210,13 @@ namespace TEN::Entities::TR4
}
// Update bone mutators.
- for (size_t i = 0; i < item->Animation.Mutator.size(); i++)
+ for (size_t i = 0; i < item->Model.Mutator.size(); i++)
{
float scale = (float)item->ItemFlags[1] / 4096.0f;
if (scale > 0.0f)
- item->Animation.Mutator[i].Scale = Vector3(1.0f, scale, 1.0f);
+ item->Model.Mutator[i].Scale = Vector3(1.0f, scale, 1.0f);
else
- item->Animation.Mutator[i].Scale = Vector3::Zero;
+ item->Model.Mutator[i].Scale = Vector3::Zero;
}
}
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
index 2aa85589e..bb8004419 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_cyborg.cpp
@@ -239,7 +239,7 @@ namespace TEN::Entities::Creatures::TR5
{
if (item->ItemFlags[0] < 11)
{
- item->MeshSwapBits |= 1 << HitmanJoints[item->ItemFlags[0]];
+ item->SetMeshSwapFlags(1 << HitmanJoints[item->ItemFlags[0]]);
item->ItemFlags[0]++;
}
}
diff --git a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
index 6d13a6c30..6f3a66c00 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_gladiator.cpp
@@ -77,7 +77,7 @@ namespace TEN::Entities::Creatures::TR5
SetAnimation(item, GLADIATOR_ANIM_IDLE);
if (item->TriggerFlags == 1)
- item->MeshSwapBits = ALL_JOINT_BITS;
+ item->SetMeshSwapFlags(ALL_JOINT_BITS);
}
void ControlGladiator(short itemNumber)
diff --git a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
index 100fcffb8..9f7a0c640 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_guard.cpp
@@ -127,7 +127,7 @@ namespace TEN::Entities::Creatures::TR5
case 3:
item->Animation.AnimNumber = anim + 28;
item->Animation.TargetState = GUARD_STATE_SIT;
- item->MeshSwapBits = 9216;
+ item->SetMeshSwapFlags(9216);
roomItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
if (roomItemNumber != NO_ITEM)
@@ -161,7 +161,7 @@ namespace TEN::Entities::Creatures::TR5
case 4:
item->Animation.AnimNumber = anim + 30;
item->Animation.TargetState = 17;
- item->MeshSwapBits = 8192;
+ item->SetMeshSwapFlags(8192);
break;
case 5:
@@ -708,7 +708,7 @@ namespace TEN::Entities::Creatures::TR5
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 44)
{
- item->MeshSwapBits = NO_JOINT_BITS;
+ item->SetMeshSwapFlags(NO_JOINT_BITS);
short currentItemNumber = g_Level.Rooms[item->RoomNumber].itemNumber;
if (currentItemNumber == NO_ITEM)
@@ -803,7 +803,7 @@ namespace TEN::Entities::Creatures::TR5
item->Pose.Position.x = currentItem->Pose.Position.x - CLICK(1);
item->Pose.Orientation.y = currentItem->Pose.Orientation.y;
item->Pose.Position.z = currentItem->Pose.Position.z + CLICK(0.5f);
- item->MeshSwapBits = 1024;
+ item->SetMeshSwapFlags(1024);
}
else
{
@@ -822,7 +822,7 @@ namespace TEN::Entities::Creatures::TR5
currentItem->MeshBits = 0x1FFF;
TestTriggers(item, true);
item->Animation.RequiredState = GUARD_STATE_WALK;
- item->MeshSwapBits = NO_JOINT_BITS;
+ item->SetMeshSwapFlags(NO_JOINT_BITS);
}
}
@@ -1085,7 +1085,7 @@ namespace TEN::Entities::Creatures::TR5
item->Animation.FrameNumber = g_Level.Anims[item->Animation.AnimNumber].frameBase;
item->Animation.TargetState = GUARD_STATE_IDLE;
item->Animation.ActiveState = GUARD_STATE_IDLE;
- item->MeshSwapBits = 9216;
+ item->SetMeshSwapFlags(9216);
}
void Mafia2Control(short itemNumber)
@@ -1210,13 +1210,13 @@ namespace TEN::Entities::Creatures::TR5
}
if (laraAI.angle <= ANGLE(112.5f) && laraAI.angle >= -ANGLE(112.5f))
{
- if (item->MeshSwapBits == 9216)
+ if (item->TestMeshSwapFlags(9216))
{
item->Animation.TargetState = MAFIA2_STATE_UNDRAW_GUNS;
break;
}
}
- else if (item->MeshSwapBits == 9216)
+ else if (item->TestMeshSwapFlags(9216))
{
item->Animation.TargetState = MAFIA2_STATE_TURN_180;
break;
@@ -1272,13 +1272,13 @@ namespace TEN::Entities::Creatures::TR5
item->Pose.Orientation.y += ANGLE(2.0f);
if (item->Animation.FrameNumber != g_Level.Anims[item->Animation.AnimNumber].frameBase + 16 ||
- item->MeshSwapBits != 9216)
+ !item->TestMeshSwapFlags(9216))
{
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameEnd)
item->Pose.Orientation.y += -ANGLE(180.0f);
}
else
- item->MeshSwapBits = 128;
+ item->SetMeshSwapFlags(128);
break;
@@ -1412,9 +1412,9 @@ namespace TEN::Entities::Creatures::TR5
item->Pose.Orientation.y -= ANGLE(2.0f);
if (item->Animation.FrameNumber == g_Level.Anims[item->Animation.AnimNumber].frameBase + 16 &&
- item->MeshSwapBits == 9216)
+ item->TestMeshSwapFlags(9216))
{
- item->MeshSwapBits = 128;
+ item->SetMeshSwapFlags(128);
}
break;
diff --git a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp
index dba29eb5f..0c72b0a69 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_imp.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_imp.cpp
@@ -171,9 +171,9 @@ namespace TEN::Entities::Creatures::TR5
joint3 = AI.angle / 2;
if (Wibble & 0x10)
- item->MeshSwapBits = 1024;
+ item->SetMeshSwapFlags(1024);
else
- item->MeshSwapBits = NO_JOINT_BITS;
+ item->SetMeshSwapFlags(NO_JOINT_BITS);
switch (item->Animation.ActiveState)
{
diff --git a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
index c8393cb21..10ff46095 100644
--- a/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
+++ b/TombEngine/Objects/TR5/Entity/tr5_roman_statue.cpp
@@ -311,37 +311,37 @@ namespace TEN::Entities::Creatures::TR5
auto* item = &g_Level.Items[itemNumber];
auto* creature = GetCreatureInfo(item);
- int prevMeshSwapBits = item->MeshSwapBits.ToPackedBits();
+ auto prevMeshSwapBits = item->Model.MeshIndex;
// At determined HP values, roman statues sheds material.
- if (item->HitPoints < 1 && !(item->MeshSwapBits & 0x10000))
+ if (item->HitPoints < 1 && !item->TestMeshSwapFlags(0x10000))
{
ExplodeItemNode(item, 16, 0, 8);
item->MeshBits |= 0x10000;
- item->MeshSwapBits |= 0x10000;
+ item->SetMeshSwapFlags(0x10000);
}
- else if (item->HitPoints < 75 && !(item->MeshSwapBits & 0x100))
+ else if (item->HitPoints < 75 && !item->TestMeshSwapFlags(0x100))
{
ExplodeItemNode(item, 8, 0, 8);
item->MeshBits |= 0x100;
- item->MeshSwapBits |= 0x100;
+ item->SetMeshSwapFlags(0x100);
}
- else if (item->HitPoints < 150 && !(item->MeshSwapBits & 0x400))
+ else if (item->HitPoints < 150 && !item->TestMeshSwapFlags(0x400))
{
ExplodeItemNode(item, 10, 0, 32);
ExplodeItemNode(item, 11, 0, 32);
item->MeshBits |= 0x400u;
- item->MeshSwapBits |= 0x400;
+ item->SetMeshSwapFlags(0x400);
}
- else if (item->HitPoints < 225 && !(item->MeshSwapBits & 0x10))
+ else if (item->HitPoints < 225 && !item->TestMeshSwapFlags(0x10))
{
ExplodeItemNode(item, 4, 0, 8);
item->MeshBits |= 0x10;
- item->MeshSwapBits |= 0x10;
+ item->SetMeshSwapFlags(0x10);
}
// Play hit animation.
- if (prevMeshSwapBits != item->MeshSwapBits.ToPackedBits())
+ if (prevMeshSwapBits != item->Model.MeshIndex)
{
item->Animation.TargetState = STATUE_STATE_HIT;
item->Animation.ActiveState = STATUE_STATE_HIT;
@@ -859,7 +859,7 @@ namespace TEN::Entities::Creatures::TR5
CreatureJoint(item, 1, joint1);
CreatureJoint(item, 2, joint2);
- if (item->MeshSwapBits & 0x400)
+ if (item->TestMeshSwapFlags(0x400))
{
auto pos = Vector3i(
(GetRandomControl() & 0x1F) - 16,
@@ -869,7 +869,7 @@ namespace TEN::Entities::Creatures::TR5
RomanStatueHitEffect(item, &pos, 10);
}
- if (item->MeshSwapBits & 0x10)
+ if (item->TestMeshSwapFlags(0x10))
{
auto pos = Vector3i(
-40,
@@ -879,7 +879,7 @@ namespace TEN::Entities::Creatures::TR5
RomanStatueHitEffect(item, &pos, 4);
}
- if (item->MeshSwapBits & 0x100)
+ if (item->TestMeshSwapFlags(0x100))
{
auto pos = Vector3i(
(GetRandomControl() & 0x3F) + 54,
diff --git a/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp b/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp
index d320b728c..f38622444 100644
--- a/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_expandingplatform.cpp
@@ -290,9 +290,9 @@ void ExpandingPlatformUpdateMutators(short itemNumber)
if (item->Pose.Orientation.y == ANGLE(180.0f)) zTranslate = -offset + width;
if (item->Pose.Orientation.y == ANGLE(270.0f)) zTranslate = width - offset;
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
{
- item->Animation.Mutator[i].Offset = Vector3(0, 0, zTranslate);
- item->Animation.Mutator[i].Scale = Vector3(1.0f, 1.0f, item->ItemFlags[1] / 4096.0f);
+ item->Model.Mutator[i].Offset = Vector3(0, 0, zTranslate);
+ item->Model.Mutator[i].Scale = Vector3(1.0f, 1.0f, item->ItemFlags[1] / 4096.0f);
}
}
diff --git a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
index 7dba1ca3c..8f3613678 100644
--- a/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
+++ b/TombEngine/Objects/TR5/Object/tr5_raisingblock.cpp
@@ -24,8 +24,8 @@ void InitialiseRaisingBlock(short itemNumber)
g_Level.Boxes[floor->Box].flags &= ~BLOCKED;
// Set mutators to 0 by default
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
- item->Animation.Mutator[i].Scale.y = 0;
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i].Scale.y = 0;
if (item->TriggerFlags < 0)
{
@@ -144,8 +144,8 @@ void ControlRaisingBlock(short itemNumber)
// Update bone mutators
if (item->TriggerFlags > -1)
{
- for (int i = 0; i < item->Animation.Mutator.size(); i++)
- item->Animation.Mutator[i].Scale = Vector3(1.0f, item->ItemFlags[1] / 4096.0f, 1.0f);
+ for (int i = 0; i < item->Model.Mutator.size(); i++)
+ item->Model.Mutator[i].Scale = Vector3(1.0f, item->ItemFlags[1] / 4096.0f, 1.0f);
}
}
diff --git a/TombEngine/Renderer/Renderer11.h b/TombEngine/Renderer/Renderer11.h
index 1f3a58f6b..05941bc30 100644
--- a/TombEngine/Renderer/Renderer11.h
+++ b/TombEngine/Renderer/Renderer11.h
@@ -108,19 +108,24 @@ namespace TEN::Renderer
{
int ItemNumber;
int ObjectNumber;
- bool DoneAnimations;
+
Vector3 Position;
Matrix World;
Matrix Translation;
Matrix Rotation;
Matrix Scale;
Matrix AnimationTransforms[MAX_BONES];
+
int RoomNumber = NO_ROOM;
int PrevRoomNumber = NO_ROOM;
Vector4 Color;
Vector4 AmbientLight;
std::vector LightsToDraw;
float LightFade;
+
+ std::vector MeshIndex;
+
+ bool DoneAnimations;
};
struct RendererMesh
diff --git a/TombEngine/Renderer/Renderer11Draw.cpp b/TombEngine/Renderer/Renderer11Draw.cpp
index e0bacd7c8..6c8528b65 100644
--- a/TombEngine/Renderer/Renderer11Draw.cpp
+++ b/TombEngine/Renderer/Renderer11Draw.cpp
@@ -69,7 +69,7 @@ namespace TEN::Renderer
if (!nativeItem.MeshBits.Test(sphereMeshes[i]))
continue;
- auto& mesh = g_Level.Meshes[Lara.MeshPtrs[sphereMeshes[i]]];
+ auto& mesh = g_Level.Meshes[nativeItem.Model.MeshIndex[sphereMeshes[i]]];
auto offset = Vector3i(mesh.sphere.Center.x, mesh.sphere.Center.y, mesh.sphere.Center.z);
// Push foot spheres a little lower.
@@ -225,7 +225,7 @@ namespace TEN::Renderer
for (int k = 0; k < skin.ObjectMeshes.size(); k++)
{
- auto* mesh = item->ObjectNumber == ID_LARA ? GetMesh(Lara.MeshPtrs[k]) : skin.ObjectMeshes[k];
+ auto* mesh = GetMesh(item->MeshIndex[k]);
for (auto& bucket : mesh->Buckets)
{
@@ -1711,7 +1711,6 @@ namespace TEN::Renderer
ItemInfo* nativeItem = &g_Level.Items[item->ItemNumber];
RendererRoom* room = &m_rooms[item->RoomNumber];
RendererObject& moveableObj = *m_moveableObjects[item->ObjectNumber];
- ObjectInfo* obj = &Objects[item->ObjectNumber];
// Bind item main properties
m_stItem.World = item->World;
@@ -1733,17 +1732,7 @@ namespace TEN::Renderer
if (!(nativeItem->MeshBits & (1 << k)))
continue;
- RendererMesh* mesh = moveableObj.ObjectMeshes[k];
-
- // Do the swapmesh
- if (obj->meshSwapSlot != -1 && m_moveableObjects[obj->meshSwapSlot].has_value() && ((nativeItem->MeshSwapBits.ToPackedBits() >> k) & 1))
- {
- RendererObject& swapMeshObj = *m_moveableObjects[obj->meshSwapSlot];
- if (swapMeshObj.ObjectMeshes.size() > k)
- mesh = swapMeshObj.ObjectMeshes[k];
- }
-
- DrawMoveableMesh(item, mesh, room, k, transparent);
+ DrawMoveableMesh(item, GetMesh(item->MeshIndex[k]), room, k, transparent);
}
}
diff --git a/TombEngine/Renderer/Renderer11Helper.cpp b/TombEngine/Renderer/Renderer11Helper.cpp
index 57171cd5f..9f095dbdf 100644
--- a/TombEngine/Renderer/Renderer11Helper.cpp
+++ b/TombEngine/Renderer/Renderer11Helper.cpp
@@ -120,11 +120,11 @@ namespace TEN::Renderer
{
auto* nativeItem = &g_Level.Items[item->ItemNumber];
- if (nativeItem->Animation.Mutator.size() == boneIndexList.size())
+ if (nativeItem->Model.Mutator.size() == boneIndexList.size())
{
for (int i : boneIndexList)
{
- auto mutator = nativeItem->Animation.Mutator[i];
+ auto mutator = nativeItem->Model.Mutator[i];
if (mutator.IsEmpty())
continue;
@@ -154,145 +154,147 @@ namespace TEN::Renderer
if (!force && itemToDraw->DoneAnimations)
return;
+ itemToDraw->DoneAnimations = true;
+
auto* obj = &Objects[nativeItem->ObjectNumber];
auto& moveableObj = *m_moveableObjects[nativeItem->ObjectNumber];
- // Update animation matrices
- if (obj->animIndex != -1 /*&& item->objectNumber != ID_HARPOON*/)
+ // Copy meshswaps
+ itemToDraw->MeshIndex = nativeItem->Model.MeshIndex;
+
+ if (obj->animIndex == -1)
+ return;
+
+ // Apply extra rotations
+ int lastJoint = 0;
+ for (int j = 0; j < moveableObj.LinearizedBones.size(); j++)
{
- // Apply extra rotations
- int lastJoint = 0;
- for (int j = 0; j < moveableObj.LinearizedBones.size(); j++)
- {
- auto* currentBone = moveableObj.LinearizedBones[j];
+ auto* currentBone = moveableObj.LinearizedBones[j];
- auto prevRotation = currentBone->ExtraRotation;
- currentBone->ExtraRotation = Vector3(0.0f, 0.0f, 0.0f);
+ auto prevRotation = currentBone->ExtraRotation;
+ currentBone->ExtraRotation = Vector3(0.0f, 0.0f, 0.0f);
- nativeItem->Data.apply(
- [&j, ¤tBone](QuadBikeInfo& quadBike)
+ nativeItem->Data.apply(
+ [&j, ¤tBone](QuadBikeInfo& quadBike)
+ {
+ if (j == 3 || j == 4)
+ currentBone->ExtraRotation.x = TO_RAD(quadBike.RearRot);
+ else if (j == 6 || j == 7)
{
- if (j == 3 || j == 4)
- currentBone->ExtraRotation.x = TO_RAD(quadBike.RearRot);
- else if (j == 6 || j == 7)
- {
- currentBone->ExtraRotation.x = TO_RAD(quadBike.FrontRot);
- currentBone->ExtraRotation.y = TO_RAD(quadBike.TurnRate * 2);
- }
- },
- [&j, ¤tBone](JeepInfo& jeep)
+ currentBone->ExtraRotation.x = TO_RAD(quadBike.FrontRot);
+ currentBone->ExtraRotation.y = TO_RAD(quadBike.TurnRate * 2);
+ }
+ },
+ [&j, ¤tBone](JeepInfo& jeep)
+ {
+ switch(j)
{
- switch(j)
- {
- case 9:
- currentBone->ExtraRotation.x = TO_RAD(jeep.FrontRightWheelRotation);
- currentBone->ExtraRotation.y = TO_RAD(jeep.TurnRate * 4);
- break;
+ case 9:
+ currentBone->ExtraRotation.x = TO_RAD(jeep.FrontRightWheelRotation);
+ currentBone->ExtraRotation.y = TO_RAD(jeep.TurnRate * 4);
+ break;
- case 10:
- currentBone->ExtraRotation.x = TO_RAD(jeep.FrontLeftWheelRotation);
- currentBone->ExtraRotation.y = TO_RAD(jeep.TurnRate * 4);
- break;
+ case 10:
+ currentBone->ExtraRotation.x = TO_RAD(jeep.FrontLeftWheelRotation);
+ currentBone->ExtraRotation.y = TO_RAD(jeep.TurnRate * 4);
+ break;
- case 12:
- currentBone->ExtraRotation.x = TO_RAD(jeep.BackRightWheelRotation);
- break;
+ case 12:
+ currentBone->ExtraRotation.x = TO_RAD(jeep.BackRightWheelRotation);
+ break;
- case 13:
- currentBone->ExtraRotation.x = TO_RAD(jeep.BackLeftWheelRotation);
- break;
- }
- },
- [&j, ¤tBone](MotorbikeInfo& bike)
+ case 13:
+ currentBone->ExtraRotation.x = TO_RAD(jeep.BackLeftWheelRotation);
+ break;
+ }
+ },
+ [&j, ¤tBone](MotorbikeInfo& bike)
+ {
+ switch (j)
{
- switch (j)
- {
- case 2:
- currentBone->ExtraRotation.x = TO_RAD(bike.RightWheelsRotation);
- currentBone->ExtraRotation.y = TO_RAD(bike.TurnRate * 8);
- break;
+ case 2:
+ currentBone->ExtraRotation.x = TO_RAD(bike.RightWheelsRotation);
+ currentBone->ExtraRotation.y = TO_RAD(bike.TurnRate * 8);
+ break;
- case 4:
- currentBone->ExtraRotation.x = TO_RAD(bike.RightWheelsRotation);
- break;
+ case 4:
+ currentBone->ExtraRotation.x = TO_RAD(bike.RightWheelsRotation);
+ break;
- case 8:
- currentBone->ExtraRotation.x = TO_RAD(bike.LeftWheelRotation);
- break;
- }
- },
- [&j, ¤tBone, &prevRotation](MinecartInfo& cart)
+ case 8:
+ currentBone->ExtraRotation.x = TO_RAD(bike.LeftWheelRotation);
+ break;
+ }
+ },
+ [&j, ¤tBone, &prevRotation](MinecartInfo& cart)
+ {
+ switch (j)
{
- switch (j)
- {
- case 1:
- case 2:
- case 3:
- case 4:
- currentBone->ExtraRotation.z = TO_RAD((short)std::clamp(cart.Velocity, 0, (int)ANGLE(25.0f)) + FROM_RAD(prevRotation.z));
- break;
- }
- },
- [&j, ¤tBone](RubberBoatInfo& boat)
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ currentBone->ExtraRotation.z = TO_RAD((short)std::clamp(cart.Velocity, 0, (int)ANGLE(25.0f)) + FROM_RAD(prevRotation.z));
+ break;
+ }
+ },
+ [&j, ¤tBone](RubberBoatInfo& boat)
+ {
+ if (j == 2)
+ currentBone->ExtraRotation.z = TO_RAD(boat.PropellerRotation);
+ },
+ [&j, ¤tBone](UPVInfo& upv)
+ {
+ switch (j)
{
- if (j == 2)
- currentBone->ExtraRotation.z = TO_RAD(boat.PropellerRotation);
- },
- [&j, ¤tBone](UPVInfo& upv)
+ case 1:
+ currentBone->ExtraRotation.x = TO_RAD(upv.LeftRudderRotation);
+ break;
+
+ case 2:
+ currentBone->ExtraRotation.x = TO_RAD(upv.RightRudderRotation);
+ break;
+
+ case 3:
+ currentBone->ExtraRotation.z = TO_RAD(upv.TurbineRotation);
+ break;
+ }
+ },
+ [&j, ¤tBone](BigGunInfo& big_gun)
+ {
+ if (j == 2)
+ currentBone->ExtraRotation.z = big_gun.BarrelRotation;
+ },
+ [&j, ¤tBone, &lastJoint](CreatureInfo& creature)
+ {
+ if (currentBone->ExtraRotationFlags & ROT_Y)
{
- switch (j)
- {
- case 1:
- currentBone->ExtraRotation.x = TO_RAD(upv.LeftRudderRotation);
- break;
+ currentBone->ExtraRotation.y = TO_RAD(creature.JointRotation[lastJoint]);
+ lastJoint++;
+ }
- case 2:
- currentBone->ExtraRotation.x = TO_RAD(upv.RightRudderRotation);
- break;
-
- case 3:
- currentBone->ExtraRotation.z = TO_RAD(upv.TurbineRotation);
- break;
- }
- },
- [&j, ¤tBone](BigGunInfo& big_gun)
+ if (currentBone->ExtraRotationFlags & ROT_X)
{
- if (j == 2)
- currentBone->ExtraRotation.z = big_gun.BarrelRotation;
- },
- [&j, ¤tBone, &lastJoint](CreatureInfo& creature)
+ currentBone->ExtraRotation.x = TO_RAD(creature.JointRotation[lastJoint]);
+ lastJoint++;
+ }
+
+ if (currentBone->ExtraRotationFlags & ROT_Z)
{
- if (currentBone->ExtraRotationFlags & ROT_Y)
- {
- currentBone->ExtraRotation.y = TO_RAD(creature.JointRotation[lastJoint]);
- lastJoint++;
- }
-
- if (currentBone->ExtraRotationFlags & ROT_X)
- {
- currentBone->ExtraRotation.x = TO_RAD(creature.JointRotation[lastJoint]);
- lastJoint++;
- }
-
- if (currentBone->ExtraRotationFlags & ROT_Z)
- {
- currentBone->ExtraRotation.z = TO_RAD(creature.JointRotation[lastJoint]);
- lastJoint++;
- }
- });
- }
-
- AnimFrame* framePtr[2];
- int rate;
- int frac = GetFrame(nativeItem, framePtr, rate);
-
- UpdateAnimation(itemToDraw, moveableObj, framePtr, frac, rate, UINT_MAX);
-
- for (int m = 0; m < obj->nmeshes; m++)
- itemToDraw->AnimationTransforms[m] = itemToDraw->AnimationTransforms[m];
+ currentBone->ExtraRotation.z = TO_RAD(creature.JointRotation[lastJoint]);
+ lastJoint++;
+ }
+ });
}
- itemToDraw->DoneAnimations = true;
+ AnimFrame* framePtr[2];
+ int rate;
+ int frac = GetFrame(nativeItem, framePtr, rate);
+
+ UpdateAnimation(itemToDraw, moveableObj, framePtr, frac, rate, UINT_MAX);
+
+ for (int m = 0; m < obj->nmeshes; m++)
+ itemToDraw->AnimationTransforms[m] = itemToDraw->AnimationTransforms[m];
}
void Renderer11::UpdateItemAnimations(RenderView& view)
diff --git a/TombEngine/Renderer/Renderer11Lara.cpp b/TombEngine/Renderer/Renderer11Lara.cpp
index eb11b900a..045cd5883 100644
--- a/TombEngine/Renderer/Renderer11Lara.cpp
+++ b/TombEngine/Renderer/Renderer11Lara.cpp
@@ -244,7 +244,9 @@ void Renderer11::UpdateLaraAnimations(bool force)
for (int m = 0; m < 15; m++)
laraObj.AnimationTransforms[m] = item->AnimationTransforms[m];
- m_items[Lara.ItemNumber].DoneAnimations = true;
+ // Copy meshswap indices
+ item->MeshIndex = LaraItem->Model.MeshIndex;
+ item->DoneAnimations = true;
}
void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent)
@@ -287,7 +289,7 @@ void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent)
m_stItem.AmbientLight = item->AmbientLight;
memcpy(m_stItem.BonesMatrices, laraObj.AnimationTransforms.data(), sizeof(Matrix) * MAX_BONES);
for (int k = 0; k < laraSkin.ObjectMeshes.size(); k++)
- m_stItem.BoneLightModes[k] = GetMesh(Lara.MeshPtrs[k])->LightMode;
+ m_stItem.BoneLightModes[k] = GetMesh(nativeItem->Model.MeshIndex[k])->LightMode;
m_cbItem.updateData(m_stItem, m_context.Get());
BindConstantBufferVS(CB_ITEM, m_cbItem.get());
@@ -300,8 +302,7 @@ void TEN::Renderer::Renderer11::DrawLara(RenderView& view, bool transparent)
if (!nativeItem->MeshBits.Test(k))
continue;
- RendererMesh *mesh = GetMesh(Lara.MeshPtrs[k]);
- DrawMoveableMesh(item, mesh, room, k, transparent);
+ DrawMoveableMesh(item, GetMesh(nativeItem->Model.MeshIndex[k]), room, k, transparent);
}
DrawLaraHolsters(transparent);
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index 18d36c20b..e89a5007b 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -822,7 +822,7 @@ bool Moveable::MeshIsSwapped(int meshId) const
if (!MeshExists(meshId))
return false;
- return m_item->MeshSwapBits.Test(meshId);
+ return m_item->Model.MeshIndex[meshId] == m_item->Model.BaseMesh + meshId;
}
void Moveable::SwapMesh(int meshId, int swapSlotId, sol::optional swapMeshIndex)
@@ -833,32 +833,26 @@ void Moveable::SwapMesh(int meshId, int swapSlotId, sol::optional swapMeshI
if (!swapMeshIndex.has_value())
swapMeshIndex = meshId;
- // TODO: After beta, we should refactor whole meshswap workflow,
- // because currently Lara and other objects use different convention -- Lwmte, 09.07.22
- if (m_item->IsLara())
+ if (swapSlotId <= -1 || swapSlotId >= ID_NUMBER_OBJECTS)
{
- if (swapSlotId <= -1)
- return;
-
- auto* lara = GetLaraInfo(m_item);
-
- if (swapSlotId >= ID_NUMBER_OBJECTS || !Objects[swapSlotId].loaded)
- {
- TENLog("Specified slot does not exist in level!", LogLevel::Error);
- return;
- }
-
- if (swapMeshIndex.value() >= Objects[swapSlotId].nmeshes)
- {
- TENLog("Specified meshswap index does not exist in meshswap slot!", LogLevel::Error);
- return;
- }
-
- lara->MeshPtrs[meshId] = Objects[swapSlotId].meshIndex + swapMeshIndex.value();
+ TENLog("Specified meshswap slot ID is incorrect!", LogLevel::Error);
+ return;
}
- else
- m_item->MeshSwapBits.Set(meshId);
+
+ if (!Objects[swapSlotId].loaded)
+ {
+ TENLog("Object in specified meshswap slot doesn't exist in level!", LogLevel::Error);
+ return;
+ }
+
+ if (swapMeshIndex.value() >= Objects[swapSlotId].nmeshes)
+ {
+ TENLog("Specified meshswap index does not exist in meshswap slot!", LogLevel::Error);
+ return;
+ }
+
+ m_item->Model.MeshIndex[meshId] = Objects[swapSlotId].meshIndex + swapMeshIndex.value();
}
void Moveable::UnswapMesh(int meshId)
@@ -866,20 +860,7 @@ void Moveable::UnswapMesh(int meshId)
if (!MeshExists(meshId))
return;
- if (m_item->IsLara())
- {
- auto* lara = GetLaraInfo(m_item);
-
- if (meshId >= NUM_LARA_MESHES)
- {
- TENLog("Specified mesh index does not exist!", LogLevel::Error);
- return;
- }
-
- lara->MeshPtrs[meshId] = Objects[ID_LARA_SKIN].meshIndex + meshId;
- }
- else
- m_item->MeshSwapBits.Clear(meshId);
+ m_item->Model.MeshIndex[meshId] = m_item->Model.BaseMesh + meshId;
}
void Moveable::EnableItem()
diff --git a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h
index 14be600e6..80144bcdf 100644
--- a/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h
+++ b/TombEngine/Specific/savegame/flatbuffers/ten_savegame_generated.h
@@ -450,8 +450,9 @@ struct ItemT : public flatbuffers::NativeTable {
bool collidable = false;
bool looked_at = false;
int32_t ai_bits = 0;
- int32_t swap_mesh_flags = 0;
TEN::Save::ItemDataUnion data{};
+ int32_t base_mesh = 0;
+ std::vector mesh_pointers{};
std::string lua_name{};
std::string lua_on_killed_name{};
std::string lua_on_hit_name{};
@@ -495,14 +496,15 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_COLLIDABLE = 60,
VT_LOOKED_AT = 62,
VT_AI_BITS = 64,
- VT_SWAP_MESH_FLAGS = 66,
- VT_DATA_TYPE = 68,
- VT_DATA = 70,
- VT_LUA_NAME = 72,
- VT_LUA_ON_KILLED_NAME = 74,
- VT_LUA_ON_HIT_NAME = 76,
- VT_LUA_ON_COLLIDED_WITH_OBJECT_NAME = 78,
- VT_LUA_ON_COLLIDED_WITH_ROOM_NAME = 80
+ VT_DATA_TYPE = 66,
+ VT_DATA = 68,
+ VT_BASE_MESH = 70,
+ VT_MESH_POINTERS = 72,
+ VT_LUA_NAME = 74,
+ VT_LUA_ON_KILLED_NAME = 76,
+ VT_LUA_ON_HIT_NAME = 78,
+ VT_LUA_ON_COLLIDED_WITH_OBJECT_NAME = 80,
+ VT_LUA_ON_COLLIDED_WITH_ROOM_NAME = 82
};
int32_t active_state() const {
return GetField(VT_ACTIVE_STATE, 0);
@@ -597,9 +599,6 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t ai_bits() const {
return GetField(VT_AI_BITS, 0);
}
- int32_t swap_mesh_flags() const {
- return GetField(VT_SWAP_MESH_FLAGS, 0);
- }
TEN::Save::ItemData data_type() const {
return static_cast(GetField(VT_DATA_TYPE, 0));
}
@@ -673,6 +672,12 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const TEN::Save::Minecart *data_as_Minecart() const {
return data_type() == TEN::Save::ItemData::Minecart ? static_cast(data()) : nullptr;
}
+ int32_t base_mesh() const {
+ return GetField(VT_BASE_MESH, 0);
+ }
+ const flatbuffers::Vector *mesh_pointers() const {
+ return GetPointer *>(VT_MESH_POINTERS);
+ }
const flatbuffers::String *lua_name() const {
return GetPointer(VT_LUA_NAME);
}
@@ -722,10 +727,12 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField(verifier, VT_COLLIDABLE) &&
VerifyField(verifier, VT_LOOKED_AT) &&
VerifyField(verifier, VT_AI_BITS) &&
- VerifyField(verifier, VT_SWAP_MESH_FLAGS) &&
VerifyField(verifier, VT_DATA_TYPE) &&
VerifyOffset(verifier, VT_DATA) &&
VerifyItemData(verifier, data(), data_type()) &&
+ VerifyField(verifier, VT_BASE_MESH) &&
+ VerifyOffset(verifier, VT_MESH_POINTERS) &&
+ verifier.VerifyVector(mesh_pointers()) &&
VerifyOffset(verifier, VT_LUA_NAME) &&
verifier.VerifyString(lua_name()) &&
VerifyOffset(verifier, VT_LUA_ON_KILLED_NAME) &&
@@ -928,15 +935,18 @@ struct ItemBuilder {
void add_ai_bits(int32_t ai_bits) {
fbb_.AddElement(Item::VT_AI_BITS, ai_bits, 0);
}
- void add_swap_mesh_flags(int32_t swap_mesh_flags) {
- fbb_.AddElement(Item::VT_SWAP_MESH_FLAGS, swap_mesh_flags, 0);
- }
void add_data_type(TEN::Save::ItemData data_type) {
fbb_.AddElement(Item::VT_DATA_TYPE, static_cast(data_type), 0);
}
void add_data(flatbuffers::Offset data) {
fbb_.AddOffset(Item::VT_DATA, data);
}
+ void add_base_mesh(int32_t base_mesh) {
+ fbb_.AddElement(Item::VT_BASE_MESH, base_mesh, 0);
+ }
+ void add_mesh_pointers(flatbuffers::Offset> mesh_pointers) {
+ fbb_.AddOffset(Item::VT_MESH_POINTERS, mesh_pointers);
+ }
void add_lua_name(flatbuffers::Offset lua_name) {
fbb_.AddOffset(Item::VT_LUA_NAME, lua_name);
}
@@ -996,9 +1006,10 @@ inline flatbuffers::Offset- CreateItem(
bool collidable = false,
bool looked_at = false,
int32_t ai_bits = 0,
- int32_t swap_mesh_flags = 0,
TEN::Save::ItemData data_type = TEN::Save::ItemData::NONE,
flatbuffers::Offset data = 0,
+ int32_t base_mesh = 0,
+ flatbuffers::Offset> mesh_pointers = 0,
flatbuffers::Offset lua_name = 0,
flatbuffers::Offset lua_on_killed_name = 0,
flatbuffers::Offset lua_on_hit_name = 0,
@@ -1010,8 +1021,9 @@ inline flatbuffers::Offset
- CreateItem(
builder_.add_lua_on_hit_name(lua_on_hit_name);
builder_.add_lua_on_killed_name(lua_on_killed_name);
builder_.add_lua_name(lua_name);
+ builder_.add_mesh_pointers(mesh_pointers);
+ builder_.add_base_mesh(base_mesh);
builder_.add_data(data);
- builder_.add_swap_mesh_flags(swap_mesh_flags);
builder_.add_ai_bits(ai_bits);
builder_.add_status(status);
builder_.add_next_item_active(next_item_active);
@@ -1085,15 +1097,17 @@ inline flatbuffers::Offset
- CreateItemDirect(
bool collidable = false,
bool looked_at = false,
int32_t ai_bits = 0,
- int32_t swap_mesh_flags = 0,
TEN::Save::ItemData data_type = TEN::Save::ItemData::NONE,
flatbuffers::Offset data = 0,
+ int32_t base_mesh = 0,
+ const std::vector *mesh_pointers = nullptr,
const char *lua_name = nullptr,
const char *lua_on_killed_name = nullptr,
const char *lua_on_hit_name = nullptr,
const char *lua_on_collided_with_object_name = nullptr,
const char *lua_on_collided_with_room_name = nullptr) {
auto item_flags__ = item_flags ? _fbb.CreateVector(*item_flags) : 0;
+ auto mesh_pointers__ = mesh_pointers ? _fbb.CreateVector(*mesh_pointers) : 0;
auto lua_name__ = lua_name ? _fbb.CreateString(lua_name) : 0;
auto lua_on_killed_name__ = lua_on_killed_name ? _fbb.CreateString(lua_on_killed_name) : 0;
auto lua_on_hit_name__ = lua_on_hit_name ? _fbb.CreateString(lua_on_hit_name) : 0;
@@ -1132,9 +1146,10 @@ inline flatbuffers::Offset
- CreateItemDirect(
collidable,
looked_at,
ai_bits,
- swap_mesh_flags,
data_type,
data,
+ base_mesh,
+ mesh_pointers__,
lua_name__,
lua_on_killed_name__,
lua_on_hit_name__,
@@ -3338,7 +3353,6 @@ struct LaraT : public flatbuffers::NativeTable {
int32_t burn_blue = 0;
bool burn_smoke = false;
std::vector wet{};
- std::vector mesh_ptrs{};
int32_t location = 0;
int32_t highest_location = 0;
int32_t location_pad = 0;
@@ -3381,10 +3395,9 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VT_BURN_BLUE = 62,
VT_BURN_SMOKE = 64,
VT_WET = 66,
- VT_MESH_PTRS = 68,
- VT_LOCATION = 70,
- VT_HIGHEST_LOCATION = 72,
- VT_LOCATION_PAD = 74
+ VT_LOCATION = 68,
+ VT_HIGHEST_LOCATION = 70,
+ VT_LOCATION_PAD = 72
};
int32_t item_number() const {
return GetField(VT_ITEM_NUMBER, 0);
@@ -3482,9 +3495,6 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::Vector *wet() const {
return GetPointer *>(VT_WET);
}
- const flatbuffers::Vector *mesh_ptrs() const {
- return GetPointer *>(VT_MESH_PTRS);
- }
int32_t location() const {
return GetField(VT_LOCATION, 0);
}
@@ -3538,8 +3548,6 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField(verifier, VT_BURN_SMOKE) &&
VerifyOffset(verifier, VT_WET) &&
verifier.VerifyVector(wet()) &&
- VerifyOffset(verifier, VT_MESH_PTRS) &&
- verifier.VerifyVector(mesh_ptrs()) &&
VerifyField(verifier, VT_LOCATION) &&
VerifyField(verifier, VT_HIGHEST_LOCATION) &&
VerifyField(verifier, VT_LOCATION_PAD) &&
@@ -3650,9 +3658,6 @@ struct LaraBuilder {
void add_wet(flatbuffers::Offset> wet) {
fbb_.AddOffset(Lara::VT_WET, wet);
}
- void add_mesh_ptrs(flatbuffers::Offset> mesh_ptrs) {
- fbb_.AddOffset(Lara::VT_MESH_PTRS, mesh_ptrs);
- }
void add_location(int32_t location) {
fbb_.AddElement(Lara::VT_LOCATION, location, 0);
}
@@ -3707,7 +3712,6 @@ inline flatbuffers::Offset CreateLara(
int32_t burn_blue = 0,
bool burn_smoke = false,
flatbuffers::Offset> wet = 0,
- flatbuffers::Offset> mesh_ptrs = 0,
int32_t location = 0,
int32_t highest_location = 0,
int32_t location_pad = 0) {
@@ -3715,7 +3719,6 @@ inline flatbuffers::Offset CreateLara(
builder_.add_location_pad(location_pad);
builder_.add_highest_location(highest_location);
builder_.add_location(location);
- builder_.add_mesh_ptrs(mesh_ptrs);
builder_.add_wet(wet);
builder_.add_burn_blue(burn_blue);
builder_.add_burn_count(burn_count);
@@ -3790,14 +3793,12 @@ inline flatbuffers::Offset CreateLaraDirect(
int32_t burn_blue = 0,
bool burn_smoke = false,
const std::vector *wet = nullptr,
- const std::vector *mesh_ptrs = nullptr,
int32_t location = 0,
int32_t highest_location = 0,
int32_t location_pad = 0) {
auto weapons__ = weapons ? _fbb.CreateVector>(*weapons) : 0;
auto target_arm_angles__ = target_arm_angles ? _fbb.CreateVector(*target_arm_angles) : 0;
auto wet__ = wet ? _fbb.CreateVector(*wet) : 0;
- auto mesh_ptrs__ = mesh_ptrs ? _fbb.CreateVector(*mesh_ptrs) : 0;
return TEN::Save::CreateLara(
_fbb,
item_number,
@@ -3832,7 +3833,6 @@ inline flatbuffers::Offset CreateLaraDirect(
burn_blue,
burn_smoke,
wet__,
- mesh_ptrs__,
location,
highest_location,
location_pad);
@@ -6652,9 +6652,10 @@ inline void Item::UnPackTo(ItemT *_o, const flatbuffers::resolver_function_t *_r
{ auto _e = collidable(); _o->collidable = _e; }
{ auto _e = looked_at(); _o->looked_at = _e; }
{ auto _e = ai_bits(); _o->ai_bits = _e; }
- { auto _e = swap_mesh_flags(); _o->swap_mesh_flags = _e; }
{ auto _e = data_type(); _o->data.type = _e; }
{ auto _e = data(); if (_e) _o->data.value = TEN::Save::ItemDataUnion::UnPack(_e, data_type(), _resolver); }
+ { auto _e = base_mesh(); _o->base_mesh = _e; }
+ { auto _e = mesh_pointers(); if (_e) { _o->mesh_pointers.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->mesh_pointers[_i] = _e->Get(_i); } } }
{ auto _e = lua_name(); if (_e) _o->lua_name = _e->str(); }
{ auto _e = lua_on_killed_name(); if (_e) _o->lua_on_killed_name = _e->str(); }
{ auto _e = lua_on_hit_name(); if (_e) _o->lua_on_hit_name = _e->str(); }
@@ -6701,9 +6702,10 @@ inline flatbuffers::Offset
- CreateItem(flatbuffers::FlatBufferBuilder &_fbb
auto _collidable = _o->collidable;
auto _looked_at = _o->looked_at;
auto _ai_bits = _o->ai_bits;
- auto _swap_mesh_flags = _o->swap_mesh_flags;
auto _data_type = _o->data.type;
auto _data = _o->data.Pack(_fbb);
+ auto _base_mesh = _o->base_mesh;
+ auto _mesh_pointers = _fbb.CreateVector(_o->mesh_pointers);
auto _lua_name = _o->lua_name.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->lua_name);
auto _lua_on_killed_name = _o->lua_on_killed_name.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->lua_on_killed_name);
auto _lua_on_hit_name = _o->lua_on_hit_name.empty() ? _fbb.CreateSharedString("") : _fbb.CreateString(_o->lua_on_hit_name);
@@ -6742,9 +6744,10 @@ inline flatbuffers::Offset
- CreateItem(flatbuffers::FlatBufferBuilder &_fbb
_collidable,
_looked_at,
_ai_bits,
- _swap_mesh_flags,
_data_type,
_data,
+ _base_mesh,
+ _mesh_pointers,
_lua_name,
_lua_on_killed_name,
_lua_on_hit_name,
@@ -7504,7 +7507,6 @@ inline void Lara::UnPackTo(LaraT *_o, const flatbuffers::resolver_function_t *_r
{ auto _e = burn_blue(); _o->burn_blue = _e; }
{ auto _e = burn_smoke(); _o->burn_smoke = _e; }
{ auto _e = wet(); if (_e) { _o->wet.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->wet[_i] = _e->Get(_i) != 0; } } }
- { auto _e = mesh_ptrs(); if (_e) { _o->mesh_ptrs.resize(_e->size()); for (flatbuffers::uoffset_t _i = 0; _i < _e->size(); _i++) { _o->mesh_ptrs[_i] = _e->Get(_i); } } }
{ auto _e = location(); _o->location = _e; }
{ auto _e = highest_location(); _o->highest_location = _e; }
{ auto _e = location_pad(); _o->location_pad = _e; }
@@ -7550,7 +7552,6 @@ inline flatbuffers::Offset CreateLara(flatbuffers::FlatBufferBuilder &_fbb
auto _burn_blue = _o->burn_blue;
auto _burn_smoke = _o->burn_smoke;
auto _wet = _fbb.CreateVector(_o->wet);
- auto _mesh_ptrs = _fbb.CreateVector(_o->mesh_ptrs);
auto _location = _o->location;
auto _highest_location = _o->highest_location;
auto _location_pad = _o->location_pad;
@@ -7588,7 +7589,6 @@ inline flatbuffers::Offset CreateLara(flatbuffers::FlatBufferBuilder &_fbb
_burn_blue,
_burn_smoke,
_wet,
- _mesh_ptrs,
_location,
_highest_location,
_location_pad);
diff --git a/TombEngine/Specific/savegame/schema/ten_savegame.fbs b/TombEngine/Specific/savegame/schema/ten_savegame.fbs
index d734b53f2..d56d0afda 100644
--- a/TombEngine/Specific/savegame/schema/ten_savegame.fbs
+++ b/TombEngine/Specific/savegame/schema/ten_savegame.fbs
@@ -39,8 +39,11 @@ table Item {
collidable: bool;
looked_at: bool;
ai_bits: int32;
- swap_mesh_flags: int32;
data: TEN.Save.ItemData;
+
+ base_mesh: int32;
+ mesh_pointers: [int32];
+
lua_name: string;
lua_on_killed_name: string;
lua_on_hit_name: string;
@@ -255,7 +258,6 @@ table Lara {
burn_blue: int32;
burn_smoke: bool;
wet: [bool];
- mesh_ptrs: [int32];
location: int32;
highest_location: int32;
location_pad: int32;
From 5b126dbc8bfca1d2171cdda6d9f656dc5ae41f16 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Fri, 11 Nov 2022 13:48:54 +0200
Subject: [PATCH 04/13] Update Changes.txt
---
Documentation/Changes.txt | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index 7319c9133..aab61d750 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -3,6 +3,7 @@ Version 1.0.3
* Add ledge jumps (Lara object must be updated with new animations to make it work).
* Add FlipMap and PlayFlyBy script commands and node functions.
+* Allow any object slot to be used as meshswap for other object slots than Lara.
* Add FlyCheat option to gameflow script for disabling dozy mode.
* Add SetNumberOfSecrets option to gameflow script to set overall amount of secrets.
* Add OCB 1 for rollingball to make it silent.
From d64047434a55840e7b14bdf8ef9f6ec3a9aced71 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sat, 12 Nov 2022 13:08:30 +0200
Subject: [PATCH 05/13] Fix going into inventory and load/save dialogs during
fade-ins and fade-outs
---
Documentation/Changes.txt | 1 +
TombEngine/Game/control/control.cpp | 4 ++--
TombEngine/Renderer/Renderer11Enums.h | 3 ---
3 files changed, 3 insertions(+), 5 deletions(-)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index aab61d750..a448885d1 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -15,6 +15,7 @@ Version 1.0.3
* Increase amount of maximum secrets per level from 8 to 32.
* Improve game and inventory input handling.
* Adjust sprint jump timing.
+* Fix going into inventory and load/save dialogs during fade-ins and fade-outs.
* Fix dodgy weapon lock angle constraints.
* Fix wrong shotgun ammo pickup amount.
* Fix shotgun using 6 units of ammo with each shot.
diff --git a/TombEngine/Game/control/control.cpp b/TombEngine/Game/control/control.cpp
index e3f8f8502..0600fd176 100644
--- a/TombEngine/Game/control/control.cpp
+++ b/TombEngine/Game/control/control.cpp
@@ -135,7 +135,7 @@ GameStatus ControlPhase(int numFrames, bool demoMode)
// which assumes 30 iterations per second.
g_GameScript->OnControlPhase(DELTA_TIME);
- if (CurrentLevel != 0)
+ if (CurrentLevel != 0 && !ScreenFading)
{
// Does the player want to enter inventory?
if (IsClicked(In::Save) && LaraItem->HitPoints > 0 &&
@@ -161,7 +161,7 @@ GameStatus ControlPhase(int numFrames, bool demoMode)
return GameStatus::LoadGame;
}
else if (IsClicked(In::Pause) && LaraItem->HitPoints > 0 &&
- g_Gui.GetInventoryMode() != InventoryMode::Pause)
+ g_Gui.GetInventoryMode() != InventoryMode::Pause)
{
StopAllSounds();
StopRumble();
diff --git a/TombEngine/Renderer/Renderer11Enums.h b/TombEngine/Renderer/Renderer11Enums.h
index c8b5be151..b5a0055bc 100644
--- a/TombEngine/Renderer/Renderer11Enums.h
+++ b/TombEngine/Renderer/Renderer11Enums.h
@@ -210,9 +210,6 @@ constexpr auto TEXTURE_PAGE = (TEXTURE_HEIGHT * TEXTURE_WIDTH);
#define NUM_SPRITES_PER_BUCKET 4096
#define NUM_LINES_PER_BUCKET 4096
#define NUM_CAUSTICS_TEXTURES 16
-#define FADEMODE_NONE 0
-#define FADEMODE_FADEIN 1
-#define FADEMODE_FADEOUT 2
#define PRINTSTRING_CENTER 1
#define PRINTSTRING_BLINK 2
#define PRINTSTRING_OUTLINE 8
From d8dbbdf110f289a37b5f26e02a2bad6fcd167978 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 00:34:03 +0200
Subject: [PATCH 06/13] Fix incorrect population of mesh list in renderer
---
TombEngine/Game/items.cpp | 2 +-
TombEngine/Renderer/Renderer11Compatibility.cpp | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 0e4060cd4..857e0c32f 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -526,7 +526,7 @@ void InitialiseItem(short itemNumber)
item->Model.MeshIndex.clear();
}
- if (Objects[item->ObjectNumber].initialise != NULL)
+ if (Objects[item->ObjectNumber].initialise != nullptr)
Objects[item->ObjectNumber].initialise(itemNumber);
}
diff --git a/TombEngine/Renderer/Renderer11Compatibility.cpp b/TombEngine/Renderer/Renderer11Compatibility.cpp
index 4ee2c3eab..fad49091c 100644
--- a/TombEngine/Renderer/Renderer11Compatibility.cpp
+++ b/TombEngine/Renderer/Renderer11Compatibility.cpp
@@ -395,6 +395,7 @@ namespace TEN::Renderer
j, MoveablesIds[i] == ID_LARA_SKIN_JOINTS,
MoveablesIds[i] == ID_HAIR, &lastVertex, &lastIndex);
moveable.ObjectMeshes.push_back(mesh);
+ m_meshes.push_back(mesh);
}
if (objNum == ID_IMP_ROCK || objNum == ID_ENERGY_BUBBLES || objNum == ID_BUBBLES || objNum == ID_BODY_PART)
@@ -678,6 +679,7 @@ namespace TEN::Renderer
RendererMesh *mesh = GetRendererMeshFromTrMesh(&staticObject, &g_Level.Meshes[obj->meshNumber], 0, false, false, &lastVertex, &lastIndex);
staticObject.ObjectMeshes.push_back(mesh);
+ m_meshes.push_back(mesh);
m_staticObjects[StaticObjectsIds[i]] = staticObject;
}
@@ -857,8 +859,6 @@ namespace TEN::Renderer
mesh->Buckets.push_back(bucket);
}
- m_meshes.push_back(mesh);
-
return mesh;
}
}
From d4c58a9a89d16efc1413f6be851393823d141540 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 00:53:14 +0200
Subject: [PATCH 07/13] Update Changes.txt
---
Documentation/Changes.txt | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index a448885d1..46237034f 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -3,7 +3,7 @@ Version 1.0.3
* Add ledge jumps (Lara object must be updated with new animations to make it work).
* Add FlipMap and PlayFlyBy script commands and node functions.
-* Allow any object slot to be used as meshswap for other object slots than Lara.
+* Allow any object slot to be used as a meshswap.
* Add FlyCheat option to gameflow script for disabling dozy mode.
* Add SetNumberOfSecrets option to gameflow script to set overall amount of secrets.
* Add OCB 1 for rollingball to make it silent.
@@ -37,6 +37,7 @@ Version 1.0.3
* Fix potential crashes when exiting game.
* Fix secret soundtrack (which filename number should be the last) not playing.
* Fix distance fog not applying properly to additive and subtractive surfaces.
+* Fix swarm enemies and projectiles occasionally drawn using incorrect meshes.
* Fix single-hand weapons not having a sound on draw and undraw.
* Fix waterfall mist - it can now be disabled with antitrigger.
* Fix underwater lever pull animation playing after interacting with underwater ceiling switch.
From ad719fdf301507122f9c0b79ebf4ccbd057f65eb Mon Sep 17 00:00:00 2001
From: Anatoly <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:46:12 +0200
Subject: [PATCH 08/13] Simple Lua callback refactor (#829)
---
TombEngine/Game/Lara/lara_fire.cpp | 6 ++---
TombEngine/Game/control/los.cpp | 6 ++---
TombEngine/Game/control/volume.h | 2 +-
TombEngine/Game/items.cpp | 18 ++++++-------
TombEngine/Game/items.h | 18 ++++++++-----
TombEngine/Game/savegame.cpp | 24 ++++++++---------
TombEngine/Objects/Sink.h | 2 +-
.../TEN/Objects/Camera/CameraObject.cpp | 6 ++---
.../TEN/Objects/Moveable/MoveableObject.cpp | 26 +++++++++----------
.../Internal/TEN/Objects/ObjectsHandler.cpp | 8 +++---
.../Internal/TEN/Objects/ObjectsHandler.h | 6 ++---
.../Internal/TEN/Objects/Sink/SinkObject.cpp | 6 ++---
.../Objects/SoundSource/SoundSourceObject.cpp | 6 ++---
TombEngine/Sound/sound.h | 2 +-
TombEngine/Specific/LevelCameraInfo.h | 2 +-
TombEngine/Specific/level.cpp | 18 ++++++-------
16 files changed, 80 insertions(+), 76 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_fire.cpp b/TombEngine/Game/Lara/lara_fire.cpp
index 36f38380a..c382355dd 100644
--- a/TombEngine/Game/Lara/lara_fire.cpp
+++ b/TombEngine/Game/Lara/lara_fire.cpp
@@ -1148,10 +1148,10 @@ void HitTarget(ItemInfo* laraItem, ItemInfo* targetEntity, GameVector* hitPos, i
}
}
- if (!targetEntity->LuaCallbackOnHitName.empty())
+ if (!targetEntity->Callbacks.OnHit.empty())
{
- short index = g_GameScriptEntities->GetIndexByName(targetEntity->LuaName);
- g_GameScript->ExecuteFunction(targetEntity->LuaCallbackOnHitName, index);
+ short index = g_GameScriptEntities->GetIndexByName(targetEntity->Name);
+ g_GameScript->ExecuteFunction(targetEntity->Callbacks.OnHit, index);
}
}
diff --git a/TombEngine/Game/control/los.cpp b/TombEngine/Game/control/los.cpp
index c964755e5..60db0cb41 100644
--- a/TombEngine/Game/control/los.cpp
+++ b/TombEngine/Game/control/los.cpp
@@ -191,10 +191,10 @@ bool GetTargetOnLOS(GameVector* origin, GameVector* target, bool drawTarget, boo
DoDamage(item, Weapons[(int)Lara.Control.Weapon.GunType].Damage);
- if (!item->LuaCallbackOnHitName.empty())
+ if (!item->Callbacks.OnHit.empty())
{
- short index = g_GameScriptEntities->GetIndexByName(item->LuaName);
- g_GameScript->ExecuteFunction(item->LuaCallbackOnHitName, index);
+ short index = g_GameScriptEntities->GetIndexByName(item->Name);
+ g_GameScript->ExecuteFunction(item->Callbacks.OnHit, index);
}
}
}
diff --git a/TombEngine/Game/control/volume.h b/TombEngine/Game/control/volume.h
index 7ebd16d2b..079ba5327 100644
--- a/TombEngine/Game/control/volume.h
+++ b/TombEngine/Game/control/volume.h
@@ -38,7 +38,7 @@ enum TriggerVolumeActivators
struct TriggerVolume
{
TriggerVolumeType Type;
- std::string LuaName;
+ std::string Name = "";
int EventSetIndex;
Vector3 Position;
diff --git a/TombEngine/Game/items.cpp b/TombEngine/Game/items.cpp
index 857e0c32f..43eb3192c 100644
--- a/TombEngine/Game/items.cpp
+++ b/TombEngine/Game/items.cpp
@@ -181,14 +181,14 @@ void KillItem(short const itemNumber)
g_GameScriptEntities->NotifyKilled(item);
g_GameScriptEntities->TryRemoveColliding(itemNumber, true);
- if (!item->LuaCallbackOnKilledName.empty())
- g_GameScript->ExecuteFunction(item->LuaCallbackOnKilledName, itemNumber);
+ if (!item->Callbacks.OnKilled.empty())
+ g_GameScript->ExecuteFunction(item->Callbacks.OnKilled, itemNumber);
- item->LuaName.clear();
- item->LuaCallbackOnKilledName.clear();
- item->LuaCallbackOnHitName.clear();
- item->LuaCallbackOnCollidedWithObjectName.clear();
- item->LuaCallbackOnCollidedWithRoomName.clear();
+ item->Name.clear();
+ item->Callbacks.OnKilled.clear();
+ item->Callbacks.OnHit.clear();
+ item->Callbacks.OnObjectCollided.clear();
+ item->Callbacks.OnRoomCollided.clear();
if (itemNumber >= g_Level.NumItems)
{
@@ -433,9 +433,9 @@ void RemoveActiveItem(short itemNumber)
}
g_GameScriptEntities->NotifyKilled(&item);
- if (!item.LuaCallbackOnKilledName.empty())
+ if (!item.Callbacks.OnKilled.empty())
{
- g_GameScript->ExecuteFunction(item.LuaCallbackOnKilledName, itemNumber);
+ g_GameScript->ExecuteFunction(item.Callbacks.OnKilled, itemNumber);
}
}
}
diff --git a/TombEngine/Game/items.h b/TombEngine/Game/items.h
index 0b9deb815..52e285dac 100644
--- a/TombEngine/Game/items.h
+++ b/TombEngine/Game/items.h
@@ -75,10 +75,19 @@ struct EntityModelData
std::vector Mutator = {};
};
+struct EntityCallbackData
+{
+ std::string OnKilled;
+ std::string OnHit;
+ std::string OnObjectCollided;
+ std::string OnRoomCollided;
+};
+
//todo we need to find good "default states" for a lot of these - squidshire 25/05/2022
struct ItemInfo
{
GAME_OBJECT_ID ObjectNumber;
+ std::string Name;
int Status; // ItemStatus enum.
bool Active;
@@ -89,7 +98,9 @@ struct ItemInfo
ITEM_DATA Data;
EntityAnimationData Animation;
+ EntityCallbackData Callbacks;
EntityModelData Model;
+
Pose StartPose;
Pose Pose;
ROOM_VECTOR Location;
@@ -118,13 +129,6 @@ struct ItemInfo
short AfterDeath;
short CarriedItem;
- // Lua
- std::string LuaName;
- std::string LuaCallbackOnKilledName;
- std::string LuaCallbackOnHitName;
- std::string LuaCallbackOnCollidedWithObjectName;
- std::string LuaCallbackOnCollidedWithRoomName;
-
bool TestOcb(short ocbFlags);
void RemoveOcb(short ocbFlags);
void ClearAllOcb();
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index d752b25ff..a234f7dbe 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -456,11 +456,11 @@ bool SaveGame::Save(int slot)
{
ObjectInfo* obj = &Objects[itemToSerialize.ObjectNumber];
- auto luaNameOffset = fbb.CreateString(itemToSerialize.LuaName);
- auto luaOnKilledNameOffset = fbb.CreateString(itemToSerialize.LuaCallbackOnKilledName);
- auto luaOnHitNameOffset = fbb.CreateString(itemToSerialize.LuaCallbackOnHitName);
- auto luaOnCollidedObjectNameOffset = fbb.CreateString(itemToSerialize.LuaCallbackOnCollidedWithObjectName);
- auto luaOnCollidedRoomNameOffset = fbb.CreateString(itemToSerialize.LuaCallbackOnCollidedWithRoomName);
+ auto luaNameOffset = fbb.CreateString(itemToSerialize.Name);
+ auto luaOnKilledNameOffset = fbb.CreateString(itemToSerialize.Callbacks.OnKilled);
+ auto luaOnHitNameOffset = fbb.CreateString(itemToSerialize.Callbacks.OnHit);
+ auto luaOnCollidedObjectNameOffset = fbb.CreateString(itemToSerialize.Callbacks.OnObjectCollided);
+ auto luaOnCollidedRoomNameOffset = fbb.CreateString(itemToSerialize.Callbacks.OnRoomCollided);
std::vector itemFlags;
for (int i = 0; i < 7; i++)
@@ -1325,14 +1325,14 @@ bool SaveGame::Load(int slot)
ObjectInfo* obj = &Objects[item->ObjectNumber];
- item->LuaName = savedItem->lua_name()->str();
- if (!item->LuaName.empty())
- g_GameScriptEntities->AddName(item->LuaName, i);
+ item->Name = savedItem->lua_name()->str();
+ if (!item->Name.empty())
+ g_GameScriptEntities->AddName(item->Name, i);
- item->LuaCallbackOnKilledName = savedItem->lua_on_killed_name()->str();
- item->LuaCallbackOnHitName = savedItem->lua_on_hit_name()->str();
- item->LuaCallbackOnCollidedWithObjectName = savedItem->lua_on_collided_with_object_name()->str();
- item->LuaCallbackOnCollidedWithRoomName = savedItem->lua_on_collided_with_room_name()->str();
+ item->Callbacks.OnKilled = savedItem->lua_on_killed_name()->str();
+ item->Callbacks.OnHit = savedItem->lua_on_hit_name()->str();
+ item->Callbacks.OnObjectCollided = savedItem->lua_on_collided_with_object_name()->str();
+ item->Callbacks.OnRoomCollided = savedItem->lua_on_collided_with_room_name()->str();
g_GameScriptEntities->TryAddColliding(i);
diff --git a/TombEngine/Objects/Sink.h b/TombEngine/Objects/Sink.h
index 638b46a0e..b3ea420ea 100644
--- a/TombEngine/Objects/Sink.h
+++ b/TombEngine/Objects/Sink.h
@@ -11,7 +11,7 @@ struct SinkInfo
Vector3i Position = Vector3i::Zero;
int Strength = 0;
int BoxIndex = 0;
- string LuaName = "";
+ string Name = "";
SinkInfo()
{
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp
index 052c23a67..f8738c92e 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Camera/CameraObject.cpp
@@ -73,7 +73,7 @@ void Camera::SetPos(Vec3 const& pos)
std::string Camera::GetName() const
{
- return m_camera.LuaName;
+ return m_camera.Name;
}
void Camera::SetName(std::string const & id)
@@ -86,8 +86,8 @@ void Camera::SetName(std::string const & id)
if (s_callbackSetName(id, m_camera))
{
// remove the old name if we have one
- s_callbackRemoveName(m_camera.LuaName);
- m_camera.LuaName = id;
+ s_callbackRemoveName(m_camera.Name);
+ m_camera.Name = id;
}
else
{
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
index e89a5007b..03275acf3 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Moveable/MoveableObject.cpp
@@ -447,7 +447,7 @@ void Moveable::Init()
{
bool cond = IsPointInRoom(m_item->Pose.Position, m_item->RoomNumber);
std::string err{ "Position of item \"{}\" does not match its room ID." };
- if (!ScriptAssertF(cond, err, m_item->LuaName))
+ if (!ScriptAssertF(cond, err, m_item->Name))
{
ScriptWarn("Resetting to the center of the room.");
auto center = GetRoomCenter(m_item->RoomNumber);
@@ -482,7 +482,7 @@ void SetLevelFuncCallback(TypeOrNil const & cb, std::string const & c
}
else
{
- ScriptAssert(false, "Tried giving " + mov.m_item->LuaName
+ ScriptAssert(false, "Tried giving " + mov.m_item->Name
+ " a non-LevelFunc object as an arg to "
+ callerName);
}
@@ -491,27 +491,27 @@ void SetLevelFuncCallback(TypeOrNil const & cb, std::string const & c
void Moveable::SetOnHit(TypeOrNil const & cb)
{
- SetLevelFuncCallback(cb, ScriptReserved_SetOnHit, *this, m_item->LuaCallbackOnHitName);
+ SetLevelFuncCallback(cb, ScriptReserved_SetOnHit, *this, m_item->Callbacks.OnHit);
}
void Moveable::SetOnKilled(TypeOrNil const & cb)
{
- SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->LuaCallbackOnKilledName);
+ SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->Callbacks.OnKilled);
}
void Moveable::SetOnCollidedWithObject(TypeOrNil const & cb)
{
- SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->LuaCallbackOnCollidedWithObjectName);
+ SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->Callbacks.OnObjectCollided);
}
void Moveable::SetOnCollidedWithRoom(TypeOrNil const & cb)
{
- SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithRoom, *this, m_item->LuaCallbackOnCollidedWithRoomName);
+ SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithRoom, *this, m_item->Callbacks.OnRoomCollided);
}
std::string Moveable::GetName() const
{
- return m_item->LuaName;
+ return m_item->Name;
}
bool Moveable::SetName(std::string const & id)
@@ -524,11 +524,11 @@ bool Moveable::SetName(std::string const & id)
if (s_callbackSetName(id, m_num))
{
// remove the old name if we have one
- if (id != m_item->LuaName)
+ if (id != m_item->Name)
{
- if(!m_item->LuaName.empty())
- s_callbackRemoveName(m_item->LuaName);
- m_item->LuaName = id;
+ if(!m_item->Name.empty())
+ s_callbackRemoveName(m_item->Name);
+ m_item->Name = id;
}
}
else
@@ -980,7 +980,7 @@ void Moveable::Destroy()
if (m_num > NO_ITEM)
{
dynamic_cast(g_GameScriptEntities)->RemoveMoveableFromMap(m_item, this);
- s_callbackRemoveName(m_item->LuaName);
+ s_callbackRemoveName(m_item->Name);
KillItem(m_num);
}
@@ -991,7 +991,7 @@ bool Moveable::MeshExists(int index) const
{
if (index < 0 || index >= Objects[m_item->ObjectNumber].nmeshes)
{
- ScriptAssertF(false, "Mesh index {} does not exist in moveable '{}'", index, m_item->LuaName);
+ ScriptAssertF(false, "Mesh index {} does not exist in moveable '{}'", index, m_item->Name);
return false;
}
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
index 088db35ef..a22903a6c 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.cpp
@@ -123,7 +123,7 @@ void ObjectsHandler::TestCollidingObjects()
for (const auto idOne : m_collidingItems)
{
auto item = &g_Level.Items[idOne];
- if (!item->LuaCallbackOnCollidedWithObjectName.empty())
+ if (!item->Callbacks.OnObjectCollided.empty())
{
//test against other moveables
GetCollidedObjects(item, 0, true, CollidedItems, nullptr, 0);
@@ -131,17 +131,17 @@ void ObjectsHandler::TestCollidingObjects()
while (CollidedItems[i])
{
short idTwo = CollidedItems[i] - &g_Level.Items[0];
- g_GameScript->ExecuteFunction(item->LuaCallbackOnCollidedWithObjectName, idOne, idTwo);
+ g_GameScript->ExecuteFunction(item->Callbacks.OnObjectCollided, idOne, idTwo);
++i;
}
}
- if (!item->LuaCallbackOnCollidedWithRoomName.empty())
+ if (!item->Callbacks.OnRoomCollided.empty())
{
//test against room geometry
if (TestItemRoomCollisionAABB(item))
{
- g_GameScript->ExecuteFunction(item->LuaCallbackOnCollidedWithRoomName, idOne);
+ g_GameScript->ExecuteFunction(item->Callbacks.OnRoomCollided, idOne);
}
}
}
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.h b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.h
index 1c1122e60..4eecd0d8c 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.h
+++ b/TombEngine/Scripting/Internal/TEN/Objects/ObjectsHandler.h
@@ -20,8 +20,8 @@ public:
bool TryAddColliding(short id) override
{
ItemInfo* item = &g_Level.Items[id];
- bool hasName = !(item->LuaCallbackOnCollidedWithObjectName.empty() && item->LuaCallbackOnCollidedWithRoomName.empty());
- if(hasName && item->Collidable && (item->Status != ITEM_INVISIBLE))
+ bool hasName = !(item->Callbacks.OnObjectCollided.empty() && item->Callbacks.OnRoomCollided.empty());
+ if (hasName && item->Collidable && (item->Status != ITEM_INVISIBLE))
return m_collidingItems.insert(id).second;
return false;
@@ -30,7 +30,7 @@ public:
bool TryRemoveColliding(short id, bool force = false) override
{
ItemInfo* item = &g_Level.Items[id];
- bool hasName = !(item->LuaCallbackOnCollidedWithObjectName.empty() && item->LuaCallbackOnCollidedWithRoomName.empty());
+ bool hasName = !(item->Callbacks.OnObjectCollided.empty() && item->Callbacks.OnRoomCollided.empty());
if(!force && hasName && item->Collidable && (item->Status != ITEM_INVISIBLE))
return false;
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp
index 8d8d756ed..7a31ffe30 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/Sink/SinkObject.cpp
@@ -73,7 +73,7 @@ void Sink::SetPos(Vec3 const& pos)
std::string Sink::GetName() const
{
- return m_sink.LuaName;
+ return m_sink.Name;
}
void Sink::SetName(std::string const & id)
@@ -86,8 +86,8 @@ void Sink::SetName(std::string const & id)
if (s_callbackSetName(id, m_sink))
{
// remove the old name if we have one
- s_callbackRemoveName(m_sink.LuaName);
- m_sink.LuaName = id;
+ s_callbackRemoveName(m_sink.Name);
+ m_sink.Name = id;
}
else
{
diff --git a/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp b/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp
index c9b7f9b39..c76bf88eb 100644
--- a/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp
+++ b/TombEngine/Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.cpp
@@ -71,7 +71,7 @@ void SoundSource::SetPos(Vec3 const& pos)
std::string SoundSource::GetName() const
{
- return m_soundSource.LuaName;
+ return m_soundSource.Name;
}
void SoundSource::SetName(std::string const& id)
@@ -84,8 +84,8 @@ void SoundSource::SetName(std::string const& id)
if (s_callbackSetName(id, m_soundSource))
{
// remove the old name if we have one
- s_callbackRemoveName(m_soundSource.LuaName);
- m_soundSource.LuaName = id;
+ s_callbackRemoveName(m_soundSource.Name);
+ m_soundSource.Name = id;
}
else
{
diff --git a/TombEngine/Sound/sound.h b/TombEngine/Sound/sound.h
index 68f199563..7ed3d58fd 100644
--- a/TombEngine/Sound/sound.h
+++ b/TombEngine/Sound/sound.h
@@ -115,7 +115,7 @@ struct SoundSourceInfo
Vector3i Position = Vector3i::Zero;
int SoundID = 0;
int Flags = 0;
- string LuaName = "";
+ string Name = "";
SoundSourceInfo()
{
diff --git a/TombEngine/Specific/LevelCameraInfo.h b/TombEngine/Specific/LevelCameraInfo.h
index ccb0d6b75..ea36fbb32 100644
--- a/TombEngine/Specific/LevelCameraInfo.h
+++ b/TombEngine/Specific/LevelCameraInfo.h
@@ -12,7 +12,7 @@ struct LevelCameraInfo
int RoomNumber = 0;
int Flags = 0;
int Speed = 1;
- string LuaName = "";
+ string Name = "";
LevelCameraInfo()
{
diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp
index 04313ccb7..5204887b9 100644
--- a/TombEngine/Specific/level.cpp
+++ b/TombEngine/Specific/level.cpp
@@ -184,9 +184,9 @@ void LoadItems()
item->Color = ReadVector4();
item->TriggerFlags = ReadInt16();
item->Flags = ReadInt16();
- item->LuaName = ReadString();
+ item->Name = ReadString();
- g_GameScriptEntities->AddName(item->LuaName, i);
+ g_GameScriptEntities->AddName(item->Name, i);
g_GameScriptEntities->TryAddColliding(i);
memcpy(&item->StartPose, &item->Pose, sizeof(Pose));
@@ -423,9 +423,9 @@ void LoadCameras()
camera.RoomNumber = ReadInt32();
camera.Flags = ReadInt32();
camera.Speed = ReadInt32();
- camera.LuaName = ReadString();
+ camera.Name = ReadString();
- g_GameScriptEntities->AddName(camera.LuaName, camera);
+ g_GameScriptEntities->AddName(camera.Name, camera);
}
NumberSpotcams = ReadInt32();
@@ -445,9 +445,9 @@ void LoadCameras()
sink.Position.z = ReadInt32();
sink.Strength = ReadInt32();
sink.BoxIndex = ReadInt32();
- sink.LuaName = ReadString();
+ sink.Name = ReadString();
- g_GameScriptEntities->AddName(sink.LuaName, sink);
+ g_GameScriptEntities->AddName(sink.Name, sink);
}
}
@@ -795,7 +795,7 @@ void ReadRooms()
volume.Scale.y = ReadFloat();
volume.Scale.z = ReadFloat();
- volume.LuaName = ReadString();
+ volume.Name = ReadString();
volume.EventSetIndex = ReadInt32();
volume.Status = TriggerStatus::Outside;
@@ -903,9 +903,9 @@ void LoadSoundSources()
source.Position.z = ReadInt32();
source.SoundID = ReadInt32();
source.Flags = ReadInt32();
- source.LuaName = ReadString();
+ source.Name = ReadString();
- g_GameScriptEntities->AddName(source.LuaName, source);
+ g_GameScriptEntities->AddName(source.Name, source);
}
}
From fce8a0c361a89ba02f4ae3819fd015c3aa869f9c Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:03:08 +0200
Subject: [PATCH 09/13] Fix #832
---
Documentation/Changes.txt | 1 +
TombEngine/Game/savegame.cpp | 3 +++
2 files changed, 4 insertions(+)
diff --git a/Documentation/Changes.txt b/Documentation/Changes.txt
index 46237034f..ff0d602be 100644
--- a/Documentation/Changes.txt
+++ b/Documentation/Changes.txt
@@ -16,6 +16,7 @@ Version 1.0.3
* Improve game and inventory input handling.
* Adjust sprint jump timing.
* Fix going into inventory and load/save dialogs during fade-ins and fade-outs.
+* Fix savegames not preserving save number and game timer.
* Fix dodgy weapon lock angle constraints.
* Fix wrong shotgun ammo pickup amount.
* Fix shotgun using 6 units of ammo with each shot.
diff --git a/TombEngine/Game/savegame.cpp b/TombEngine/Game/savegame.cpp
index a234f7dbe..e108587fb 100644
--- a/TombEngine/Game/savegame.cpp
+++ b/TombEngine/Game/savegame.cpp
@@ -1195,6 +1195,9 @@ bool SaveGame::Load(int slot)
const Save::SaveGame* s = Save::GetSaveGame(buffer.get());
// Statistics
+ LastSaveGame = s->header()->count();
+ GameTimer = s->header()->timer();
+
Statistics.Game.AmmoHits = s->game()->ammo_hits();
Statistics.Game.AmmoUsed = s->game()->ammo_used();
Statistics.Game.Distance = s->game()->distance();
From ca0a495b9224bc56fcf295c3f7fcf3b614595ba4 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 02:10:24 +0200
Subject: [PATCH 10/13] Remove portal merge code as it's now on TE side
---
TombEngine/Specific/level.cpp | 86 +----------------------------------
1 file changed, 1 insertion(+), 85 deletions(-)
diff --git a/TombEngine/Specific/level.cpp b/TombEngine/Specific/level.cpp
index 5204887b9..4fa46943a 100644
--- a/TombEngine/Specific/level.cpp
+++ b/TombEngine/Specific/level.cpp
@@ -1428,96 +1428,12 @@ void LoadPortal(ROOM_INFO& room)
door.normal.y = ReadInt32();
door.normal.z = ReadInt32();
- float minX1 = INFINITY;
- float minY1 = INFINITY;
- float minZ1 = INFINITY;
- float maxX1 = -INFINITY;
- float maxY1 = -INFINITY;
- float maxZ1 = -INFINITY;
-
for (int k = 0; k < 4; k++)
{
door.vertices[k].x = ReadInt32();
door.vertices[k].y = ReadInt32();
door.vertices[k].z = ReadInt32();
-
- minX1 = std::min(minX1, door.vertices[k].x);
- minY1 = std::min(minY1, door.vertices[k].y);
- minZ1 = std::min(minZ1, door.vertices[k].z);
-
- maxX1 = std::max(maxX1, door.vertices[k].x);
- maxY1 = std::max(maxY1, door.vertices[k].y);
- maxZ1 = std::max(maxZ1, door.vertices[k].z);
}
- bool found = false;
-
- float minX2 = INFINITY;
- float minY2 = INFINITY;
- float minZ2 = INFINITY;
- float maxX2 = -INFINITY;
- float maxY2 = -INFINITY;
- float maxZ2 = -INFINITY;
-
- for (int k = 0; k < room.doors.size(); k++)
- {
- ROOM_DOOR* current = &room.doors[k];
-
- if (current->room == door.room)
- {
- // Merge door
- found = true;
-
- for (int n = 0; n < 4; n++)
- {
- minX2 = std::min(minX2, current->vertices[n].x);
- minY2 = std::min(minY2, current->vertices[n].y);
- minZ2 = std::min(minZ2, current->vertices[n].z);
-
- maxX2 = std::max(maxX2, current->vertices[n].x);
- maxY2 = std::max(maxY2, current->vertices[n].y);
- maxZ2 = std::max(maxZ2, current->vertices[n].z);
- }
-
- minX1 = std::min(minX2, minX1);
- minY1 = std::min(minY2, minY1);
- minZ1 = std::min(minZ2, minZ1);
-
- maxX1 = std::max(maxX2, maxX1);
- maxY1 = std::max(maxY2, maxY1);
- maxZ1 = std::max(maxZ2, maxZ1);
-
- if (minY1 == maxY1)
- {
- current->vertices[0] = Vector3(minX1, minY1, minZ1);
- current->vertices[1] = Vector3(minX1, minY1, maxZ1);
- current->vertices[2] = Vector3(maxX1, minY1, maxZ1);
- current->vertices[3] = Vector3(maxX1, minY1, minZ1);
- }
- else if (minX1 == maxX1)
- {
- current->vertices[0] = Vector3(minX1, minY1, minZ1);
- current->vertices[1] = Vector3(minX1, maxY1, minZ1);
- current->vertices[2] = Vector3(minX1, maxY1, maxZ1);
- current->vertices[3] = Vector3(minX1, minY1, maxZ1);
- }
- else if (minZ1 == maxZ1)
- {
- current->vertices[0] = Vector3(minX1, minY1, minZ1);
- current->vertices[1] = Vector3(minX1, maxY1, minZ1);
- current->vertices[2] = Vector3(maxX1, maxY1, minZ1);
- current->vertices[3] = Vector3(maxX1, minY1, minZ1);
- }
- else
- {
- current->vertices[0] = Vector3(minX1, minY1, minZ1);
- current->vertices[1] = Vector3(minX1, maxY1, maxZ1);
- current->vertices[2] = Vector3(maxX1, maxY1, maxZ1);
- current->vertices[3] = Vector3(maxX1, minY1, minZ1);
- }
- }
- }
-
- if (!found)
- room.doors.push_back(door);
+ room.doors.push_back(door);
}
\ No newline at end of file
From 1bf50ca313688608b4097dbed888fa0e75935d83 Mon Sep 17 00:00:00 2001
From: Sezz
Date: Sun, 13 Nov 2022 13:26:23 +1100
Subject: [PATCH 11/13] Let idle state handle landing on slopes
---
TombEngine/Game/Lara/lara_jump.cpp | 20 --------------------
1 file changed, 20 deletions(-)
diff --git a/TombEngine/Game/Lara/lara_jump.cpp b/TombEngine/Game/Lara/lara_jump.cpp
index 49ac7baff..1fe0f00f8 100644
--- a/TombEngine/Game/Lara/lara_jump.cpp
+++ b/TombEngine/Game/Lara/lara_jump.cpp
@@ -62,8 +62,6 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) USE_FEATURE_IF_CPP20([[unlikely]])
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else if (TrInput & IN_FORWARD && !(TrInput & IN_WALK) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
@@ -144,8 +142,6 @@ void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -201,8 +197,6 @@ void lara_as_reach(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -413,8 +407,6 @@ void lara_as_jump_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -469,8 +461,6 @@ void lara_as_jump_right(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -526,8 +516,6 @@ void lara_as_jump_left(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -581,8 +569,6 @@ void lara_as_jump_up(ItemInfo* item, CollisionInfo* coll)
{
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -678,8 +664,6 @@ void lara_as_fall_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -750,8 +734,6 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else if ((TrInput & IN_CROUCH || TestLaraCrawlspaceDive(item, coll)) &&
g_GameFlow->HasCrawlspaceDive())
{
@@ -829,8 +811,6 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_DEATH;
Rumble(0.5f, 0.2f);
}
- else if (TestLaraSlide(item, coll))
- SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
From 654e6c1aa37deb6b4139616bede3d11e2d9abbb7 Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 12:19:50 +0200
Subject: [PATCH 12/13] Disable UpdateItemRoom when using SetPosition
animcommand on non-Lara objects
---
TombEngine/Game/animation.cpp | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/TombEngine/Game/animation.cpp b/TombEngine/Game/animation.cpp
index 6d82c4d24..77eb24f7a 100644
--- a/TombEngine/Game/animation.cpp
+++ b/TombEngine/Game/animation.cpp
@@ -115,8 +115,12 @@ void PerformAnimCommands(ItemInfo* item, bool isFrameBased)
if (!isFrameBased)
{
TranslateItem(item, item->Pose.Orientation.y, commandPtr[2], commandPtr[1], commandPtr[0]);
- auto bounds = GameBoundingBox(item);
- UpdateItemRoom(item, -bounds.GetHeight() / 2, -commandPtr[0], -commandPtr[2]);
+
+ if (item->IsLara())
+ {
+ auto bounds = GameBoundingBox(item);
+ UpdateItemRoom(item, -bounds.GetHeight() / 2, -commandPtr[0], -commandPtr[2]);
+ }
}
commandPtr += 3;
From 049368a249d6f30226932c029f9f04766059256d Mon Sep 17 00:00:00 2001
From: Lwmte <3331699+Lwmte@users.noreply.github.com>
Date: Sun, 13 Nov 2022 12:28:45 +0200
Subject: [PATCH 13/13] Revert "Let idle state handle landing on slopes"
This reverts commit 1bf50ca313688608b4097dbed888fa0e75935d83.
---
TombEngine/Game/Lara/lara_jump.cpp | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/TombEngine/Game/Lara/lara_jump.cpp b/TombEngine/Game/Lara/lara_jump.cpp
index 1fe0f00f8..49ac7baff 100644
--- a/TombEngine/Game/Lara/lara_jump.cpp
+++ b/TombEngine/Game/Lara/lara_jump.cpp
@@ -62,6 +62,8 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0) USE_FEATURE_IF_CPP20([[unlikely]])
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else if (TrInput & IN_FORWARD && !(TrInput & IN_WALK) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
@@ -142,6 +144,8 @@ void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -197,6 +201,8 @@ void lara_as_reach(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -407,6 +413,8 @@ void lara_as_jump_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -461,6 +469,8 @@ void lara_as_jump_right(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -516,6 +526,8 @@ void lara_as_jump_left(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -569,6 +581,8 @@ void lara_as_jump_up(ItemInfo* item, CollisionInfo* coll)
{
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -664,6 +678,8 @@ void lara_as_fall_back(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;
@@ -734,6 +750,8 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else if ((TrInput & IN_CROUCH || TestLaraCrawlspaceDive(item, coll)) &&
g_GameFlow->HasCrawlspaceDive())
{
@@ -811,6 +829,8 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_DEATH;
Rumble(0.5f, 0.2f);
}
+ else if (TestLaraSlide(item, coll))
+ SetLaraSlideAnimation(item, coll);
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_IDLE;