Better narration processing
This commit is contained in:
@@ -4,15 +4,190 @@
|
||||
#include "Components.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "CharacterAnimationModule.h"
|
||||
#include "StaticGeometryModule.h"
|
||||
#include "PhysicsModule.h"
|
||||
#include "PlayerActionModule.h"
|
||||
#include "items.h"
|
||||
#include "CharacterManagerModule.h"
|
||||
|
||||
namespace ECS
|
||||
{
|
||||
struct TownNPCs {
|
||||
struct NPCData {
|
||||
flecs::entity e;
|
||||
nlohmann::json props;
|
||||
Ogre::Vector3 position;
|
||||
Ogre::Quaternion orientation;
|
||||
Ogre::String model;
|
||||
};
|
||||
|
||||
std::map<int, NPCData> npcs;
|
||||
};
|
||||
struct LivesIn {};
|
||||
void createNPCActionNodes(flecs::entity town, flecs::entity e, int index)
|
||||
{
|
||||
NPCActionNodes &anodes = e.get_mut<NPCActionNodes>();
|
||||
const CharacterBase &ch = e.get<CharacterBase>();
|
||||
Ogre::Vector3 characterPos = ch.mBodyNode->_getDerivedPosition();
|
||||
Ogre::Quaternion characterRot = ch.mBodyNode->_getDerivedOrientation();
|
||||
if (anodes.anodes.size() > 0) {
|
||||
int i;
|
||||
for (i = 0; i < anodes.anodes.size(); i++) {
|
||||
auto &anode = anodes.anodes[i];
|
||||
Ogre::Vector3 offset = Ogre::Vector3::UNIT_Z * 0.3f +
|
||||
Ogre::Vector3::UNIT_Y;
|
||||
if (i == 1)
|
||||
offset = Ogre::Vector3::NEGATIVE_UNIT_Z * 0.3f +
|
||||
Ogre::Vector3::UNIT_Y;
|
||||
anode.position = characterPos + characterRot * offset;
|
||||
anode.rotation = characterRot;
|
||||
to_json(anode.props["position"], anode.position);
|
||||
to_json(anode.props["rotation"], anode.rotation);
|
||||
}
|
||||
e.modified<NPCActionNodes>();
|
||||
return;
|
||||
}
|
||||
{
|
||||
ActionNodeList::ActionNode anode;
|
||||
anode.props["action"] = "talk";
|
||||
anode.props["action_text"] = "Talk";
|
||||
anode.action = "talk";
|
||||
anode.action_text = "Talk";
|
||||
Ogre::Vector3 offset = Ogre::Vector3::UNIT_Z * 0.25f +
|
||||
Ogre::Vector3::UNIT_Y * 1.5f;
|
||||
anode.position = characterPos + characterRot * offset;
|
||||
anode.rotation = characterRot;
|
||||
anode.radius = 0.6f;
|
||||
anode.height = 1.0f;
|
||||
to_json(anode.props["position"], anode.position);
|
||||
to_json(anode.props["rotation"], anode.rotation);
|
||||
|
||||
anode.props["radius"] = anode.radius;
|
||||
anode.props["height"] = anode.height;
|
||||
anode.props["town"] = town.id();
|
||||
anode.props["index"] = index;
|
||||
anodes.anodes.push_back(anode);
|
||||
}
|
||||
{
|
||||
ActionNodeList::ActionNode anode;
|
||||
anode.props["action"] = "action";
|
||||
anode.props["action_text"] = "Action";
|
||||
anode.action = "action";
|
||||
anode.action_text = "Action";
|
||||
Ogre::Vector3 offset = Ogre::Vector3::NEGATIVE_UNIT_Z * 0.2f +
|
||||
Ogre::Vector3::UNIT_Y;
|
||||
anode.position = characterPos + characterRot * offset;
|
||||
anode.rotation = characterRot;
|
||||
anode.radius = 0.3f;
|
||||
anode.height = 1.0f;
|
||||
to_json(anode.props["position"], anode.position);
|
||||
to_json(anode.props["rotation"], anode.rotation);
|
||||
anode.props["radius"] = anode.radius;
|
||||
anode.props["height"] = anode.height;
|
||||
anode.props["town"] = town.id();
|
||||
anode.props["index"] = index;
|
||||
anodes.anodes.push_back(anode);
|
||||
}
|
||||
e.modified<NPCActionNodes>();
|
||||
}
|
||||
CharacterManagerModule::CharacterManagerModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<CharacterManagerModule>();
|
||||
ecs.import <CharacterModule>();
|
||||
ecs.import <CharacterAnimationModule>();
|
||||
ecs.import <PhysicsModule>();
|
||||
ecs.import <PlayerActionModule>();
|
||||
ecs.component<TownCharacterHolder>();
|
||||
ecs.component<TownNPCs>();
|
||||
ecs.component<LivesIn>();
|
||||
ecs.component<NPCActionNodes>().on_add(
|
||||
[](flecs::entity e, NPCActionNodes &anodes) {
|
||||
anodes.anodes.clear();
|
||||
});
|
||||
ecs.system<TerrainItem, TownNPCs>("UpdateCharacters")
|
||||
.immediate()
|
||||
.kind(flecs::OnUpdate)
|
||||
.interval(1.0f)
|
||||
.write<CharacterBase>()
|
||||
.write<NPCActionNodes>()
|
||||
.write<CharacterLocation>()
|
||||
.write<CharacterConf>()
|
||||
.write<Character>()
|
||||
.write<LivesIn>()
|
||||
.each([this](flecs::entity town, TerrainItem &item,
|
||||
TownNPCs &npcs) {
|
||||
if (!player.is_valid())
|
||||
return;
|
||||
if (!player.has<CharacterBase>())
|
||||
return;
|
||||
ECS::get().defer_suspend();
|
||||
Ogre::Vector3 cameraPos =
|
||||
player.get<CharacterBase>()
|
||||
.mBodyNode->_getDerivedPosition();
|
||||
for (auto &npc : npcs.npcs) {
|
||||
int index = npc.first;
|
||||
TownNPCs::NPCData &data = npc.second;
|
||||
Ogre::Vector3 npcPosition = data.position;
|
||||
Ogre::Quaternion npcOrientation =
|
||||
data.orientation;
|
||||
if (cameraPos.squaredDistance(npcPosition) <
|
||||
10000.0f) {
|
||||
if (!data.e.is_valid()) {
|
||||
data.e = createCharacterData(
|
||||
data.model,
|
||||
data.position,
|
||||
data.orientation);
|
||||
data.e.add<LivesIn>(town);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cameraPos.squaredDistance(npcPosition) >
|
||||
22500.0f) {
|
||||
if (data.e.is_valid()) {
|
||||
data.e.destruct();
|
||||
data.e = flecs::entity();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ECS::get().defer_resume();
|
||||
});
|
||||
ecs.system<TerrainItem, TownNPCs>("UpdateCharacters2")
|
||||
.immediate()
|
||||
.kind(flecs::OnUpdate)
|
||||
.write<CharacterBase>()
|
||||
.write<NPCActionNodes>()
|
||||
.write<CharacterLocation>()
|
||||
.write<CharacterConf>()
|
||||
.write<Character>()
|
||||
.write<LivesIn>()
|
||||
.each([this](flecs::entity town, TerrainItem &item,
|
||||
TownNPCs &npcs) {
|
||||
if (!player.is_valid())
|
||||
return;
|
||||
if (!player.has<CharacterBase>())
|
||||
return;
|
||||
Ogre::Vector3 cameraPos =
|
||||
player.get<CharacterBase>()
|
||||
.mBodyNode->_getDerivedPosition();
|
||||
for (auto &npc : npcs.npcs) {
|
||||
int index = npc.first;
|
||||
TownNPCs::NPCData &data = npc.second;
|
||||
Ogre::Vector3 npcPosition = data.position;
|
||||
Ogre::Quaternion npcOrientation =
|
||||
data.orientation;
|
||||
if (cameraPos.squaredDistance(npcPosition) <
|
||||
10000.0f) {
|
||||
if (data.e.is_valid()) {
|
||||
if (data.e.has<CharacterBase>() &&
|
||||
data.e.has<LivesIn>(town))
|
||||
createNPCActionNodes(
|
||||
town, data.e,
|
||||
index);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
flecs::entity
|
||||
CharacterManagerModule::createPlayer(const Ogre::Vector3 &position,
|
||||
@@ -43,7 +218,44 @@ CharacterManagerModule::createCharacterData(const Ogre::String model,
|
||||
.entity()
|
||||
.set<CharacterLocation>({ rotation, position })
|
||||
.set<CharacterConf>({ model })
|
||||
.add<Character>();
|
||||
return e;
|
||||
.add<Character>()
|
||||
.add<NPCActionNodes>();
|
||||
return e;
|
||||
}
|
||||
|
||||
void CharacterManagerModule::registerTownCharacters(flecs::entity town)
|
||||
{
|
||||
Ogre::MeshManager::getSingleton().load("normal-male.glb", "General");
|
||||
Ogre::MeshManager::getSingleton().load("normal-female.glb", "General");
|
||||
Ogre::String props = StaticGeometryModule::getItemProperties(town);
|
||||
nlohmann::json j = nlohmann::json::parse(props);
|
||||
nlohmann::json npcs = nlohmann::json::array();
|
||||
if (town.has<TownNPCs>())
|
||||
return;
|
||||
if (j.find("npcs") != j.end())
|
||||
npcs = j["npcs"];
|
||||
std::cout << npcs.dump(4) << std::endl;
|
||||
int index = 0;
|
||||
std::map<int, TownNPCs::NPCData> npcMap;
|
||||
for (auto &npc : npcs) {
|
||||
const char *models[] = { "normal-male.glb",
|
||||
"normal-female.glb" };
|
||||
int sex = npc["sex"].get<int>();
|
||||
Ogre::Vector3 npcPosition;
|
||||
Ogre::Quaternion npcOrientation;
|
||||
from_json(npc["position"], npcPosition);
|
||||
from_json(npc["orientation"], npcOrientation);
|
||||
Ogre::String model = models[sex];
|
||||
TownNPCs::NPCData npcData;
|
||||
npcData.e = flecs::entity();
|
||||
npcData.model = model;
|
||||
npcData.orientation = npcOrientation;
|
||||
npcData.position = npcPosition;
|
||||
npcData.props = npc;
|
||||
npcMap[index] = npcData;
|
||||
index++;
|
||||
}
|
||||
town.set<TownNPCs>({ npcMap });
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user