Merge remote-tracking branch 'origin/master' into lua_1.0.3

This commit is contained in:
hispidence 2022-11-13 12:30:56 +00:00
commit a8be0d667d
58 changed files with 563 additions and 682 deletions

View file

@ -3,11 +3,11 @@ 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 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.
* 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).
@ -15,6 +15,8 @@ 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 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.
@ -28,6 +30,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.
@ -35,6 +38,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.

View file

@ -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);
@ -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);
}
}

View file

@ -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)

View file

@ -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 */

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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();

View file

@ -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)

View file

@ -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);
}
}
}

View file

@ -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()

View file

@ -29,7 +29,7 @@ enum TriggerVolumeActivators
{
Player = 1,
NPC = 2,
Movable = 4,
Moveable = 4,
Static = 8,
Flyby = 16,
PhysicalObject = 32 // Future-proofing for Bullet.
@ -38,7 +38,7 @@ enum TriggerVolumeActivators
struct TriggerVolume
{
TriggerVolumeType Type;
std::string LuaName;
std::string Name = "";
int EventSetIndex;
Vector3 Position;

View file

@ -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;

View file

@ -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<unsigned int> 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<unsigned int> flags, bool clear)
{
BitField bits = {};
bits.Set(flags);
SetMeshSwapFlags(bits.ToPackedBits(), clear);
}
bool ItemInfo::IsLara()
{
return this->Data.is<LaraInfo*>();
@ -133,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)
{
@ -385,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);
}
}
}
@ -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,14 +510,23 @@ 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)
if (Objects[item->ObjectNumber].initialise != nullptr)
Objects[item->ObjectNumber].initialise(itemNumber);
}

View file

@ -66,13 +66,28 @@ struct EntityAnimationData
bool IsAirborne = false;
Vector3 Velocity = Vector3::Zero; // CONVENTION: +X = right, +Y = down, +Z = forward
};
struct EntityModelData
{
int BaseMesh;
std::vector<int> MeshIndex = {};
std::vector<BoneMutator> 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;
@ -83,6 +98,9 @@ struct ItemInfo
ITEM_DATA Data;
EntityAnimationData Animation;
EntityCallbackData Callbacks;
EntityModelData Model;
Pose StartPose;
Pose Pose;
ROOM_VECTOR Location;
@ -101,7 +119,6 @@ struct ItemInfo
BitField TouchBits = BitField();
BitField MeshBits = BitField();
BitField MeshSwapBits = BitField();
unsigned short Flags; // ItemFlags enum
short ItemFlags[8];
@ -112,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();
@ -126,6 +136,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<unsigned int> flags);
void SetMeshSwapFlags(unsigned int flags, bool clear = false);
void SetMeshSwapFlags(const std::vector<unsigned int> flags, bool clear = false);
bool IsLara();
bool IsCreature();
};

View file

@ -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;
}
}

View file

@ -228,11 +228,6 @@ bool SaveGame::Save(int slot)
examinesCombo.push_back(Lara.Inventory.ExaminesCombo[i]);
auto examinesComboOffset = fbb.CreateVector(examinesCombo);
std::vector<int> meshPtrs;
for (int i = 0; i < 15; i++)
meshPtrs.push_back(Lara.MeshPtrs[i]);
auto meshPtrsOffset = fbb.CreateVector(meshPtrs);
std::vector<byte> 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);
@ -462,16 +456,21 @@ 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<int> itemFlags;
for (int i = 0; i < 7; i++)
itemFlags.push_back(itemToSerialize.ItemFlags[i]);
auto itemFlagsOffset = fbb.CreateVector(itemFlags);
std::vector<int> meshPointers;
for (auto p : itemToSerialize.Model.MeshIndex)
meshPointers.push_back(p);
auto meshPointerOffset = fbb.CreateVector(meshPointers);
flatbuffers::Offset<Save::Creature> creatureOffset;
flatbuffers::Offset<Save::QuadBike> 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<CreatureInfo>())
@ -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();
@ -1325,14 +1328,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);
@ -1388,7 +1391,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 +1708,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);

View file

@ -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)

View file

@ -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)

View file

@ -11,7 +11,7 @@ struct SinkInfo
Vector3i Position = Vector3i::Zero;
int Strength = 0;
int BoxIndex = 0;
string LuaName = "";
string Name = "";
SinkInfo()
{

View file

@ -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;

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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;

View file

@ -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))

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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;
}
}

View file

@ -1,6 +0,0 @@
#pragma once
struct CollisionInfo;
struct ItemInfo;
void DragSasCollision(short itemNumber, ItemInfo* laraItem, CollisionInfo* coll);

View file

@ -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);
}
}
}

View file

@ -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;
}
}
}

View file

@ -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;

View file

@ -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]++;
}
}

View file

@ -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)

View file

@ -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;

View file

@ -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)
{

View file

@ -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,

View file

@ -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);
}
}

View file

@ -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);
}
}

View file

@ -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<RendererLight*> LightsToDraw;
float LightFade;
std::vector<int> MeshIndex;
bool DoneAnimations;
};
struct RendererMesh

View file

@ -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;
}
}

View file

@ -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);
}
}

View file

@ -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

View file

@ -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, &currentBone](QuadBikeInfo& quadBike)
nativeItem->Data.apply(
[&j, &currentBone](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, &currentBone](JeepInfo& jeep)
currentBone->ExtraRotation.x = TO_RAD(quadBike.FrontRot);
currentBone->ExtraRotation.y = TO_RAD(quadBike.TurnRate * 2);
}
},
[&j, &currentBone](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, &currentBone](MotorbikeInfo& bike)
case 13:
currentBone->ExtraRotation.x = TO_RAD(jeep.BackLeftWheelRotation);
break;
}
},
[&j, &currentBone](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, &currentBone, &prevRotation](MinecartInfo& cart)
case 8:
currentBone->ExtraRotation.x = TO_RAD(bike.LeftWheelRotation);
break;
}
},
[&j, &currentBone, &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, &currentBone](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, &currentBone](RubberBoatInfo& boat)
{
if (j == 2)
currentBone->ExtraRotation.z = TO_RAD(boat.PropellerRotation);
},
[&j, &currentBone](UPVInfo& upv)
{
switch (j)
{
if (j == 2)
currentBone->ExtraRotation.z = TO_RAD(boat.PropellerRotation);
},
[&j, &currentBone](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, &currentBone](BigGunInfo& big_gun)
{
if (j == 2)
currentBone->ExtraRotation.z = big_gun.BarrelRotation;
},
[&j, &currentBone, &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, &currentBone](BigGunInfo& big_gun)
if (currentBone->ExtraRotationFlags & ROT_X)
{
if (j == 2)
currentBone->ExtraRotation.z = big_gun.BarrelRotation;
},
[&j, &currentBone, &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)

View file

@ -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);

View file

@ -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
{

View file

@ -441,7 +441,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);
@ -476,7 +476,7 @@ void SetLevelFuncCallback(TypeOrNil<LevelFunc> 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);
}
@ -485,27 +485,27 @@ void SetLevelFuncCallback(TypeOrNil<LevelFunc> const & cb, std::string const & c
void Moveable::SetOnHit(TypeOrNil<LevelFunc> const & cb)
{
SetLevelFuncCallback(cb, ScriptReserved_SetOnHit, *this, m_item->LuaCallbackOnHitName);
SetLevelFuncCallback(cb, ScriptReserved_SetOnHit, *this, m_item->Callbacks.OnHit);
}
void Moveable::SetOnKilled(TypeOrNil<LevelFunc> const & cb)
{
SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->LuaCallbackOnKilledName);
SetLevelFuncCallback(cb, ScriptReserved_SetOnKilled, *this, m_item->Callbacks.OnKilled);
}
void Moveable::SetOnCollidedWithObject(TypeOrNil<LevelFunc> const & cb)
{
SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->LuaCallbackOnCollidedWithObjectName);
SetLevelFuncCallback(cb, ScriptReserved_SetOnCollidedWithObject, *this, m_item->Callbacks.OnObjectCollided);
}
void Moveable::SetOnCollidedWithRoom(TypeOrNil<LevelFunc> 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)
@ -518,11 +518,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
@ -814,7 +814,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<int> swapMeshIndex)
@ -825,32 +825,26 @@ void Moveable::SwapMesh(int meshId, int swapSlotId, sol::optional<int> 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)
@ -858,20 +852,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()
@ -991,7 +972,7 @@ void Moveable::Destroy()
if (m_num > NO_ITEM)
{
dynamic_cast<ObjectsHandler*>(g_GameScriptEntities)->RemoveMoveableFromMap(m_item, this);
s_callbackRemoveName(m_item->LuaName);
s_callbackRemoveName(m_item->Name);
KillItem(m_num);
}
@ -1002,7 +983,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;
}

View file

@ -125,7 +125,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);
@ -133,17 +133,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);
}
}
}

