diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index fc61f140..875fdab6 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -40,6 +40,11 @@ int main() EditorInterface editor; editor.BuildFonts(); + Ref myFramebuffer = CreateRef(true, Vector2(200, 200)); + myFramebuffer->SetTexture(CreateRef(Vector2(200, 200), GL_RGB)); + + Ref myScene = CreateRef(); + while (!Engine::GetCurrentWindow()->ShouldClose()) { Engine::Tick(); @@ -49,8 +54,25 @@ int main() if (Input::IsKeyPressed(GLFW_KEY_F8)) Engine::ExitPlayMode(); - editor.Draw(); + myFramebuffer->Bind(); + myScene->EditorDraw(); + + myFramebuffer->Unbind(); + if (ImGui::Begin("hahahah")) + { + ImVec2 regionAvail = ImGui::GetContentRegionAvail(); + glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); + if (myFramebuffer->GetSize() != viewportPanelSize) + myFramebuffer->QueueResize(viewportPanelSize); + + Ref texture = myFramebuffer->GetTexture(); + ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); + + } + ImGui::End(); + editor.Draw(); + Engine::EndDraw(); } diff --git a/Editor/resources/Scripts/Trigger.wren b/Editor/resources/Scripts/Trigger.wren index e9bada17..87218abf 100644 --- a/Editor/resources/Scripts/Trigger.wren +++ b/Editor/resources/Scripts/Trigger.wren @@ -25,7 +25,6 @@ class TriggerScript is ScriptableEntity { if(isPlayer) { _Activated = true } - } if(_Activated) { var brush = this.GetComponent("Brush") diff --git a/Editor/resources/test.project b/Editor/resources/test.project index 0f6fa6b9..c272e8f8 100644 --- a/Editor/resources/test.project +++ b/Editor/resources/test.project @@ -1 +1,6 @@ -{"DefaultScene":"Scenes/test.scene","Description":"","Name":""} \ No newline at end of file +{ + "DefaultScene":"Scenes/test.scene", + "Description":"", + "Name":"DemoProject", + "EntityDefinition": "lalala.json" +} \ No newline at end of file diff --git a/Editor/src/EditorInterface.cpp b/Editor/src/EditorInterface.cpp index a1aa1845..193d89fa 100644 --- a/Editor/src/EditorInterface.cpp +++ b/Editor/src/EditorInterface.cpp @@ -39,98 +39,12 @@ void EditorInterface::Init() ImGui::DockSpaceOverViewport(viewport, dockspace_flags); //this->filesystem = FileSystemUI(); - - - - } ImVec2 LastSize = ImVec2(); void EditorInterface::DrawViewport() { - /* - if(ImGui::Begin("ShadowMap1")) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - - if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { - auto& light = m_SelectedEntity.GetComponent(); - Ref texture = light.m_Framebuffers[0]->GetTexture(GL_DEPTH_ATTACHMENT); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - } - else { - ImGui::Text("Please select a light entity"); - } - - } - ImGui::End(); - if (ImGui::Begin("ShadowMap2")) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - - if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { - auto& light = m_SelectedEntity.GetComponent(); - Ref texture = light.m_Framebuffers[1]->GetTexture(GL_DEPTH_ATTACHMENT); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - } - else { - ImGui::Text("Please select a light entity"); - } - - } - - ImGui::End(); - if (ImGui::Begin("ShadowMap3")) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - - if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { - auto& light = m_SelectedEntity.GetComponent(); - Ref texture = light.m_Framebuffers[2]->GetTexture(GL_DEPTH_ATTACHMENT); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - } - else { - ImGui::Text("Please select a light entity"); - } - - } - - ImGui::End(); - if (ImGui::Begin("ShadowMap4")) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - glm::vec2 viewportPanelSize = glm::vec2(regionAvail.x, regionAvail.y); - - if (m_IsEntitySelected && m_SelectedEntity.HasComponent()) { - auto& light = m_SelectedEntity.GetComponent(); - Ref texture = light.m_Framebuffers[3]->GetTexture(GL_DEPTH_ATTACHMENT); - ImGui::Image((void*)texture->GetID(), regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - } - else { - ImGui::Text("Please select a light entity"); - } - - } - - ImGui::End(); - - if (ImGui::Begin("SDF FONT")) - { - ImVec2 regionAvail = ImGui::GetContentRegionAvail(); - if (userInterface) - { - auto id = userInterface->font->FontAtlas->GetID(); - ImGui::Image((void*)id, regionAvail, ImVec2(0, 1), ImVec2(1, 0)); - - } - - } - ImGui::End(); - */ ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0)); std::string name = ICON_FA_GAMEPAD + std::string(" Scene"); @@ -198,9 +112,6 @@ void EditorInterface::DrawViewport() tc.Scale = scale; } } - - - } else { @@ -211,6 +122,7 @@ void EditorInterface::DrawViewport() } static int selected = 0; +Entity QueueDeletion; void EditorInterface::DrawEntityTree(Entity e) { ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanAvailWidth; @@ -268,14 +180,15 @@ void EditorInterface::DrawEntityTree(Entity e) m_SelectedEntity = e; m_IsEntitySelected = true; } + if (ImGui::BeginPopupContextItem()) { if (ImGui::Selectable("Remove")) { - Engine::GetCurrentScene()->DestroyEntity(m_SelectedEntity); - m_SelectedEntity = Engine::GetCurrentScene()->GetAllEntities()[0]; + QueueDeletion = e; open = false; } + if (ImGui::Selectable("Move to root")) { auto& p = m_SelectedEntity.GetComponent(); @@ -285,18 +198,19 @@ void EditorInterface::DrawEntityTree(Entity e) p.HasParent = false; } } - //m_SelectedEntity.Add ImGui::Selectable("Save as prefab"); ImGui::EndPopup(); } if (open) { - for (auto child : parent.Children) - DrawEntityTree(child); - - ImGui::TreePop(); - } + // Caching list to prevent deletion while iterating. + std::vector childrens = parent.Children; + for (auto c : childrens) + DrawEntityTree(c); + ImGui::TreePop(); + + } ImGui::PopFont(); } @@ -354,10 +268,12 @@ void EditorInterface::DrawSceneTree() // Unselect delted entity. m_SelectedEntity = scene->GetAllEntities().at(0); } - ImGui::EndChild(); + } + ImGui::EndChild(); ImGui::Separator(); + // Draw a tree of entities. std::vector entities = scene->GetAllEntities(); for (Entity e : entities) @@ -379,6 +295,7 @@ void EditorInterface::DrawSceneTree() { // Recursively draw childrens. DrawEntityTree(e); + } // Pop font. @@ -389,9 +306,19 @@ void EditorInterface::DrawSceneTree() // ImGui::EndPopup(); } - + // Delete entity + if (QueueDeletion.GetHandle() != 0) + { + Engine::GetCurrentScene()->DestroyEntity(QueueDeletion); + + if(m_SelectedEntity == QueueDeletion) + m_SelectedEntity = scene->GetAllEntities().at(0); + + QueueDeletion = Entity{ (entt::entity)0, scene.get() }; + ImGui::TreePop(); + } + ImGui::End(); } - ImGui::End(); } @@ -1144,6 +1071,7 @@ void NewProject() } +ProjectInterface pInterface; void OpenProject() { // Parse the project and load it. @@ -1160,7 +1088,7 @@ void OpenProject() project->FullPath = projectPath; Engine::LoadProject(project); - + pInterface.m_CurrentProject = project; // Create new interface named test. //userInterface = UI::UserInterface::New("test"); @@ -1368,7 +1296,6 @@ void EditorInterface::Draw() filesystem.Draw(); filesystem.DrawDirectoryExplorer(); - ProjectInterface pInterface; pInterface.DrawEntitySettings(); if(m_ShowImGuiDemo) diff --git a/Editor/src/FileSystemUI.cpp b/Editor/src/FileSystemUI.cpp index f213f78a..ad52fd46 100644 --- a/Editor/src/FileSystemUI.cpp +++ b/Editor/src/FileSystemUI.cpp @@ -217,9 +217,7 @@ void FileSystemUI::DrawDirectoryExplorer() { if (ImGui::Button("Refresh")) FileSystem::Scan(); - ImGui::SameLine(); - for (int i = paths.size() - 1; i > 0; i--) { if (i != paths.size()) ImGui::SameLine(); diff --git a/Editor/src/ProjectInterface.cpp b/Editor/src/ProjectInterface.cpp index c874e4cb..b69957eb 100644 --- a/Editor/src/ProjectInterface.cpp +++ b/Editor/src/ProjectInterface.cpp @@ -31,20 +31,35 @@ void ProjectInterface::DrawCreatePointEntity() } } - FGDPointEntity newEntity; const char* items[] = { "String", "Integer", "Float", "Boolean"}; void ProjectInterface::DrawEntitySettings() { + if (!m_CurrentProject) + return; + if (ImGui::Begin("Entity definitions")) { ImGui::Text("This is the entity definition used by trenchbroom. This files allows you to see your entities inside Trenchbroom"); + ImGui::Text("Trenchbroom path:"); + ImGui::SameLine(); + + + ImGuiTextSTD("", m_CurrentProject->TrenchbroomPath); + if (ImGui::Button("Browse")) + { + std::string path = FileDialog::OpenFile("*.exe"); + if (path != "") + { + path += "/../"; + m_CurrentProject->TrenchbroomPath = path; + } + } Ref file = Engine::GetProject()->EntityDefinitionsFile; - auto flags = ImGuiWindowFlags_NoTitleBar; if (ImGui::BeginPopupModal("Create new point entity", NULL, flags)) { @@ -82,14 +97,13 @@ void ProjectInterface::DrawEntitySettings() idx++; ImGui::TableNextColumn(); } - if (ImGui::Button("Add new property")) { + if (ImGui::Button("Add new property")) + { newEntity.Properties.push_back(ClassProperty()); } ImGui::EndTable(); - } - ImGui::Button("Create"); ImGui::SameLine(); @@ -99,6 +113,19 @@ void ProjectInterface::DrawEntitySettings() ImGui::EndPopup(); } + + if (ImGui::Button("Export")) + { + file->Export(); + } + + ImGui::SameLine(); + + if (ImGui::Button("Save")) + { + file->Save(); + } + ImGui::PushStyleVar(ImGuiStyleVar_WindowMinSize, ImVec2(0, 100)); if (ImGui::BeginTabBar("##Tabs", ImGuiTabBarFlags_None)) { @@ -106,6 +133,7 @@ void ProjectInterface::DrawEntitySettings() { ImVec2 avail = ImGui::GetContentRegionAvail(); avail.y *= .8; + ImGui::BeginChild("table_child", avail, false); if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) { @@ -130,23 +158,99 @@ void ProjectInterface::DrawEntitySettings() } ImGui::EndTable(); - } ImGui::EndChild(); ImGui::EndTabItem(); } if (ImGui::BeginTabItem("Brush entities")) { - ImGui::Text("ID: 0123456789"); + ImVec2 avail = ImGui::GetContentRegionAvail(); + avail.y *= .8; + ImGui::BeginChild("table_child", avail, false); + if (ImGui::BeginTable("nested1", 4, ImGuiTableFlags_Borders | ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_Hideable)) + { + ImGui::TableSetupColumn("Name"); + ImGui::TableSetupColumn("Desciption"); + ImGui::TableSetupColumn("Settings"); + ImGui::TableSetupColumn("Script"); + ImGui::TableHeadersRow(); + ImGui::TableNextColumn(); + + int i = 0; + for (auto& pE : file->BrushEntities) + { + ImGuiTextSTD("##Name" + std::to_string(i), pE.Name); + ImGui::TableNextColumn(); + + ImGuiTextSTD("Desc" + std::to_string(i), pE.Description); + ImGui::TableNextColumn(); + + ImGui::Checkbox(std::string("Visible##" + std::to_string(i)).c_str(), &pE.Visible); + ImGui::SameLine(); + ImGui::Checkbox(std::string("Solid" + std::to_string(i)).c_str(), &pE.Solid); + ImGui::SameLine(); + ImGui::Checkbox(std::string("Trigger" + std::to_string(i)).c_str(), &pE.IsTrigger); + + ImGui::TableNextColumn(); + + ImGuiTextSTD("Script##" + std::to_string(i), pE.Script); + if (ImGui::BeginDragDropTarget()) + { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Script")) + { + char* file = (char*)payload->Data; + std::string fullPath = std::string(file, 256); + pE.Script = FileSystem::AbsoluteToRelative(fullPath); + } + + ImGui::EndDragDropTarget(); + } + ImGui::TableNextColumn(); + + i++; + } + + ImGui::TableNextColumn(); + ImGui::EndTable(); + + if (ImGui::BeginPopupModal("CreateBrush", NULL, flags)) + { + ImGuiTextSTD("Name", newEntity.Name); + ImGuiTextMultiline("Description", newEntity.Description); + + bool isSolid = true; + bool isTrigger = false; + bool isVisible = true; + ImGui::Checkbox("Is Solid", &isSolid); + ImGui::Checkbox("Is Trigger", &isTrigger); + ImGui::Checkbox("Is Visible", &isVisible); + + if (ImGui::Button("Create")) + { + + } + + ImGui::SameLine(); + + if (ImGui::Button("Cancel")) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); + } + + if (ImGui::Button("Add new")) + { + file->BrushEntities.push_back(FGDBrushEntity("New brush")); + } + + } + ImGui::EndChild(); ImGui::EndTabItem(); } ImGui::EndTabBar(); } ImGui::PopStyleVar(); - - if (ImGui::Button("Add new")) - ImGui::OpenPopup("Create new point entity"); } ImGui::End(); } \ No newline at end of file diff --git a/Nuake/Engine.cpp b/Nuake/Engine.cpp index 8da4a3b3..0e0a599d 100644 --- a/Nuake/Engine.cpp +++ b/Nuake/Engine.cpp @@ -14,6 +14,7 @@ Ref Engine::CurrentProject; Ref Engine::CurrentWindow; + float Engine::m_LastFrameTime = 0.0f; float Engine::m_FixedUpdateRate = 1.0 / 144.0f; float Engine::m_FixedUpdateDifference = 0.f; @@ -26,6 +27,7 @@ void Engine::Init() PhysicsManager::Get()->Init(); Logger::Log("Physics initialized"); + // Creates the window CurrentWindow = Window::Get(); Logger::Log("Window initialized"); @@ -46,7 +48,7 @@ void Engine::Tick() Timestep timestep = time - m_LastFrameTime; m_LastFrameTime = time; - // Play mode update vs editor update. + // Play mode update all the entities, Editor does not. if (Engine::IsPlayMode) { CurrentWindow->Update(timestep); @@ -79,8 +81,11 @@ void Engine::EnterPlayMode() void Engine::ExitPlayMode() { // Dont trigger exit if already not in play mode. - if (IsPlayMode) + if (IsPlayMode) { GetCurrentScene()->OnExit(); + Input::ShowMouse(); + } + IsPlayMode = false; } diff --git a/Nuake/Engine.h b/Nuake/Engine.h index 035cde98..481f6c92 100644 --- a/Nuake/Engine.h +++ b/Nuake/Engine.h @@ -10,33 +10,32 @@ /* TODOS: * * Engine: -* Trigger zones from trenchbroom -* Scripting API vectors operation * Scripting API for all component * Scripting API for editing UI maybe * Launch game standalone * Fix physics system * trenchbroom physics element * -* Editor: -* File browser refact * */ +// Welcome to the Nuake source code. This is the entry point for the engine. + class Engine { private: - static float m_LastFrameTime; static Ref CurrentWindow; static Ref CurrentProject; static Ref CurrentScene; + + static float m_LastFrameTime; static float m_FixedUpdateRate; static float m_FixedUpdateDifference; public: - static bool IsPlayMode; // True if is playing a scene + static bool IsPlayMode; // True if currently playing the game. - static void Init(); // Initialize the systems - static void Tick(); // Update every system, called once per frame. - static void Close(); // Close the systems + static void Init(); // Initialize the engine. + static void Tick(); // Updates everything, called everyframe. + static void Close(); // Shutdown the engine. static void EnterPlayMode(); // Start the game static void ExitPlayMode(); // Stops the game diff --git a/Nuake/src/Resource/FGD/FDGSerializer.h b/Nuake/src/Resource/FGD/FDGSerializer.h index b7c3f0fc..55a2885f 100644 --- a/Nuake/src/Resource/FGD/FDGSerializer.h +++ b/Nuake/src/Resource/FGD/FDGSerializer.h @@ -7,6 +7,6 @@ public: static bool BeginFGDFile(const std::string path); static bool SerializeClass(FGDClass fgdClass); - + static bool SerializeBrush(FGDBrushEntity fgdClass); static bool EndFGDFile(); }; \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDClass.h b/Nuake/src/Resource/FGD/FGDClass.h index 37bda367..2b415895 100644 --- a/Nuake/src/Resource/FGD/FGDClass.h +++ b/Nuake/src/Resource/FGD/FGDClass.h @@ -1,8 +1,10 @@ #pragma once #include "ClassProperty.h" +#include "src/Resource/Serializable.h" #include #include + class FGDBaseEntity { public: @@ -10,21 +12,61 @@ public: std::vector Properties; }; -class FGDBrushEntity + +class FGDBrushEntity : ISerializable { public: std::string Name; std::string Description; - bool Transparent = false; - bool Collision = false; + + bool Visible = false; + bool Solid = false; bool IsTrigger = false; std::string Script = ""; + std::vector Properties; + FGDBrushEntity() + { + Name = ""; + Description = ""; + } + + FGDBrushEntity(const std::string& name) + { + Name = name; + Description = ""; + } + + json Serialize() override + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Name); + SERIALIZE_VAL(Description); + SERIALIZE_VAL(Visible); + SERIALIZE_VAL(Solid); + SERIALIZE_VAL(IsTrigger); + SERIALIZE_VAL(Script); + END_SERIALIZE(); + } + + bool Deserialize(const std::string& str) override + { + BEGIN_DESERIALIZE(); + Name = j["Name"]; + Description = j["Description"]; + Visible = j["Visible"]; + Solid = j["Solid"]; + IsTrigger = j["IsTrigger"]; + Script = j["Script"]; + return true; + } + FGDBaseEntity BaseClass; }; -class FGDPointEntity + +class FGDPointEntity : ISerializable { public: std::string Name; @@ -32,6 +74,20 @@ public: std::string Prefab; std::vector Properties; FGDBaseEntity BaseClass; + + json Serialize() override + { + BEGIN_SERIALIZE(); + SERIALIZE_VAL(Name); + SERIALIZE_VAL(Description); + SERIALIZE_VAL(Prefab); + END_SERIALIZE(); + } + + bool Deserialize(const std::string& str) override + { + return true; + } }; class FGDClass { @@ -42,6 +98,7 @@ public: std::vector Properties; FGDClass(FGDClassType type, const std::string& name, const std::string& desc); + void AddProperty(ClassProperty prop); void RemoveProperty(const std::string name); }; \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDFile.cpp b/Nuake/src/Resource/FGD/FGDFile.cpp index 09c5e6b2..102ac45e 100644 --- a/Nuake/src/Resource/FGD/FGDFile.cpp +++ b/Nuake/src/Resource/FGD/FGDFile.cpp @@ -1,22 +1,26 @@ #include "FGDFile.h" #include +#include +#include "Engine.h" FGDFile::FGDFile(const std::string path) { - this->path = path; + this->Path = path; this->BaseEntities = std::vector(); this->BrushEntities = std::vector(); this->PointEntities = std::vector(); } + FGDFile::FGDFile() { - this->path = ""; + this->Path = ""; this->BaseEntities = std::vector(); this->BrushEntities = std::vector(); this->PointEntities = std::vector(); + // TODO: Remove this, debugging stuff. FGDPointEntity newEnt; newEnt.Name = "Light"; newEnt.Description = "A Nuake PBR light"; @@ -24,9 +28,67 @@ FGDFile::FGDFile() this->PointEntities.push_back(newEnt); } + bool FGDFile::Save() { - FGDSerializer::BeginFGDFile(this->path); + BEGIN_SERIALIZE(); + + int i = 0; + for (auto& c : this->BrushEntities) + { + j["BrushEntities"][i] = c.Serialize(); + i++; + } + + i = 0; + for (auto& c : this->PointEntities) + { + j["PointEntities"][i] = c.Serialize(); + i++; + } + + // Write to file. + FileSystem::BeginWriteFile(Path); + FileSystem::WriteLine(j.dump(4)); + FileSystem::EndWriteFile(); + + return true; +} + +bool FGDFile::SaveAs() +{ + return false; +} + + +void FGDFile::AddClass(FGDClass fgdClass) +{ + //this->Classes.push_back(fgdClass); +} + + +void FGDFile::RemoveClass(const std::string& name) +{ + //int idx = 0; + //for (auto& c : Classes) + //{ + //if (c.Name == name) + //Classes.erase(Classes.begin() + idx); + + //idx++; + //} +} + + +// Exports the FGD data into an fgd file that Trenchbroom can read. +// Should be exported in the Trenchbroom directory directly. /Games/project_name +bool FGDFile::Export() +{ + Ref project = Engine::GetProject(); + std::string path = project->TrenchbroomPath + "games/" + project->Name + "/" + project->Name + ".fgd"; + + + FGDSerializer::BeginFGDFile(path); for (auto& b : BaseEntities) { @@ -40,28 +102,13 @@ bool FGDFile::Save() for (auto& b : BrushEntities) { - + FGDSerializer::SerializeBrush(b); } + //for(auto& c : Classes) // FGDSerializer::SerializeClass(c); FGDSerializer::EndFGDFile(); + return true; -} - -void FGDFile::AddClass(FGDClass fgdClass) -{ - //this->Classes.push_back(fgdClass); -} - -void FGDFile::RemoveClass(const std::string& name) -{ - //int idx = 0; - //for (auto& c : Classes) - //{ - //if (c.Name == name) - //Classes.erase(Classes.begin() + idx); - - //idx++; - //} -} +} \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDFile.h b/Nuake/src/Resource/FGD/FGDFile.h index 7fd54efa..6921297d 100644 --- a/Nuake/src/Resource/FGD/FGDFile.h +++ b/Nuake/src/Resource/FGD/FGDFile.h @@ -6,17 +6,18 @@ class FGDFile : ISerializable{ public: - std::string path; + std::string Path; std::vector PointEntities; std::vector BrushEntities; std::vector BaseEntities; FGDFile(const std::string path); - FGDFile(); + bool Export(); bool Save(); + bool SaveAs(); void AddClass(FGDClass fgdClass); void RemoveClass(const std::string& name); @@ -30,6 +31,24 @@ public: bool Deserialize(const std::string& str) { + BEGIN_DESERIALIZE(); + + if (j.contains("BrushEntities")) + { + for (auto& brush : j["BrushEntities"]) + { + FGDBrushEntity brushEntity = FGDBrushEntity(); + brushEntity.Deserialize(brush.dump()); + BrushEntities.push_back(brushEntity); + } + + } + + if (j.contains("PointEntities")) + { + + } + return true; } }; \ No newline at end of file diff --git a/Nuake/src/Resource/FGD/FGDSerializer.cpp b/Nuake/src/Resource/FGD/FGDSerializer.cpp index c5d94144..0f708834 100644 --- a/Nuake/src/Resource/FGD/FGDSerializer.cpp +++ b/Nuake/src/Resource/FGD/FGDSerializer.cpp @@ -8,6 +8,8 @@ bool FGDSerializer::BeginFGDFile(const std::string path) return true; } + + bool FGDSerializer::SerializeClass(FGDClass fgdClass) { std::string line = "@"; @@ -51,6 +53,42 @@ bool FGDSerializer::SerializeClass(FGDClass fgdClass) return true; } +bool FGDSerializer::SerializeBrush(FGDBrushEntity fgdClass) +{ + std::string line = "@"; + line += "SolidClass = "; + line += fgdClass.Name + " : \"" + fgdClass.Description + "\""; + + // Exit early + if (fgdClass.Properties.size() == 0) + { + line += " [] \n"; + FileSystem::WriteLine(line); + return true; + } + + // Properties here. + line += "\n [ \n"; + for (auto& p : fgdClass.Properties) + { + // E.g: myProp(integer) : "description" + line += " "; // Tabulation + line += p.name; + line += "("; + if (p.type == ClassPropertyType::Integer) + line += "integer"; + line += ") : "; + line += "\"" + p.description + "\""; + line += "\n"; + + } + + line += "]"; + + FileSystem::WriteLine(line); + return false; +} + bool FGDSerializer::EndFGDFile() { FileSystem::EndWriteFile(); diff --git a/Nuake/src/Resource/Prefab.h b/Nuake/src/Resource/Prefab.h index 9c648236..2e5ffe52 100644 --- a/Nuake/src/Resource/Prefab.h +++ b/Nuake/src/Resource/Prefab.h @@ -1,7 +1,22 @@ #pragma once - +#include +#include +#include class Prefab { +public: + std::string Path; + std::vector Entities; + Prefab() + { + Path = ""; + Entities = std::vector(); + } + + void AddEntity(Entity& entity) + { + Entities.push_back(entity); + } }; \ No newline at end of file diff --git a/Nuake/src/Resource/Project.cpp b/Nuake/src/Resource/Project.cpp index c8b7521b..84bc309d 100644 --- a/Nuake/src/Resource/Project.cpp +++ b/Nuake/src/Resource/Project.cpp @@ -9,6 +9,7 @@ Project::Project(const std::string Name, const std::string Description, const st this->Name = Name; this->Description = Description; this->FullPath = FullPath; + this->TrenchbroomPath = ""; if (defaultScenePath != "") { @@ -26,6 +27,7 @@ Project::Project() this->Name = ""; this->Description = ""; this->FullPath = ""; + this->TrenchbroomPath = ""; this->EntityDefinitionsFile = CreateRef(); } @@ -37,15 +39,14 @@ void Project::Save() void Project::SaveAs(const std::string FullPath) { - json j = Serialize(); - // Dump. std::string serialized_string = j.dump(); - // write to file. + // TODO: Use file interface here... + // Write to file. std::ofstream projectFile; - projectFile.open(FullPath); - projectFile << serialized_string; + projectFile.open(FullPath); + projectFile << serialized_string; projectFile.close(); } @@ -85,40 +86,50 @@ Ref Project::Load(std::string path) json Project::Serialize() { BEGIN_SERIALIZE(); - SERIALIZE_VAL(Name); - SERIALIZE_VAL(Description); - SERIALIZE_VAL_LBL("DefaultScene", DefaultScene->Path); + SERIALIZE_VAL(Name); + SERIALIZE_VAL(Description); + SERIALIZE_VAL_LBL("DefaultScene", DefaultScene->Path); + SERIALIZE_VAL_LBL("EntityDefinition", EntityDefinitionsFile->Path); END_SERIALIZE(); } bool Project::Deserialize(const std::string& str) { - json j = json::parse(str); - if (!j.contains("Name")) - return false; - if (!j.contains("Description")) + BEGIN_DESERIALIZE(); + + if (!j.contains("Name") || !j.contains("Description")) return false; - this->DefaultScene = Scene::New(); + Name = j["Name"]; + Description = j["Description"]; - if (j.contains("DefaultScene")) + DefaultScene = Scene::New(); + + // Load default scene, a project can have no default scene set. + if (!j.contains("DefaultScene")) + return true; + + std::string scenePath = j["DefaultScene"]; + if (scenePath == "") // Not set correctly. + return true; + + std::string sceneContent = FileSystem::ReadFile(scenePath, false); + if (!DefaultScene->Deserialize(sceneContent)) { - std::string scenePath = j["DefaultScene"]; - if (scenePath != "") - { - std::string sceneContent = FileSystem::ReadFile(scenePath, false); - if (!this->DefaultScene->Deserialize(sceneContent)) - { - Logger::Log("Error loading scene: " + scenePath, CRITICAL); - } - else - { - this->DefaultScene->Path = scenePath; - Logger::Log("Successfully loaded scene: " + scenePath); - } - } - + Logger::Log("Error loading scene: " + scenePath, CRITICAL); + return false; } + if (j.contains("EntityDefinition")) + { + std::string path = j["EntityDefinition"]; + EntityDefinitionsFile = CreateRef(path); + std::string content = FileSystem::ReadFile(path, false); + EntityDefinitionsFile->Deserialize(content); + } + + DefaultScene->Path = scenePath; + Logger::Log("Successfully loaded scene: " + scenePath); + return true; // Success } diff --git a/Nuake/src/Resource/Project.h b/Nuake/src/Resource/Project.h index 780794ab..4b5ed6da 100644 --- a/Nuake/src/Resource/Project.h +++ b/Nuake/src/Resource/Project.h @@ -13,6 +13,9 @@ public: std::string Description; std::string FullPath; + // Path of the trenchbroom .exe folder + std::string TrenchbroomPath = ""; + Ref DefaultScene; Ref EntityDefinitionsFile; @@ -28,5 +31,4 @@ public: json Serialize() override; bool Deserialize(const std::string& str) override; - }; \ No newline at end of file diff --git a/Nuake/src/Scene/Scene.h b/Nuake/src/Scene/Scene.h index a0273362..6c1e44b9 100644 --- a/Nuake/src/Scene/Scene.h +++ b/Nuake/src/Scene/Scene.h @@ -12,16 +12,19 @@ #include "src/UI/UserInterface.h" #include "../Core/Maths.h" #include + class Entity; class Scene : public ISerializable { friend Entity; - private: - std::string Name; + std::string Name; // Name of the scene bool has_changed = true; + // The systems are what updates the components. + // You can create a new system(see 'Systems/'.) and register it + // In the scene constructor. std::vector> m_Systems; Ref m_Environement; diff --git a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp index 01db11e9..7730e072 100644 --- a/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp +++ b/Nuake/src/Scene/Systems/QuakeMapBuilder.cpp @@ -304,12 +304,14 @@ void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) std::string target = ""; std::string targetname = ""; - for (int i = 0; i < entity_inst->property_count; i++) { + for (int i = 0; i < entity_inst->property_count; i++) + { property* prop = &(entity_inst->properties)[i]; std::string key = prop->key; std::string value = prop->value; - if (key == "origin") { + if (key == "origin") + { // Position std::vector splits = split(value, ' '); @@ -334,11 +336,13 @@ void QuakeMapBuilder::BuildQuakeMap(Entity& ent, bool Collisions) isTrigger = true; newEntity.GetComponent().Name = "Trigger " + std::to_string(i); } - else if (value == "func_any") { + else if (value == "func_any") + { isFunc = true; newEntity.GetComponent().Name = "func_any " + std::to_string(i); } - else if (value == "position") { + else if (value == "position") + { isPos = true; } } diff --git a/Nuake/src/Scene/Systems/System.h b/Nuake/src/Scene/Systems/System.h index e9bd56ad..958fbe84 100644 --- a/Nuake/src/Scene/Systems/System.h +++ b/Nuake/src/Scene/Systems/System.h @@ -15,5 +15,4 @@ public: virtual void FixedUpdate(Timestep ts) = 0; virtual void Exit() = 0; - }; \ No newline at end of file diff --git a/Nuake/src/Scripting/ScriptingEngine.cpp b/Nuake/src/Scripting/ScriptingEngine.cpp index eaeffb51..144ae20b 100644 --- a/Nuake/src/Scripting/ScriptingEngine.cpp +++ b/Nuake/src/Scripting/ScriptingEngine.cpp @@ -59,7 +59,19 @@ bool hasEnding(std::string const& fullString, std::string const& ending) { WrenLoadModuleResult myLoadModule(WrenVM* vm, const char* name) { WrenLoadModuleResult result = { 0 }; + std::string sname = name; + std::string s = "tititoto"; std::string path = "resources/" + std::string(name); + + if (s.rfind("Nuake/", 0) == 0) + { + path = "resources/" + std::string(name); + } + else + { + path = FileSystem::Root + name; + } + if(!hasEnding(path, ".wren")) path += ".wren";