Updated editor

This commit is contained in:
2026-03-22 18:43:39 +03:00
parent 02ec62a00d
commit 0bd98ea3e2
8 changed files with 178 additions and 6 deletions

View File

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

View File

@@ -17,7 +17,6 @@
#include "harbour.h"
#include "temple.h"
#include "town.h"
#include "property_editor.h"
#include "items.h"
#include <tracy/Tracy.hpp>
namespace ECS

View File

@@ -1,6 +1,13 @@
#include <iostream>
#include <OgreTerrainGroup.h>
#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<std::string>().find("\n") !=
std::string::npos ||
j[ptr].get<std::string>().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>
boolPropertyEditor(propertyEditors);
static registerPropertyEditor<ColorRectPropertyEditor>
colorRectPropertyEditor(propertyEditors);
static registerPropertyEditor<PropertyEditorNPC>
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<EditorGizmo>().sceneNode->_setDerivedPosition(
cursorPos);
ECS::get<EditorGizmo>().sceneNode->_setDerivedOrientation(
cursorOrientation);
Ogre::Vector3 cameraPos =
ECS::get<Camera>().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<Terrain>().mTerrainGroup, cameraPos) +
10.0f;
Ogre::TerrainGroup *tg = ECS::get<Terrain>().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<Camera>().mCameraPivot->_setDerivedPosition(cameraPos);
ECS::get<Camera>().mCameraPivot->_setDerivedOrientation(
cursorOrientation);
cameraPos =
ECS::get<Camera>().mCameraGoal->_getDerivedPosition();
ECS::get<Camera>().mCameraNode->_setDerivedPosition(cameraPos);
ECS::get<Camera>().mCameraNode->_setDerivedOrientation(
ECS::get<Camera>()
.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<Camera>()
.mCameraGoal
->_setDerivedPosition(position);
ECS::get<Camera>()
.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();

View File

@@ -15,6 +15,7 @@ enum EditType {
EditString,
EditMultilineString,
EditColorRect,
EditNPC,
EditFloat,
EditBool,
EditInt,

View File

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

View File

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

View File

@@ -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<Ogre::String>(), lot);
script.run();
}
struct Selector {
int selection;
Ogre::String result;

View File

@@ -2,6 +2,7 @@
#define __TOWN_H__
#include <OgreMeshLodGenerator.h>
#include <flecs.h>
#include <nlohmann/json.hpp>
namespace Procedural
{
class TriangleBuffer;
@@ -14,6 +15,7 @@ void createTownItem();
void createTownMenu();
void createTownPopup(const std::pair<flecs::entity, Ogre::String> item);
void runAllScriptsForTown(flecs::entity e);
void runSingleLotScript(flecs::entity e, nlohmann::json &lot);
}
namespace Geometry
{