View file

@ -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;

View file

@ -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
{

View file

@ -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
{

View file

@ -115,7 +115,7 @@ struct SoundSourceInfo
Vector3i Position = Vector3i::Zero;
int SoundID = 0;
int Flags = 0;
string LuaName = "";
string Name = "";
SoundSourceInfo()
{

View file

@ -12,7 +12,7 @@ struct LevelCameraInfo
int RoomNumber = 0;
int Flags = 0;
int Speed = 1;
string LuaName = "";
string Name = "";
LevelCameraInfo()
{

View file

@ -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);
}
}
@ -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);
}

View file

@ -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<int32_t> 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<int32_t>(VT_ACTIVE_STATE, 0);
@ -597,9 +599,6 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
int32_t ai_bits() const {
return GetField<int32_t>(VT_AI_BITS, 0);
}
int32_t swap_mesh_flags() const {
return GetField<int32_t>(VT_SWAP_MESH_FLAGS, 0);
}
TEN::Save::ItemData data_type() const {
return static_cast<TEN::Save::ItemData>(GetField<uint8_t>(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<const TEN::Save::Minecart *>(data()) : nullptr;
}
int32_t base_mesh() const {
return GetField<int32_t>(VT_BASE_MESH, 0);
}
const flatbuffers::Vector<int32_t> *mesh_pointers() const {
return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_MESH_POINTERS);
}
const flatbuffers::String *lua_name() const {
return GetPointer<const flatbuffers::String *>(VT_LUA_NAME);
}
@ -722,10 +727,12 @@ struct Item FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<uint8_t>(verifier, VT_COLLIDABLE) &&
VerifyField<uint8_t>(verifier, VT_LOOKED_AT) &&
VerifyField<int32_t>(verifier, VT_AI_BITS) &&
VerifyField<int32_t>(verifier, VT_SWAP_MESH_FLAGS) &&
VerifyField<uint8_t>(verifier, VT_DATA_TYPE) &&
VerifyOffset(verifier, VT_DATA) &&
VerifyItemData(verifier, data(), data_type()) &&
VerifyField<int32_t>(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<int32_t>(Item::VT_AI_BITS, ai_bits, 0);
}
void add_swap_mesh_flags(int32_t swap_mesh_flags) {
fbb_.AddElement<int32_t>(Item::VT_SWAP_MESH_FLAGS, swap_mesh_flags, 0);
}
void add_data_type(TEN::Save::ItemData data_type) {
fbb_.AddElement<uint8_t>(Item::VT_DATA_TYPE, static_cast<uint8_t>(data_type), 0);
}
void add_data(flatbuffers::Offset<void> data) {
fbb_.AddOffset(Item::VT_DATA, data);
}
void add_base_mesh(int32_t base_mesh) {
fbb_.AddElement<int32_t>(Item::VT_BASE_MESH, base_mesh, 0);
}
void add_mesh_pointers(flatbuffers::Offset<flatbuffers::Vector<int32_t>> mesh_pointers) {
fbb_.AddOffset(Item::VT_MESH_POINTERS, mesh_pointers);
}
void add_lua_name(flatbuffers::Offset<flatbuffers::String> lua_name) {
fbb_.AddOffset(Item::VT_LUA_NAME, lua_name);
}
@ -996,9 +1006,10 @@ inline flatbuffers::Offset<Item> 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<void> data = 0,
int32_t base_mesh = 0,
flatbuffers::Offset<flatbuffers::Vector<int32_t>> mesh_pointers = 0,
flatbuffers::Offset<flatbuffers::String> lua_name = 0,
flatbuffers::Offset<flatbuffers::String> lua_on_killed_name = 0,
flatbuffers::Offset<flatbuffers::String> lua_on_hit_name = 0,
@ -1010,8 +1021,9 @@ inline flatbuffers::Offset<Item> 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<Item> 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<void> data = 0,
int32_t base_mesh = 0,
const std::vector<int32_t> *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<int32_t>(*item_flags) : 0;
auto mesh_pointers__ = mesh_pointers ? _fbb.CreateVector<int32_t>(*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<Item> 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<bool> wet{};
std::vector<int32_t> 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<int32_t>(VT_ITEM_NUMBER, 0);
@ -3482,9 +3495,6 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
const flatbuffers::Vector<uint8_t> *wet() const {
return GetPointer<const flatbuffers::Vector<uint8_t> *>(VT_WET);
}
const flatbuffers::Vector<int32_t> *mesh_ptrs() const {
return GetPointer<const flatbuffers::Vector<int32_t> *>(VT_MESH_PTRS);
}
int32_t location() const {
return GetField<int32_t>(VT_LOCATION, 0);
}
@ -3538,8 +3548,6 @@ struct Lara FLATBUFFERS_FINAL_CLASS : private flatbuffers::Table {
VerifyField<uint8_t>(verifier, VT_BURN_SMOKE) &&
VerifyOffset(verifier, VT_WET) &&
verifier.VerifyVector(wet()) &&
VerifyOffset(verifier, VT_MESH_PTRS) &&
verifier.VerifyVector(mesh_ptrs()) &&
VerifyField<int32_t>(verifier, VT_LOCATION) &&
VerifyField<int32_t>(verifier, VT_HIGHEST_LOCATION) &&
VerifyField<int32_t>(verifier, VT_LOCATION_PAD) &&
@ -3650,9 +3658,6 @@ struct LaraBuilder {
void add_wet(flatbuffers::Offset<flatbuffers::Vector<uint8_t>> wet) {
fbb_.AddOffset(Lara::VT_WET, wet);
}
void add_mesh_ptrs(flatbuffers::Offset<flatbuffers::Vector<int32_t>> mesh_ptrs) {
fbb_.AddOffset(Lara::VT_MESH_PTRS, mesh_ptrs);
}
void add_location(int32_t location) {
fbb_.AddElement<int32_t>(Lara::VT_LOCATION, location, 0);
}
@ -3707,7 +3712,6 @@ inline flatbuffers::Offset<Lara> CreateLara(
int32_t burn_blue = 0,
bool burn_smoke = false,
flatbuffers::Offset<flatbuffers::Vector<uint8_t>> wet = 0,
flatbuffers::Offset<flatbuffers::Vector<int32_t>> mesh_ptrs = 0,
int32_t location = 0,
int32_t highest_location = 0,
int32_t location_pad = 0) {
@ -3715,7 +3719,6 @@ inline flatbuffers::Offset<Lara> 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<Lara> CreateLaraDirect(
int32_t burn_blue = 0,
bool burn_smoke = false,
const std::vector<uint8_t> *wet = nullptr,
const std::vector<int32_t> *mesh_ptrs = nullptr,
int32_t location = 0,
int32_t highest_location = 0,
int32_t location_pad = 0) {
auto weapons__ = weapons ? _fbb.CreateVector<flatbuffers::Offset<TEN::Save::CarriedWeaponInfo>>(*weapons) : 0;
auto target_arm_angles__ = target_arm_angles ? _fbb.CreateVector<int32_t>(*target_arm_angles) : 0;
auto wet__ = wet ? _fbb.CreateVector<uint8_t>(*wet) : 0;
auto mesh_ptrs__ = mesh_ptrs ? _fbb.CreateVector<int32_t>(*mesh_ptrs) : 0;
return TEN::Save::CreateLara(
_fbb,
item_number,
@ -3832,7 +3833,6 @@ inline flatbuffers::Offset<Lara> 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<Item> 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<Item> 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<Lara> 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<Lara> CreateLara(flatbuffers::FlatBufferBuilder &_fbb
_burn_blue,
_burn_smoke,
_wet,
_mesh_ptrs,
_location,
_highest_location,
_location_pad);

View file

@ -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;

View file

@ -166,7 +166,6 @@ CALL gen.bat</Command>
<ClInclude Include="Game\debug\debug.h" />
<ClInclude Include="Game\effects\lightning.h" />
<ClInclude Include="Game\GuiObjects.h" />
<ClInclude Include="Objects\TR4\Object\tr4_sas_drag_bloke.h" />
<ClInclude Include="Scripting\Internal\TEN\Objects\Lara\LaraObject.h" />
<ClInclude Include="Specific\Input\InputAction.h" />
<ClInclude Include="Game\itemdata\door_data.h" />
@ -630,7 +629,6 @@ CALL gen.bat</Command>
<ClCompile Include="Game\effects\footprint.cpp" />
<ClCompile Include="Game\GuiObjects.cpp" />
<ClCompile Include="Scripting\Internal\TEN\Objects\Lara\LaraObject.cpp" />
<ClCompile Include="Objects\TR4\Object\tr4_sas_drag_bloke.cpp" />
<ClCompile Include="Specific\Input\InputAction.cpp" />
<ClCompile Include="Game\itemdata\itemdata.cpp" />
<ClCompile Include="Game\Lara\lara_basic.cpp" />