Maintain item list
This commit is contained in:
@@ -2,11 +2,17 @@ project(gamedata)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
find_package(OGRE REQUIRED COMPONENTS Bites Bullet Paging Terrain Overlay CONFIG)
|
||||
find_package(Bullet REQUIRED)
|
||||
find_package(nlohmann_json REQUIRED)
|
||||
add_library(GameData STATIC GameData.cpp CharacterModule.cpp WaterModule.cpp SunModule.cpp TerrainModule.cpp
|
||||
GUIModule.cpp LuaData.cpp WorldMapModule.cpp BoatModule.cpp EventTriggerModule.cpp
|
||||
CharacterAnimationModule.cpp PhysicsModule.cpp EventModule.cpp CharacterManagerModule.cpp
|
||||
VehicleManagerModule.cpp AppModule.cpp SmartObject.cpp SlotsModule.cpp goap.cpp)
|
||||
target_link_libraries(GameData PUBLIC lua flecs::flecs_static OgreMain OgreBites
|
||||
target_link_libraries(GameData PUBLIC
|
||||
lua
|
||||
flecs::flecs_static
|
||||
nlohmann_json::nlohmann_json
|
||||
OgreMain
|
||||
OgreBites
|
||||
OgrePaging OgreTerrain OgreOverlay
|
||||
PRIVATE sceneloader world-build physics editor)
|
||||
target_include_directories(GameData PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${BULLET_INCLUDE_DIR} ../luaaa)
|
||||
|
||||
@@ -700,6 +700,7 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
bool locationSelected = false;
|
||||
float strength = 0.0f;
|
||||
int size = 0;
|
||||
long slot_x, slot_y;
|
||||
void updateWorldTexture()
|
||||
{
|
||||
// Get the hardware pixel buffer
|
||||
@@ -748,16 +749,33 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
|
||||
ECS::get<Terrain>().mTerrainGroup->update(true);
|
||||
}
|
||||
void setCameraPos()
|
||||
void setCursorPos(Ogre::Vector3 &cursorPosition,
|
||||
Ogre::Quaternion &orientation)
|
||||
{
|
||||
Ogre::Vector3 worldPos =
|
||||
ECS::get<Camera>().mCameraPivot->_getDerivedPosition();
|
||||
ECS::get<EditorGizmo>().sceneNode->_getDerivedPosition();
|
||||
worldPos.x = TerrainModule::get_world_x(selected_x);
|
||||
worldPos.z = TerrainModule::get_world_y(selected_y);
|
||||
worldPos.y = TerrainModule::get_height(
|
||||
ECS::get<Terrain>().mTerrainGroup, worldPos);
|
||||
ECS::get<EditorGizmo>().sceneNode->_setDerivedPosition(
|
||||
worldPos);
|
||||
cursorPosition = worldPos;
|
||||
orientation = ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedOrientation();
|
||||
}
|
||||
void setCameraPos()
|
||||
{
|
||||
Ogre::Vector3 cursorPos;
|
||||
Ogre::Quaternion cursorOrientation;
|
||||
setCursorPos(cursorPos, cursorOrientation);
|
||||
Ogre::Vector3 cameraPos =
|
||||
ECS::get<Camera>().mCameraPivot->_getDerivedPosition();
|
||||
cameraPos.x = worldPos.x;
|
||||
cameraPos.z = worldPos.z;
|
||||
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) +
|
||||
@@ -765,9 +783,14 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
if (cameraPos.y < 0.0f)
|
||||
cameraPos.y = 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 worldMapView()
|
||||
@@ -784,10 +807,10 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
OgreAssert(TerrainModule::get_world_y(worldMap->getHeight() /
|
||||
2) == 0.0f,
|
||||
"get_world_y");
|
||||
if (ECS::get<Camera>().mCameraPivot) {
|
||||
if (ECS::get<EditorGizmo>().sceneNode) {
|
||||
Ogre::Vector3 worldPos =
|
||||
ECS::get<Camera>()
|
||||
.mCameraPivot->_getDerivedPosition();
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedPosition();
|
||||
selected_x = TerrainModule::get_img_x(worldPos.x);
|
||||
selected_y = TerrainModule::get_img_y(worldPos.z);
|
||||
locationSelected = true;
|
||||
@@ -797,6 +820,10 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
OgreAssert(selected_y >= 0 &&
|
||||
selected_y < worldMap->getHeight(),
|
||||
"mix height");
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup
|
||||
->convertWorldPositionToTerrainSlot(
|
||||
worldPos, &slot_x, &slot_y);
|
||||
}
|
||||
ImGui::SetNextWindowSizeConstraints(ImVec2(512 + 20, 512 + 20),
|
||||
ImVec2(768, 768));
|
||||
@@ -856,6 +883,18 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
ImDrawList *draw_list = ImGui::GetWindowDrawList();
|
||||
draw_list->AddCircleFilled(ImVec2(top_x + pos_x, top_y + pos_y),
|
||||
1.0f, IM_COL32(0, 255, 0, 255));
|
||||
{
|
||||
std::list<Ogre::Vector3> positions;
|
||||
TerrainModule::getItemPositions(&positions);
|
||||
for (auto pos : positions) {
|
||||
int item_x = TerrainModule::get_img_x(pos.x);
|
||||
int item_y = TerrainModule::get_img_y(pos.z);
|
||||
draw_list->AddCircleFilled(
|
||||
ImVec2(top_x + item_x, top_y + item_y),
|
||||
3.0f, IM_COL32(255, 255, 0, 255));
|
||||
std::cout << pos << std::endl;
|
||||
}
|
||||
}
|
||||
if (locationSelected)
|
||||
draw_list->AddCircleFilled(
|
||||
ImVec2(top_x + selected_x, top_y + selected_y),
|
||||
@@ -877,6 +916,13 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
ImGui::Text(
|
||||
"Selected height: %f",
|
||||
worldMapImage.getColourAt(selected_x, selected_y, 0).r);
|
||||
{
|
||||
Ogre::Vector3 position =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedPosition();
|
||||
ImGui::Text("Cursor position %f %f %f", position.x,
|
||||
position.y, position.z);
|
||||
}
|
||||
if (ImGui::Button("Update terrain")) {
|
||||
ECS::get<Terrain>().mTerrainGroup->update(true);
|
||||
}
|
||||
@@ -948,6 +994,17 @@ struct EditorGUIListener : public Ogre::RenderTargetListener {
|
||||
setLevel = true;
|
||||
setLevelValue = 0.646f;
|
||||
}
|
||||
if (ImGui::Button("Harbour")) {
|
||||
Ogre::Vector3 itemPosition =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedPosition();
|
||||
Ogre::Quaternion itemOrientation =
|
||||
ECS::get<EditorGizmo>()
|
||||
.sceneNode->_getDerivedOrientation();
|
||||
TerrainModule::createItem(itemPosition, itemOrientation,
|
||||
"harbour");
|
||||
TerrainModule::saveItems();
|
||||
}
|
||||
if (riseLower) {
|
||||
int actualSize = 1 + size * 2;
|
||||
int i, j;
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include <OgrePage.h>
|
||||
#include <OgreTerrainPaging.h>
|
||||
#include <OgreFileSystemLayer.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#include "GameData.h"
|
||||
#include "Components.h"
|
||||
@@ -465,6 +466,15 @@ struct TerrainPrivate {
|
||||
Ogre::Timer mSunUpdate;
|
||||
};
|
||||
|
||||
struct TerrainSlotParent {
|
||||
std::pair<long, long> slot;
|
||||
};
|
||||
struct TerrainItem {
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion orientation;
|
||||
Ogre::String properties;
|
||||
};
|
||||
|
||||
TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
{
|
||||
struct CanSetPlayerPosition {};
|
||||
@@ -472,6 +482,8 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
ecs.component<CanSetPlayerPosition>().add(flecs::Singleton);
|
||||
ecs.component<Terrain>().add(flecs::Singleton);
|
||||
ecs.component<TerrainPrivate>().add(flecs::Singleton);
|
||||
ecs.component<TerrainSlotParent>();
|
||||
ecs.component<TerrainItem>();
|
||||
ecs.component<PlacementObjects>();
|
||||
ecs.component<TerrainReady>().add(flecs::Singleton);
|
||||
ecs.import <CharacterModule>();
|
||||
@@ -726,6 +738,12 @@ TerrainModule::TerrainModule(flecs::world &ecs)
|
||||
player.modified<CharacterLocation>();
|
||||
ECS::get().remove<CanSetPlayerPosition>();
|
||||
});
|
||||
ecs.observer<const Terrain>("LoadTerrainItems")
|
||||
.event(flecs::OnSet)
|
||||
.each([](const Terrain &terrain) {
|
||||
if (terrain.mTerrainGroup)
|
||||
loadItems();
|
||||
});
|
||||
}
|
||||
float TerrainModule::get_height(Ogre::TerrainGroup *group,
|
||||
const Ogre::Vector3 &position)
|
||||
@@ -765,4 +783,167 @@ void TerrainModule::save_heightmap()
|
||||
{
|
||||
HeightData::get_singleton()->save_heightmap();
|
||||
}
|
||||
flecs::entity TerrainModule::createItem(const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &type)
|
||||
{
|
||||
long x, y;
|
||||
ECS::get<Terrain>().mTerrainGroup->convertWorldPositionToTerrainSlot(
|
||||
position, &x, &y);
|
||||
std::pair<long, long> pos{ x, y };
|
||||
flecs::entity slot =
|
||||
ECS::get().query_builder<const TerrainSlotParent>().build().find(
|
||||
[&](const TerrainSlotParent &slot) -> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
slot = ECS::get().entity().add<TerrainSlotParent>();
|
||||
flecs::entity item = ECS::get().entity().child_of(slot);
|
||||
nlohmann::json jproperties;
|
||||
jproperties["type"] = type;
|
||||
item.set<TerrainItem>({ position, orientation, jproperties.dump() });
|
||||
return item;
|
||||
}
|
||||
void TerrainModule::setItemProperties(flecs::entity id, Ogre::String properties)
|
||||
{
|
||||
OgreAssert(id.is_valid(), "bad id");
|
||||
id.get_mut<TerrainItem>().properties = properties;
|
||||
id.modified<TerrainItem>();
|
||||
}
|
||||
const Ogre::String &TerrainModule::getItemProperties(flecs::entity id)
|
||||
{
|
||||
OgreAssert(id.is_valid(), "bad id");
|
||||
return id.get<TerrainItem>().properties;
|
||||
}
|
||||
static void to_json(nlohmann::json &j, const Ogre::Vector3 &position)
|
||||
{
|
||||
j["x"] = position.x;
|
||||
j["y"] = position.y;
|
||||
j["z"] = position.z;
|
||||
}
|
||||
static void to_json(nlohmann::json &j, const Ogre::Quaternion &orientation)
|
||||
{
|
||||
j["w"] = orientation.w;
|
||||
j["x"] = orientation.x;
|
||||
j["y"] = orientation.y;
|
||||
j["z"] = orientation.z;
|
||||
}
|
||||
static void from_json(const nlohmann::json &j, Ogre::Vector3 &position)
|
||||
{
|
||||
position.x = j["x"].get<float>();
|
||||
position.y = j["y"].get<float>();
|
||||
position.z = j["z"].get<float>();
|
||||
}
|
||||
static void from_json(const nlohmann::json &j, Ogre::Quaternion &orientation)
|
||||
{
|
||||
orientation.w = j["w"].get<float>();
|
||||
orientation.x = j["x"].get<float>();
|
||||
orientation.y = j["y"].get<float>();
|
||||
orientation.z = j["z"].get<float>();
|
||||
}
|
||||
void TerrainModule::saveItems()
|
||||
{
|
||||
Ogre::String path = "resources/buildings/items.list";
|
||||
if (Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(
|
||||
"items.list")) {
|
||||
Ogre::String group =
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("items.list");
|
||||
Ogre::FileInfoListPtr fileInfoList(
|
||||
Ogre::ResourceGroupManager::getSingleton()
|
||||
.findResourceFileInfo(group, "items.list"));
|
||||
OgreAssert(fileInfoList->size() == 1,
|
||||
"worpd_map.png should be there and only once");
|
||||
path = fileInfoList->at(0).archive->getName() + "/" +
|
||||
"items.list";
|
||||
Ogre::FileSystemLayer::removeFile(path);
|
||||
}
|
||||
std::fstream fout(path.c_str(), std::ios::out);
|
||||
nlohmann::json jitemlist;
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
nlohmann::json jitem;
|
||||
to_json(jitem["position"], item.position);
|
||||
to_json(jitem["orientation"], item.orientation);
|
||||
to_json(jitem["properties"], item.properties);
|
||||
jitemlist.push_back(jitem);
|
||||
});
|
||||
fout << jitemlist.dump();
|
||||
fout.close();
|
||||
}
|
||||
void TerrainModule::loadItems()
|
||||
{
|
||||
if (!Ogre::ResourceGroupManager::getSingleton().resourceExistsInAnyGroup(
|
||||
"items.list"))
|
||||
return;
|
||||
Ogre::String group = Ogre::ResourceGroupManager::getSingleton()
|
||||
.findGroupContainingResource("items.list");
|
||||
Ogre::DataStreamPtr stream =
|
||||
Ogre::ResourceGroupManager::getSingleton().openResource(
|
||||
"items.list", group);
|
||||
Ogre::String json = stream->getAsString();
|
||||
nlohmann::json jlist = nlohmann::json::parse(json);
|
||||
ECS::get().delete_with<TerrainItem>();
|
||||
ECS::get().delete_with<TerrainSlotParent>();
|
||||
|
||||
for (const auto &v : jlist) {
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion orientation;
|
||||
Ogre::String properties;
|
||||
from_json(v["position"], position);
|
||||
from_json(v["orientation"], orientation);
|
||||
properties = v["properties"].get<Ogre::String>();
|
||||
long x, y;
|
||||
ECS::get<Terrain>()
|
||||
.mTerrainGroup->convertWorldPositionToTerrainSlot(
|
||||
position, &x, &y);
|
||||
std::pair<long, long> pos{ x, y };
|
||||
flecs::entity slot =
|
||||
ECS::get()
|
||||
.query_builder<const TerrainSlotParent>()
|
||||
.build()
|
||||
.find([&](const TerrainSlotParent &slot)
|
||||
-> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
slot = ECS::get().entity().add<TerrainSlotParent>();
|
||||
flecs::entity item = ECS::get().entity().child_of(slot);
|
||||
item.set<TerrainItem>({ position, orientation, properties });
|
||||
std::cout << "position: " << item.id() << " " << position
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
void TerrainModule::getItemPositionPerSlot(long x, long y,
|
||||
std::list<Ogre::Vector3> *positions)
|
||||
{
|
||||
std::pair<long, long> pos{ x, y };
|
||||
if (!positions)
|
||||
return;
|
||||
flecs::entity slot =
|
||||
ECS::get().query_builder<const TerrainSlotParent>().build().find(
|
||||
[&](const TerrainSlotParent &slot) -> bool {
|
||||
return slot.slot == pos;
|
||||
});
|
||||
if (!slot.is_valid())
|
||||
return;
|
||||
ECS::get()
|
||||
.query_builder<const TerrainItem>()
|
||||
.with(flecs::ChildOf, slot)
|
||||
.build()
|
||||
.each([&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
std::cout << e.id() << " " << item.position
|
||||
<< std::endl;
|
||||
});
|
||||
}
|
||||
void TerrainModule::getItemPositions(std::list<Ogre::Vector3> *positions)
|
||||
{
|
||||
ECS::get().query_builder<const TerrainItem>().build().each(
|
||||
[&](flecs::entity e, const TerrainItem &item) {
|
||||
positions->push_back(item.position);
|
||||
std::cout << e.id() << " " << item.position
|
||||
<< std::endl;
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,17 @@ struct TerrainModule {
|
||||
static int get_img_y(float world_z);
|
||||
static void update_heightmap(const Ogre::Image &heightmap);
|
||||
static void save_heightmap();
|
||||
static flecs::entity createItem(const Ogre::Vector3 &position,
|
||||
const Ogre::Quaternion &orientation,
|
||||
const Ogre::String &type);
|
||||
static void setItemProperties(flecs::entity id,
|
||||
Ogre::String properties);
|
||||
static const Ogre::String &getItemProperties(flecs::entity id);
|
||||
static void saveItems();
|
||||
static void loadItems();
|
||||
static void getItemPositionPerSlot(long x, long y,
|
||||
std::list<Ogre::Vector3> *positions);
|
||||
static void getItemPositions(std::list<Ogre::Vector3> *positions);
|
||||
};
|
||||
struct TerrainReady {};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user