Maintain item list
This commit is contained in:
@@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user