diff --git a/src/gamedata/items/CMakeLists.txt b/src/gamedata/items/CMakeLists.txt index bba3521..c3064f0 100644 --- a/src/gamedata/items/CMakeLists.txt +++ b/src/gamedata/items/CMakeLists.txt @@ -4,7 +4,7 @@ find_package(Bullet REQUIRED) find_package(nlohmann_json REQUIRED) find_package(OgreProcedural REQUIRED CONFIG) find_package(flecs REQUIRED CONFIG) -add_library(items STATIC items.cpp property_editor.cpp property_editor_color_rect.cpp harbour.cpp temple.cpp town.cpp) +add_library(items STATIC items.cpp property_editor.cpp property_editor_color_rect.cpp property_editor_npc.cpp harbour.cpp temple.cpp town.cpp) target_include_directories(items PUBLIC . ${CMAKE_SOURCE_DIR}/src/FastNoiseLite) target_link_libraries(items PRIVATE flecs::flecs_static diff --git a/src/gamedata/items/items.cpp b/src/gamedata/items/items.cpp index ed68fa2..21fdcca 100644 --- a/src/gamedata/items/items.cpp +++ b/src/gamedata/items/items.cpp @@ -17,7 +17,6 @@ #include "harbour.h" #include "temple.h" #include "town.h" -#include "property_editor.h" #include "items.h" #include namespace ECS diff --git a/src/gamedata/items/property_editor.cpp b/src/gamedata/items/property_editor.cpp index b21c8d0..417b58b 100644 --- a/src/gamedata/items/property_editor.cpp +++ b/src/gamedata/items/property_editor.cpp @@ -1,6 +1,13 @@ #include +#include +#include "Components.h" +#include "GameData.h" +#include "EditorGizmoModule.h" +#include "TerrainModule.h" +#include "town.h" #include "property_editor.h" #include "property_editor_color_rect.h" +#include "property_editor_npc.h" namespace ECS { @@ -66,8 +73,11 @@ struct LuaScriptPropertyEditor : DPropertyEditor { ImGui::TableSetColumnIndex(0); ImGui::Text("%s", ptr.back().c_str()); ImGui::TableSetColumnIndex(1); + ImGui::PushItemWidth(-FLT_MIN); + ImGui::BeginChild("##multilineEdit", ImVec2(0, 0), false, + ImGuiWindowFlags_HorizontalScrollbar); ImGui::InputTextMultiline("##value", buffer, sizeof(buffer), - ImVec2(0, 0), + ImVec2(900, -FLT_MIN), ImGuiInputTextFlags_AllowTabInput); if (ImGui::IsItemDeactivatedAfterEdit()) { @@ -75,6 +85,18 @@ struct LuaScriptPropertyEditor : DPropertyEditor { StaticGeometryModule::setItemProperties(entity, j.dump()); } + ImGui::EndChild(); + ImGui::PopItemWidth(); + if (ImGui::SmallButton("Update script...")) { + j[ptr] = buffer; + StaticGeometryModule::setItemProperties(entity, + j.dump()); + } + if (ImGui::SmallButton("Run Lua script...")) { + j[ptr] = buffer; + nlohmann::json &lot = j[ptr.parent_pointer()]; + Items::runSingleLotScript(entity, lot); + } } LuaScriptPropertyEditor() : DPropertyEditor(EditLuaScript, "Lua Script Editor") @@ -89,7 +111,7 @@ struct MultilineStringPropertyEditor : DPropertyEditor { const nlohmann::json::json_pointer &ptr, const nlohmann::json &j) override { - return j[ptr].is_string() && + return itemName != "cellScript" && j[ptr].is_string() && (j[ptr].get().find("\n") != std::string::npos || j[ptr].get().length() >= 100); @@ -111,6 +133,13 @@ struct MultilineStringPropertyEditor : DPropertyEditor { j[ptr] = buffer; StaticGeometryModule::setItemProperties(entity, j.dump()); + StaticGeometryModule::updateItemGeometry(entity); + } + if (ImGui::SmallButton("Update value")) { + j[ptr] = buffer; + StaticGeometryModule::setItemProperties(entity, + j.dump()); + StaticGeometryModule::updateItemGeometry(entity); } } MultilineStringPropertyEditor() @@ -216,6 +245,8 @@ static registerPropertyEditor boolPropertyEditor(propertyEditors); static registerPropertyEditor colorRectPropertyEditor(propertyEditors); +static registerPropertyEditor + propertyEditorNPC(propertyEditors); // ViewJson editor (fallback) struct FallbackPropertyEditor : DPropertyEditor { bool _matches(const std::string &itemName, @@ -311,7 +342,7 @@ struct ItemEditor { itemName == "roofs" || itemName == "pierPath") { state.edited_type = ViewJson; } else if (itemName == "cellScript") { - state.edited_type = EditMultilineString; + state.edited_type = EditLuaScript; } else if (!ptr.empty() && !ptr.parent_pointer().empty()) { std::string parent = ptr.parent_pointer().back(); if (parent == "colorRects") { @@ -346,6 +377,46 @@ struct ItemEditor { state.edited_type = ViewJson; } }; + void _setCameraSelectedPos(flecs::entity e) + { + Ogre::Vector3 cursorPos; + Ogre::Quaternion cursorOrientation; + // setCursorSelectedPos(e, cursorPos, cursorOrientation); + StaticGeometryModule::getItemPositionAndRotation( + e, cursorPos, cursorOrientation); + ECS::get().sceneNode->_setDerivedPosition( + cursorPos); + ECS::get().sceneNode->_setDerivedOrientation( + cursorOrientation); + Ogre::Vector3 cameraPos = + ECS::get().mCameraPivot->_getDerivedPosition(); + Ogre::Vector3 cameraOffset = + cursorOrientation * Ogre::Vector3::UNIT_Z * 30.0f; + cameraPos.x = cursorPos.x; + cameraPos.z = cursorPos.z; + cameraPos += cameraOffset; + cameraPos.y = + TerrainModule::get_height( + ECS::get().mTerrainGroup, cameraPos) + + 10.0f; + Ogre::TerrainGroup *tg = ECS::get().mTerrainGroup; + long x, y; + tg->convertWorldPositionToTerrainSlot(cameraPos, &x, &y); + if (tg->getTerrain(x, y) && tg->getTerrain(x, y)->isLoaded()) { + float height = tg->getHeightAtWorldPosition(cameraPos); + cameraPos.y = height + 10.0f; + } + ECS::get().mCameraPivot->_setDerivedPosition(cameraPos); + ECS::get().mCameraPivot->_setDerivedOrientation( + cursorOrientation); + cameraPos = + ECS::get().mCameraGoal->_getDerivedPosition(); + ECS::get().mCameraNode->_setDerivedPosition(cameraPos); + ECS::get().mCameraNode->_setDerivedOrientation( + ECS::get() + .mCameraGoal->_getDerivedOrientation()); + // updateHeightmap(); + } void renderHierarchy(const Ogre::String &label, flecs::entity item, ImGuiTreeNodeFlags flags, const nlohmann::json::json_pointer &ptr, @@ -378,6 +449,32 @@ struct ItemEditor { std::string itemName = ptr.empty() ? "" : ptr.back(); set_edit_type(itemName, ptr, j); std::cout << ptr << std::endl; + { + Ogre::String _jsonStr = + StaticGeometryModule::getItemProperties( + state.edited); + nlohmann::json _j = + nlohmann::json::parse(_jsonStr); + std::cout << _j[ptr].dump(4) << std::endl; + if (_j[ptr].find("type") != _j[ptr].end()) { + _setCameraSelectedPos(state.edited); + /* + Ogre::Vector3 position; + Ogre::Quaternion orientation; + StaticGeometryModule:: + getItemPositionAndRotation( + state.edited, position, + orientation); + ECS::get() + .mCameraGoal + ->_setDerivedPosition(position); + ECS::get() + .mCameraGoal + ->_setDerivedOrientation( + orientation); + */ + } + } } // Render children @@ -475,7 +572,7 @@ struct ItemEditor { } void drawPropertyEditor() { - ImGui::BeginChild("PropertiesRegion", ImVec2(0, 400), true); + ImGui::BeginChild("PropertiesRegion", ImVec2(0, 0), true); ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(10.0f, 4.0f)); if (ImGui::BeginTable("PropTable", 2, @@ -507,6 +604,15 @@ struct ItemEditor { } ImGui::EndTable(); } + if (ImGui::SmallButton("Run all town scripts")) { + runAllScriptsForTown(state.edited); + StaticGeometryModule::saveItems(); + } + if (ImGui::SmallButton("Update world")) + StaticGeometryModule::updateItemGeometry(state.edited); + ImGui::SameLine(); + if (ImGui::SmallButton("Save items...")) + StaticGeometryModule::saveItems(); ImGui::PopStyleVar(); // DrawPropertyInspector(); // Uses the Table logic from before ImGui::EndChild(); diff --git a/src/gamedata/items/property_editor.h b/src/gamedata/items/property_editor.h index 1e6ed74..ee04221 100644 --- a/src/gamedata/items/property_editor.h +++ b/src/gamedata/items/property_editor.h @@ -15,6 +15,7 @@ enum EditType { EditString, EditMultilineString, EditColorRect, + EditNPC, EditFloat, EditBool, EditInt, diff --git a/src/gamedata/items/property_editor_npc.cpp b/src/gamedata/items/property_editor_npc.cpp new file mode 100644 index 0000000..36b7812 --- /dev/null +++ b/src/gamedata/items/property_editor_npc.cpp @@ -0,0 +1,35 @@ +#include "property_editor_npc.h" + +namespace ECS +{ +namespace Items +{ + +bool PropertyEditorNPC::_matches(const std::string &itemName, + const nlohmann::json::json_pointer &ptr, + const nlohmann::json &j) +{ + if (ptr.empty()) + return false; + if (!ptr.parent_pointer().empty() && + ptr.parent_pointer().back() == "npcs") { + return true; + } + return false; +} + +void PropertyEditorNPC::_render(flecs::entity entity, + const nlohmann::json::json_pointer &ptr, + nlohmann::json &j) +{ + ImGui::TableSetColumnIndex(1); + ImGui::TextWrapped("%s", j[ptr].dump(4).c_str()); +} + +PropertyEditorNPC::PropertyEditorNPC() + : DPropertyEditor(EditNPC, "NPC Editor") +{ +} + +} // namespace Items +} // namespace ECS diff --git a/src/gamedata/items/property_editor_npc.h b/src/gamedata/items/property_editor_npc.h new file mode 100644 index 0000000..826c041 --- /dev/null +++ b/src/gamedata/items/property_editor_npc.h @@ -0,0 +1,22 @@ +#ifndef ECS_ITEMS_PROPERTYEDITORNPC_H +#define ECS_ITEMS_PROPERTYEDITORNPC_H +#include "property_editor.h" + +namespace ECS { +namespace Items { + +struct PropertyEditorNPC : DPropertyEditor +{ + bool _matches(const std::string &itemName, + const nlohmann::json::json_pointer &ptr, + const nlohmann::json &j) override; + void _render(flecs::entity entity, + const nlohmann::json::json_pointer &ptr, + nlohmann::json &j) override; + PropertyEditorNPC(); +}; + +} // namespace Items +} // namespace ECS + +#endif // ECS_ITEMS_PROPERTYEDITORNPC_H diff --git a/src/gamedata/items/town.cpp b/src/gamedata/items/town.cpp index 88e8bf4..d7df460 100644 --- a/src/gamedata/items/town.cpp +++ b/src/gamedata/items/town.cpp @@ -2143,6 +2143,13 @@ void runAllScriptsForTown(flecs::entity e) j["districts"] = districts; StaticGeometryModule::setItemProperties(e, j.dump()); } +void runSingleLotScript(flecs::entity e, nlohmann::json &lot) +{ + if (lot.find("cellScript") == lot.end()) + return; + CellsScript script(lot["cellScript"].get(), lot); + script.run(); +} struct Selector { int selection; Ogre::String result; diff --git a/src/gamedata/items/town.h b/src/gamedata/items/town.h index 1f29757..b52cc59 100644 --- a/src/gamedata/items/town.h +++ b/src/gamedata/items/town.h @@ -2,6 +2,7 @@ #define __TOWN_H__ #include #include +#include namespace Procedural { class TriangleBuffer; @@ -14,6 +15,7 @@ void createTownItem(); void createTownMenu(); void createTownPopup(const std::pair item); void runAllScriptsForTown(flecs::entity e); +void runSingleLotScript(flecs::entity e, nlohmann::json &lot); } namespace Geometry {