diff --git a/Editor/resources/Scripts/Scene.wren b/Editor/resources/Scripts/Scene.wren index b6bfd84a..1464c3c3 100644 --- a/Editor/resources/Scripts/Scene.wren +++ b/Editor/resources/Scripts/Scene.wren @@ -4,7 +4,9 @@ import "Nuake:Math" for Vector3 class Scene { foreign static GetEntityID(name) - + foreign static AddEntity(name) + foreign static AddPrefab(prefabPath) + static GetEntity(name) { var entId = Scene.GetEntityID(name) var ent = Entity.new(entId) diff --git a/Nuake/src/Core/FileSystem.cpp b/Nuake/src/Core/FileSystem.cpp index 92147225..3c5e9661 100644 --- a/Nuake/src/Core/FileSystem.cpp +++ b/Nuake/src/Core/FileSystem.cpp @@ -220,7 +220,7 @@ namespace Nuake std::string FileSystem::GetFileNameFromPath(const std::string& path) { - const auto split = String::Split(path, '\\'); + const auto& split = String::Split(path, '\\'); return String::Split(split[split.size() - 1], '.')[0]; } diff --git a/Nuake/src/Scene/Scene.cpp b/Nuake/src/Scene/Scene.cpp index ca524e05..575d8781 100644 --- a/Nuake/src/Scene/Scene.cpp +++ b/Nuake/src/Scene/Scene.cpp @@ -179,12 +179,14 @@ namespace Nuake { Entity Scene::GetEntity(const std::string& name) { std::vector allEntities; - auto view = m_Registry.view(); + const auto& view = m_Registry.view(); for (auto e : view) { - auto [transform, namec] = view.get(e); + const auto& namec = view.get(e); if (namec.Name == name) + { return Entity{ e, this }; + } } return Entity(); @@ -197,16 +199,50 @@ namespace Nuake { Entity Scene::CreateEntity(const std::string& name, int id) { + if (name.empty()) + { + Logger::Log("[Scene] Failed to create entity. Entity name cannot be empty."); + return Entity(); + } + + std::string entityName; + if (GetEntity(name) != Entity()) + { + entityName = name; + } + else + { + // Try to generate a unique name + for (uint32_t i = 1; i < 2048; i++) + { + const std::string& entityEnumName = name + std::to_string(i); + const auto& entityId = GetEntity(entityEnumName).GetHandle(); + if (entityId != -1) + { + entityName = entityEnumName; + break; + } + } + + if (entityName.empty()) // We ran out of names!!! + { + Logger::Log("[Scene] Failed to create entity. Limit reached with name: " + name, CRITICAL); + return Entity(); + } + } + Entity entity = { m_Registry.create(), this }; + + // Add all mandatory component. An entity cannot exist without these. entity.AddComponent(); entity.AddComponent(); entity.AddComponent(); NameComponent& nameComponent = entity.AddComponent(); - nameComponent.Name = name; + nameComponent.Name = entityName; nameComponent.ID = id; - Logger::Log("Created entity: " + nameComponent.Name, LOG_TYPE::VERBOSE); + Logger::Log("[Scene] Entity created with name: " + nameComponent.Name, LOG_TYPE::VERBOSE); return entity; } diff --git a/Nuake/src/Scripting/Modules/SceneModule.h b/Nuake/src/Scripting/Modules/SceneModule.h index fbaa0ac5..96976c34 100644 --- a/Nuake/src/Scripting/Modules/SceneModule.h +++ b/Nuake/src/Scripting/Modules/SceneModule.h @@ -21,6 +21,7 @@ #include #include #include +#include namespace Nuake { namespace ScriptAPI { @@ -33,6 +34,8 @@ namespace Nuake { void RegisterModule(WrenVM* vm) override { + RegisterMethod("CreateEntity(_)", (void*)CreateEntity); + RegisterMethod("AddPrefab(_)", (void*)AddPrefab); RegisterMethod("GetEntityID(_)", (void*)GetEntity); RegisterMethod("EntityHasComponent(_,_)", (void*)EntityHasComponent); @@ -61,6 +64,13 @@ namespace Nuake { RegisterMethod("BrushGetTargetsCount_(_)", (void*)BrushGetTargetsCount); } + static void CreateEntity(WrenVM* vm) + { + const std::string name = wrenGetSlotString(vm, 1); + const int entity = Engine::GetCurrentScene()->CreateEntity(name).GetHandle(); + wrenSetSlotDouble(vm, 0, entity); + } + static void GetEntity(WrenVM* vm) { std::string name = wrenGetSlotString(vm, 1); @@ -68,6 +78,37 @@ namespace Nuake { wrenSetSlotDouble(vm, 0, handle); } + static void AddPrefab(WrenVM* vm) + { + const std::string& prefabPath = wrenGetSlotString(vm, 1); + if (prefabPath.empty()) + { + Logger::Log("[Scripting] Cannot add prefab with an empty path.", CRITICAL); + wrenSetSlotDouble(vm, 0, -1); // -1 is an empty entity. + return; + } + + const std::string& prefabName = wrenGetSlotString(vm, 1); + if (prefabName.empty()) + { + Logger::Log("[Scripting] Cannot add prefab with an empty name.", CRITICAL); + wrenSetSlotDouble(vm, 0, -1); // -1 is an empty entity. + return; + } + + if (!FileSystem::FileExists(prefabPath)) + { + Logger::Log("[Scripting] Cannot add prefab. File not found: " + prefabPath, CRITICAL); + return; + } + + Entity& newEntity = Engine::GetCurrentScene()->CreateEntity(prefabName); + auto& prefabComponent = newEntity.AddComponent(); + prefabComponent.PrefabInstance = Prefab::New(prefabPath); + + wrenSetSlotDouble(vm, 0, newEntity.GetHandle()); + } + static void EntityHasComponent(WrenVM* vm) { double handle = wrenGetSlotDouble(vm, 1); diff --git a/Nuake/src/Scripting/ScriptingEngine.cpp b/Nuake/src/Scripting/ScriptingEngine.cpp index 1c286233..7bac7069 100644 --- a/Nuake/src/Scripting/ScriptingEngine.cpp +++ b/Nuake/src/Scripting/ScriptingEngine.cpp @@ -20,7 +20,6 @@ namespace Nuake { const char* module, const int line, const char* msg) { - Logger::Log("YO"); switch (errorType) { case WREN_ERROR_COMPILE: