Complete short -> int conversions for Lua

This commit is contained in:
Sezz 2025-02-06 01:22:59 +11:00
parent 237ceca0f4
commit 437ce7c139
13 changed files with 146 additions and 149 deletions

View file

@ -8,7 +8,7 @@ namespace TEN::Control::Volumes
{
using Activator = std::variant<
std::nullptr_t,
short,
int,
MESH_INFO*,
CAMERA_INFO*>;

View file

@ -17,7 +17,7 @@ namespace TEN::Control::Volumes
constexpr auto CAM_SIZE = 32;
constexpr auto EVENT_STATE_MASK = SHRT_MAX;
bool TestVolumeContainment(const TriggerVolume& volume, const BoundingOrientedBox& box, short roomNumber)
bool TestVolumeContainment(const TriggerVolume& volume, const BoundingOrientedBox& box, int roomNumber)
{
float color = !volume.StateQueue.empty() ? 1.0f : 0.4f;
@ -129,7 +129,7 @@ namespace TEN::Control::Volumes
return true;
}
void TestVolumes(short roomNumber, const BoundingOrientedBox& box, ActivatorFlags activatorFlag, Activator activator)
void TestVolumes(int roomNumber, const BoundingOrientedBox& box, ActivatorFlags activatorFlag, Activator activator)
{
if (g_GameFlow->CurrentFreezeMode != FreezeMode::None)
return;
@ -152,7 +152,7 @@ namespace TEN::Control::Volumes
if (!volume.DetectInAdjacentRooms && currentRoomIndex != roomNumber)
continue;
if (volume.EventSetIndex == NO_EVENT_SET)
if (volume.EventSetIndex == NO_VALUE)
continue;
auto& set = g_Level.VolumeEventSets[volume.EventSetIndex];
@ -233,18 +233,17 @@ namespace TEN::Control::Volumes
TestVolumes(camera->pos.RoomNumber, box, ActivatorFlags::Flyby, camera);
}
void TestVolumes(short roomNumber, MESH_INFO* mesh)
void TestVolumes(int roomNumber, MESH_INFO* mesh)
{
auto box = GetBoundsAccurate(*mesh, false).ToBoundingOrientedBox(mesh->pos);
TestVolumes(roomNumber, box, ActivatorFlags::Static, mesh);
}
void TestVolumes(short itemNumber, const CollisionSetupData* coll)
void TestVolumes(int itemNumber, const CollisionSetupData* coll)
{
auto& item = g_Level.Items[itemNumber];
auto box = (coll != nullptr) ?
ConstructRoughBox(item, *coll) : GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose);
auto box = (coll != nullptr) ? ConstructRoughBox(item, *coll) : GameBoundingBox(&item).ToBoundingOrientedBox(item.Pose);
DrawDebugBox(box, Vector4(1.0f, 1.0f, 0.0f, 1.0f), RendererDebugPage::CollisionStats);

View file

@ -8,8 +8,6 @@ struct CollisionSetupData;
namespace TEN::Control::Volumes
{
constexpr auto NO_EVENT_SET = -1;
constexpr auto VOLUME_BUSY_TIMEOUT = 10;
constexpr auto VOLUME_LEAVE_TIMEOUT = 5;
@ -33,14 +31,14 @@ namespace TEN::Control::Volumes
struct VolumeState
{
VolumeStateStatus Status = VolumeStateStatus::Outside;
Activator Activator = nullptr;
Activator Activator = nullptr;
int Timestamp = 0;
};
void TestVolumes(short roomNumber, const BoundingOrientedBox& box, ActivatorFlags activatorFlag, Activator activator);
void TestVolumes(short itemNumber, const CollisionSetupData* coll = nullptr);
void TestVolumes(short roomNumber, MESH_INFO* mesh);
void TestVolumes(int roomNumber, const BoundingOrientedBox& box, ActivatorFlags activatorFlag, Activator activator);
void TestVolumes(int itemNumber, const CollisionSetupData* coll = nullptr);
void TestVolumes(int roomNumber, MESH_INFO* mesh);
void TestVolumes(CAMERA_INFO* camera);
bool HandleEvent(Event& event, Activator& activator);

View file

@ -1046,16 +1046,20 @@ const std::vector<byte> SaveGame::Build()
{
auto& currVolume = room->TriggerVolumes[j];
std::vector<flatbuffers::Offset<Save::VolumeState>> queue;
auto queue = std::vector<flatbuffers::Offset<Save::VolumeState>>{};
for (int k = 0; k < currVolume.StateQueue.size(); k++)
{
auto& entry = currVolume.StateQueue[k];
int activator = NO_VALUE;
if (std::holds_alternative<short>(entry.Activator))
activator = std::get<short>(entry.Activator);
if (std::holds_alternative<int>(entry.Activator))
{
activator = std::get<int>(entry.Activator);
}
else
{
continue;
}
Save::VolumeStateBuilder volstate{ fbb };
volstate.add_status((int)entry.Status);

View file

@ -1,6 +1,4 @@
#pragma once
#include <functional>
#include <string>
#include "Scripting/Include/VarMapVal.h"
#include "Specific/level.h"
@ -12,14 +10,14 @@ class ScriptInterfaceObjectsHandler
public:
virtual ~ScriptInterfaceObjectsHandler() = default;
[[nodiscard]] virtual short GetIndexByName(const std::string& name) const = 0;
virtual int GetIndexByName(const std::string& name) const = 0;
virtual bool AddName(const std::string& key, VarMapVal val) = 0;
virtual bool NotifyKilled(ItemInfo*) = 0;
virtual bool NotifyKilled(ItemInfo* item) = 0;
virtual void FreeEntities() = 0;
virtual void AssignLara() = 0;
virtual void AssignPlayer() = 0;
virtual bool TryAddColliding(short id) = 0;
virtual bool TryRemoveColliding(short id, bool force = false) = 0;
virtual bool TryAddColliding(int id) = 0;
virtual bool TryRemoveColliding(int id, bool force = false) = 0;
virtual void TestCollidingObjects() = 0;
};

View file

@ -10,7 +10,6 @@ struct ROOM_INFO;
using VarMapVal = std::variant<
int,
short,
std::reference_wrapper<MESH_INFO>,
std::reference_wrapper<LevelCameraInfo>,
std::reference_wrapper<SinkInfo>,

View file

@ -959,9 +959,9 @@ void LogicHandler::ExecuteFunction(const std::string& name, short idOne, short i
void LogicHandler::ExecuteFunction(const std::string& name, TEN::Control::Volumes::Activator activator, const std::string& arguments)
{
sol::protected_function func = (*m_handler.GetState())[ScriptReserved_LevelFuncs][name.c_str()];
if (std::holds_alternative<short>(activator))
if (std::holds_alternative<int>(activator))
{
func(std::make_unique<Moveable>(std::get<short>(activator), true), arguments);
func(std::make_unique<Moveable>(std::get<int>(activator), true), arguments);
}
else
{

View file

@ -26,7 +26,7 @@ using namespace TEN::Effects::Items;
using namespace TEN::Math;
/// Represents a moveable object in the game world.
// Examples include traps, enemies, doors, pickups, and the player. See also @{Objects.LaraObject} for player-specific features.
// Examples include the player, traps, enemies, doors, and pickups. See also @{Objects.LaraObject} for player-specific features.
//
// @tenclass Objects.Moveable
// pragma nostrip
@ -41,14 +41,14 @@ most can just be ignored (see usage).
@function Moveable
@tparam Objects.ObjID object ID
@tparam string name Lua name of the item
@tparam string name Lua name.
@tparam Vec3 position position in level
@tparam Rotation rotation rotation rotation about x, y, and z axes (default Rotation(0, 0, 0))
@tparam int roomNumber the room number the moveable is in (default: calculated automatically).
@tparam int animNumber animation number
@tparam int frameNumber frame number
@tparam int hp HP of item
@tparam int OCB ocb of item
@tparam int hp Hit points.
@tparam int OCB Object code bits.
@tparam table AIBits table with AI bits (default { 0, 0, 0, 0, 0, 0 })
@treturn Moveable A new Moveable object (a wrapper around the new object)
@ -58,8 +58,8 @@ most can just be ignored (see usage).
"test", -- name
Vec3(18907, 0, 21201)) -- position
*/
static std::unique_ptr<Moveable> Create(GAME_OBJECT_ID objID, const std::string& name, const Vec3& pos, const TypeOrNil<Rotation>& rot, TypeOrNil<short> room,
TypeOrNil<int> animNumber, TypeOrNil<int> frameNumber, TypeOrNil<short> hp, TypeOrNil<short> ocb, const TypeOrNil<aiBitsType>& aiBits)
static std::unique_ptr<Moveable> Create(GAME_OBJECT_ID objID, const std::string& name, const Vec3& pos, const TypeOrNil<Rotation>& rot, TypeOrNil<int> room,
TypeOrNil<int> animNumber, TypeOrNil<int> frameNumber, TypeOrNil<int> hp, TypeOrNil<int> ocb, const TypeOrNil<aiBitsType>& aiBits)
{
int movID = CreateItem();
auto scriptMov = std::make_unique<Moveable>(movID, false);
@ -70,10 +70,10 @@ static std::unique_ptr<Moveable> Create(GAME_OBJECT_ID objID, const std::string&
scriptMov->SetObjectID(objID);
if (std::holds_alternative<short>(room))
if (std::holds_alternative<int>(room))
{
scriptMov->SetPosition(pos, false);
scriptMov->SetRoomNumber(std::get<short>(room));
scriptMov->SetRoomNumber(std::get<int>(room));
}
else
{
@ -89,12 +89,12 @@ static std::unique_ptr<Moveable> Create(GAME_OBJECT_ID objID, const std::string&
scriptMov->SetFrameNumber(USE_IF_HAVE(int, frameNumber, 0));
}
if (std::holds_alternative<short>(hp))
if (std::holds_alternative<int>(hp))
{
scriptMov->SetHP(std::get<short>(hp));
scriptMov->SetHP(std::get<int>(hp));
}
scriptMov->SetOcb(USE_IF_HAVE(short, ocb, 0));
scriptMov->SetOcb(USE_IF_HAVE(int, ocb, 0));
scriptMov->SetAIBits(USE_IF_HAVE(aiBitsType, aiBits, aiBitsType{}));
scriptMov->SetColor(ScriptColor(Vector4::One));
mov.CarriedItem = NO_VALUE;
@ -115,7 +115,7 @@ void Moveable::Register(sol::state& state, sol::table& parent)
sol::call_constructor, Create,
sol::meta_function::index, IndexError,
sol::meta_function::new_index, NewIndexError,
sol::meta_function::equal_to, std::equal_to<Moveable const>(),
sol::meta_function::equal_to, std::equal_to<const Moveable>(),
ScriptReserved_GetName, &Moveable::GetName,
ScriptReserved_GetObjectID, &Moveable::GetObjectID,

View file

@ -19,17 +19,15 @@
#include "Scripting/Internal/TEN/Objects/SoundSource/SoundSourceObject.h"
#include "Scripting/Internal/TEN/Objects/Volume/VolumeObject.h"
/***
Moveables, statics, cameras, and so on.
@tentable Objects
@pragma nostrip
*/
/// Objects including moveables, statics, cameras, and others.
// @tentable Objects
// @pragma nostrip
ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
m_handler(lua),
m_table_objects(sol::table(m_handler.GetState()->lua_state(), sol::create))
_handler(lua),
_table_objects(sol::table(_handler.GetState()->lua_state(), sol::create))
{
parent.set(ScriptReserved_Objects, m_table_objects);
parent.set(ScriptReserved_Objects, _table_objects);
/***
Get a moveable by its name.
@ -37,7 +35,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the Moveable as set in, or generated by, Tomb Editor
@treturn Moveable a non-owning Moveable referencing the item.
*/
m_table_objects.set_function(ScriptReserved_GetMoveableByName, &ObjectsHandler::GetByName<Moveable, ScriptReserved_Moveable>, this);
_table_objects.set_function(ScriptReserved_GetMoveableByName, &ObjectsHandler::GetByName<Moveable, ScriptReserved_Moveable>, this);
/***
Get a Static by its name.
@ -45,7 +43,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the mesh as set in, or generated by, Tomb Editor
@treturn Static a non-owning Static referencing the mesh.
*/
m_table_objects.set_function(ScriptReserved_GetStaticByName, &ObjectsHandler::GetByName<Static, ScriptReserved_Static>, this);
_table_objects.set_function(ScriptReserved_GetStaticByName, &ObjectsHandler::GetByName<Static, ScriptReserved_Static>, this);
/***
Get moveables by its slot.
@ -53,7 +51,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam Objects.ObjID slot the unique slot of the Moveable, e.g. `Objects.ObjID.ANIMATING1`
@treturn table table of Moveables referencing the given slot.
*/
m_table_objects.set_function(ScriptReserved_GetMoveablesBySlot, &ObjectsHandler::GetMoveablesBySlot<Moveable>, this);
_table_objects.set_function(ScriptReserved_GetMoveablesBySlot, &ObjectsHandler::GetMoveablesBySlot<Moveable>, this);
/***
Get statics by its slot.
@ -61,7 +59,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam int slot the unique slot of the mesh like 10
@treturn table table of Statics referencing the given slot ID.
*/
m_table_objects.set_function(ScriptReserved_GetStaticsBySlot, &ObjectsHandler::GetStaticsBySlot<Static>, this);
_table_objects.set_function(ScriptReserved_GetStaticsBySlot, &ObjectsHandler::GetStaticsBySlot<Static>, this);
/***
Get rooms by tag.
@ -69,7 +67,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string tag to select rooms by
@treturn table table of Rooms containing the given tag.
*/
m_table_objects.set_function(ScriptReserved_GetRoomsByTag, &ObjectsHandler::GetRoomsByTag<Room>, this);
_table_objects.set_function(ScriptReserved_GetRoomsByTag, &ObjectsHandler::GetRoomsByTag<Room>, this);
/***
Get a Camera by its name.
@ -77,7 +75,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the camera as set in, or generated by, Tomb Editor
@treturn Camera a non-owning Camera referencing the camera.
*/
m_table_objects.set_function(ScriptReserved_GetCameraByName, &ObjectsHandler::GetByName<CameraObject, ScriptReserved_Camera>, this);
_table_objects.set_function(ScriptReserved_GetCameraByName, &ObjectsHandler::GetByName<CameraObject, ScriptReserved_Camera>, this);
/***
Get a Sink by its name.
@ -85,7 +83,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the sink as set in, or generated by, Tomb Editor
@treturn Sink a non-owning Sink referencing the sink.
*/
m_table_objects.set_function(ScriptReserved_GetSinkByName, &ObjectsHandler::GetByName<Sink, ScriptReserved_Sink>, this);
_table_objects.set_function(ScriptReserved_GetSinkByName, &ObjectsHandler::GetByName<Sink, ScriptReserved_Sink>, this);
/***
Get a SoundSource by its name.
@ -93,7 +91,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the sound source as set in, or generated by, Tomb Editor
@treturn SoundSource a non-owning SoundSource referencing the sound source.
*/
m_table_objects.set_function(ScriptReserved_GetSoundSourceByName, &ObjectsHandler::GetByName<SoundSource, ScriptReserved_SoundSource>, this);
_table_objects.set_function(ScriptReserved_GetSoundSourceByName, &ObjectsHandler::GetByName<SoundSource, ScriptReserved_SoundSource>, this);
/***
Get an AIObject by its name.
@ -101,7 +99,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the AIObject as set in, or generated by, Tomb Editor
@treturn AIObject a non-owning SoundSource referencing the AI moveable.
*/
m_table_objects.set_function(ScriptReserved_GetAIObjectByName, &ObjectsHandler::GetByName<AIObject, ScriptReserved_AIObject>, this);
_table_objects.set_function(ScriptReserved_GetAIObjectByName, &ObjectsHandler::GetByName<AIObject, ScriptReserved_AIObject>, this);
/***
Get a Volume by its name.
@ -109,7 +107,7 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the volume as set in, or generated by, Tomb Editor
@treturn Volume a non-owning Volume referencing the room.
*/
m_table_objects.set_function(ScriptReserved_GetVolumeByName, &ObjectsHandler::GetByName<Volume, ScriptReserved_Volume>, this);
_table_objects.set_function(ScriptReserved_GetVolumeByName, &ObjectsHandler::GetByName<Volume, ScriptReserved_Volume>, this);
/***
Get a Room by its name.
@ -117,68 +115,68 @@ ObjectsHandler::ObjectsHandler(sol::state* lua, sol::table& parent) :
@tparam string name the unique name of the room as set in Tomb Editor
@treturn Room a non-owning Room referencing the room.
*/
m_table_objects.set_function(ScriptReserved_GetRoomByName, &ObjectsHandler::GetByName<Room, ScriptReserved_Room>, this);
_table_objects.set_function(ScriptReserved_GetRoomByName, &ObjectsHandler::GetByName<Room, ScriptReserved_Room>, this);
LaraObject::Register(m_table_objects);
LaraObject::Register(_table_objects);
Moveable::Register(*lua, m_table_objects);
Moveable::Register(*lua, _table_objects);
Moveable::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
Static::Register(m_table_objects);
Static::Register(_table_objects);
Static::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
CameraObject::Register(m_table_objects);
CameraObject::Register(_table_objects);
CameraObject::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
Sink::Register(m_table_objects);
Sink::Register(_table_objects);
Sink::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
AIObject::Register(m_table_objects);
AIObject::Register(_table_objects);
AIObject::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); } );
SoundSource::Register(m_table_objects);
SoundSource::Register(_table_objects);
SoundSource::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
Room::Register(m_table_objects);
Room::Register(_table_objects);
Room::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); }
);
Volume::Register(m_table_objects);
Volume::Register(_table_objects);
Volume::SetNameCallbacks(
[this](auto && ... param) { return AddName(std::forward<decltype(param)>(param)...); },
[this](auto && ... param) { return RemoveName(std::forward<decltype(param)>(param)...); });
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_ObjID, kObjIDs);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomFlagID, ROOM_FLAG_IDS);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_RoomReverb, ROOM_REVERB_TYPES);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_WeaponType, WEAPON_TYPES);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_AmmoType, AMMO_TYPES);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_HandStatus, HandStatusMap);
m_handler.MakeReadOnlyTable(m_table_objects, ScriptReserved_MoveableStatus, MOVEABLE_STATUSES);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_ObjID, kObjIDs);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_RoomFlagID, ROOM_FLAG_IDS);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_RoomReverb, ROOM_REVERB_TYPES);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_WeaponType, WEAPON_TYPES);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_AmmoType, AMMO_TYPES);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_HandStatus, HandStatusMap);
_handler.MakeReadOnlyTable(_table_objects, ScriptReserved_MoveableStatus, MOVEABLE_STATUSES);
}
void ObjectsHandler::TestCollidingObjects()
{
// Remove items which can't collide.
for (int itemNumber : m_collidingItemsToRemove)
m_collidingItems.erase(itemNumber);
m_collidingItemsToRemove.clear();
for (int itemNumber : _collidingItemsToRemove)
_collidingItems.erase(itemNumber);
_collidingItemsToRemove.clear();
for (int itemNumber0 : m_collidingItems)
for (int itemNumber0 : _collidingItems)
{
auto& item = g_Level.Items[itemNumber0];
if (!item.Callbacks.OnObjectCollided.empty())
@ -198,17 +196,17 @@ void ObjectsHandler::TestCollidingObjects()
}
}
void ObjectsHandler::AssignLara()
void ObjectsHandler::AssignPlayer()
{
m_table_objects.set(ScriptReserved_Lara, LaraObject(LaraItem->Index, true));
_table_objects.set(ScriptReserved_Lara, LaraObject(LaraItem->Index, true));
}
bool ObjectsHandler::NotifyKilled(ItemInfo* key)
{
auto it = moveables.find(key);
if (it != std::end(moveables))
auto it = _moveables.find(key);
if (it != std::end(_moveables))
{
for (auto* movPtr : moveables[key])
for (auto* movPtr : _moveables[key])
movPtr->Invalidate();
return true;
@ -221,28 +219,28 @@ bool ObjectsHandler::AddMoveableToMap(ItemInfo* key, Moveable* mov)
{
std::unordered_set<Moveable*> movVec;
movVec.insert(mov);
auto it = moveables.find(key);
if (std::end(moveables) == it)
auto it = _moveables.find(key);
if (std::end(_moveables) == it)
{
return moveables.insert(std::pair{ key, movVec }).second;
return _moveables.insert(std::pair{ key, movVec }).second;
}
else
{
moveables[key].insert(mov);
_moveables[key].insert(mov);
return true;
}
}
bool ObjectsHandler::RemoveMoveableFromMap(ItemInfo* key, Moveable* mov)
{
auto it = moveables.find(key);
if (std::end(moveables) != it)
auto it = _moveables.find(key);
if (std::end(_moveables) != it)
{
auto& set = moveables[key];
auto& set = _moveables[key];
bool isErased = static_cast<bool>(set.erase(mov));
if (isErased && set.empty())
isErased = isErased && static_cast<bool>(moveables.erase(key));
isErased = isErased && static_cast<bool>(_moveables.erase(key));
return isErased;
}

View file

@ -17,83 +17,86 @@ public:
bool AddMoveableToMap(ItemInfo* key, Moveable* mov);
bool RemoveMoveableFromMap(ItemInfo* key, Moveable* mov);
bool TryAddColliding(short id) override
bool TryAddColliding(int id) override
{
ItemInfo* item = &g_Level.Items[id];
bool hasName = !(item->Callbacks.OnObjectCollided.empty() && item->Callbacks.OnRoomCollided.empty());
if (hasName && item->Collidable && (item->Status != ITEM_INVISIBLE))
return m_collidingItems.insert(id).second;
const auto& item = g_Level.Items[id];
bool hasName = !(item.Callbacks.OnObjectCollided.empty() && item.Callbacks.OnRoomCollided.empty());
if (hasName && item.Collidable && item.Status != ITEM_INVISIBLE)
return _collidingItems.insert(id).second;
return false;
}
bool TryRemoveColliding(short id, bool force = false) override
bool TryRemoveColliding(int id, bool force = false) override
{
ItemInfo* item = &g_Level.Items[id];
bool hasName = !(item->Callbacks.OnObjectCollided.empty() && item->Callbacks.OnRoomCollided.empty());
if(!force && hasName && item->Collidable && (item->Status != ITEM_INVISIBLE))
const auto& item = g_Level.Items[id];
bool hasName = !(item.Callbacks.OnObjectCollided.empty() && item.Callbacks.OnRoomCollided.empty());
if (!force && hasName && item.Collidable && item.Status != ITEM_INVISIBLE)
return false;
return m_collidingItemsToRemove.insert(id).second;
return _collidingItemsToRemove.insert(id).second;
}
void TestCollidingObjects() override;
private:
LuaHandler m_handler;
// A map between moveables and the engine entities they represent. This is needed
// so that something that is killed by the engine can notify all corresponding
// Lua variables which can then become invalid.
std::unordered_map<ItemInfo *, std::unordered_set<Moveable*>> moveables{};
std::unordered_map<std::string, VarMapVal> m_nameMap{};
std::unordered_map<std::string, short> m_itemsMapName{};
// A set of items that are visible, collidable, and have Lua OnCollide callbacks.
std::unordered_set<short> m_collidingItems{};
std::unordered_set<short> m_collidingItemsToRemove{};
sol::table m_table_objects;
LuaHandler _handler;
// Map between Lua moveables and engine moveables. Needed so that when something is killed,
// TEN can notify all corresponding Lua variables to become invalid.
void AssignLara() override;
std::unordered_map<ItemInfo*, std::unordered_set<Moveable*>> _moveables = {};
std::unordered_map<std::string, VarMapVal> _nameMap = {};
std::unordered_map<std::string, int> _itemsMapName = {};
template <typename R, char const* S>
// Map of moveables that are visible, collidable, and have Lua OnCollide callbacks.
std::unordered_set<int> _collidingItems = {};
std::unordered_set<int> _collidingItemsToRemove = {};
sol::table _table_objects = {};
void AssignPlayer() override;
template <typename R, const char* S>
std::unique_ptr<R> GetByName(const std::string& name)
{
if (!ScriptAssertF(m_nameMap.find(name) != m_nameMap.end(), "{} name not found: {}", S, name))
if (!ScriptAssertF(_nameMap.find(name) != _nameMap.end(), "{} name not found: {}", S, name))
return nullptr;
else
return std::make_unique<R>(std::get<R::IdentifierType>(m_nameMap.at(name)));
return std::make_unique<R>(std::get<R::IdentifierType>(_nameMap.at(name)));
}
template <typename R>
std::vector <std::unique_ptr<R>> GetMoveablesBySlot(GAME_OBJECT_ID objID)
std::vector <std::unique_ptr<R>> GetMoveablesBySlot(GAME_OBJECT_ID objectID)
{
std::vector<std::unique_ptr<R>> items = {};
for (auto& [key, val] : m_nameMap)
auto movs = std::vector<std::unique_ptr<R>>{};
for (const auto& [key, val] : _nameMap)
{
if (!std::holds_alternative<short>(val))
if (!std::holds_alternative<int>(val))
continue;
auto& item = g_Level.Items[GetIndexByName(key)];
if (objID == item.ObjectNumber)
items.push_back(GetByName<Moveable, ScriptReserved_Moveable>(key));
const auto& item = g_Level.Items[GetIndexByName(key)];
if (objectID == item.ObjectNumber)
movs.push_back(GetByName<Moveable, ScriptReserved_Moveable>(key));
}
return items;
return movs;
}
template <typename R>
std::vector <std::unique_ptr<R>> GetStaticsBySlot(int slot)
{
std::vector<std::unique_ptr<R>> items = {};
for (auto& [key, val] : m_nameMap)
auto items = std::vector<std::unique_ptr<R>>{};
for (const auto& [key, value] : _nameMap)
{
if (!std::holds_alternative<std::reference_wrapper<MESH_INFO>>(val))
if (!std::holds_alternative<std::reference_wrapper<MESH_INFO>>(value))
continue;
auto meshInfo = std::get<std::reference_wrapper<MESH_INFO>>(val).get();
auto staticObj = std::get<std::reference_wrapper<MESH_INFO>>(value).get();
if (meshInfo.staticNumber == slot)
if (staticObj.staticNumber == slot)
items.push_back(GetByName<Static, ScriptReserved_Static>(key));
}
@ -103,16 +106,15 @@ private:
template <typename R>
std::vector <std::unique_ptr<R>> GetRoomsByTag(std::string tag)
{
std::vector<std::unique_ptr<R>> rooms = {};
for (auto& [key, val] : m_nameMap)
auto rooms = std::vector<std::unique_ptr<R>>{};
for (const auto& [key, value] : _nameMap)
{
if (!std::holds_alternative<std::reference_wrapper<ROOM_INFO>>(val))
if (!std::holds_alternative<std::reference_wrapper<ROOM_INFO>>(value))
continue;
auto room = std::get<std::reference_wrapper<ROOM_INFO>>(val).get();
auto room = std::get<std::reference_wrapper<ROOM_INFO>>(value).get();
if (std::any_of(room.Tags.begin(), room.Tags.end(),
[&tag](const std::string& value) { return value == tag; }))
if (std::any_of(room.Tags.begin(), room.Tags.end(), [&tag](const std::string& value) { return value == tag; }))
{
rooms.push_back(GetByName<Room, ScriptReserved_Room>(key));
}
@ -121,9 +123,9 @@ private:
return rooms;
}
[[nodiscard]] short GetIndexByName(std::string const& name) const override
int GetIndexByName(std::string const& name) const override
{
return std::get<short>(m_nameMap.at(name));
return std::get<int>(_nameMap.at(name));
}
bool AddName(const std::string& key, VarMapVal val) override
@ -132,18 +134,18 @@ private:
return false;
auto p = std::pair<const std::string&, VarMapVal>(key, val);
return m_nameMap.insert(p).second;
return _nameMap.insert(p).second;
}
bool RemoveName(const std::string& key)
{
return m_nameMap.erase(key);
return _nameMap.erase(key);
}
void FreeEntities() override
{
m_nameMap.clear();
m_collidingItemsToRemove.clear();
m_collidingItems.clear();
_nameMap.clear();
_collidingItemsToRemove.clear();
_collidingItems.clear();
}
};

View file

@ -44,5 +44,5 @@ public:
void Shatter();
private:
MESH_INFO & m_mesh;
MESH_INFO& m_mesh;
};

View file

@ -145,10 +145,9 @@ bool Volume::IsMoveableInside(const Moveable& mov)
{
for (const auto& entry : _volume.StateQueue)
{
// TODO: Use int, not short.
if (std::holds_alternative<short>(entry.Activator))
if (std::holds_alternative<int>(entry.Activator))
{
int id = std::get<short>(entry.Activator);
int id = std::get<int>(entry.Activator);
auto& mov2 = std::make_unique<Moveable>(id);
if (mov2.get()->GetName() == mov.GetName())

View file

@ -1393,7 +1393,7 @@ bool LoadLevel(const std::string& path, bool partial)
InitializeNeighborRoomList();
GetCarriedItems();
GetAIPickups();
g_GameScriptEntities->AssignLara();
g_GameScriptEntities->AssignPlayer();
UpdateProgress(90, partial);
if (!partial)