Better narration processing
This commit is contained in:
@@ -1,8 +1,16 @@
|
||||
#include <nanoflann.hpp>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <flecs.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include "Components.h"
|
||||
#include "GameData.h"
|
||||
#include "CharacterManagerModule.h"
|
||||
#include "CharacterModule.h"
|
||||
#include "items.h"
|
||||
#include "GUIModule.h"
|
||||
#include "GUIModuleCommon.h"
|
||||
#include "LuaData.h"
|
||||
#include "PlayerActionModule.h"
|
||||
|
||||
namespace ECS
|
||||
@@ -51,13 +59,69 @@ struct ActionNodeList::indexObject {
|
||||
}
|
||||
};
|
||||
|
||||
struct TestNarrativeHandler : GUI::NarrationHandler {
|
||||
int count;
|
||||
TestNarrativeHandler()
|
||||
: GUI::NarrationHandler()
|
||||
, count(0)
|
||||
{
|
||||
}
|
||||
void finish() override
|
||||
{
|
||||
_clear_narration();
|
||||
}
|
||||
void activate() override
|
||||
{
|
||||
_narration("Dialogue...", {});
|
||||
count = 0;
|
||||
}
|
||||
void event(const Ogre::String &evt) override
|
||||
{
|
||||
if (evt == "narration_progress" ||
|
||||
evt == "narration_answered") {
|
||||
count++;
|
||||
if (count == 1) {
|
||||
_narration(
|
||||
"Question..." +
|
||||
Ogre::StringConverter::toString(
|
||||
count),
|
||||
{ "Answer1", "Answer2" });
|
||||
} else {
|
||||
_narration(
|
||||
"Whatever..." +
|
||||
Ogre::StringConverter::toString(
|
||||
count),
|
||||
{});
|
||||
}
|
||||
if (count > 5)
|
||||
_finish();
|
||||
}
|
||||
if (evt == "narration_answered")
|
||||
std::cout << "answer: " << getNarrationAnswer()
|
||||
<< std::endl;
|
||||
}
|
||||
};
|
||||
struct SimpleWordHandler : PlayerActionModule::ActionWordHandler {
|
||||
void operator()(flecs::entity town, int index,
|
||||
const Ogre::String &word) override
|
||||
{
|
||||
TestNarrativeHandler *handle = OGRE_NEW TestNarrativeHandler();
|
||||
ECS::get_mut<GUI>().addNarrationHandler(handle);
|
||||
ECS::modified<GUI>();
|
||||
}
|
||||
};
|
||||
|
||||
PlayerActionModule::PlayerActionModule(flecs::world &ecs)
|
||||
{
|
||||
ecs.module<PlayerActionModule>();
|
||||
ecs.import <CharacterManagerModule>();
|
||||
ecs.component<ActionNodeList>()
|
||||
.on_add([](flecs::entity e, ActionNodeList &alist) {
|
||||
alist.dirty = true;
|
||||
alist.nodes.reserve(1000);
|
||||
alist.dynamicNodes.reserve(1000);
|
||||
alist.selected = -1;
|
||||
alist.busy = false;
|
||||
})
|
||||
.add(flecs::Singleton);
|
||||
#if 0
|
||||
@@ -79,25 +143,166 @@ PlayerActionModule::PlayerActionModule(flecs::world &ecs)
|
||||
}
|
||||
});
|
||||
#endif
|
||||
ecs.system<ActionNodeList>("updateNodeList")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([](ActionNodeList &list) {
|
||||
if (list.busy)
|
||||
return;
|
||||
if (list.nodes.size() > 0) {
|
||||
Ogre::SceneNode *cameraNode =
|
||||
ECS::get<Camera>().mCameraNode;
|
||||
Ogre::Vector3 cameraPos =
|
||||
cameraNode->_getDerivedPosition();
|
||||
flecs::entity player =
|
||||
ECS::get<CharacterManagerModule>()
|
||||
.getPlayer();
|
||||
if (player.is_valid()) {
|
||||
Ogre::Vector3 playerPos =
|
||||
player.get<CharacterBase>()
|
||||
.mBodyNode
|
||||
->_getDerivedPosition();
|
||||
list.query(playerPos, list.points,
|
||||
list.distances);
|
||||
} else {
|
||||
list.query(cameraPos, list.points,
|
||||
list.distances);
|
||||
}
|
||||
}
|
||||
});
|
||||
ecs.system<ActionNodeList, const Input>("ActivateActionNode")
|
||||
.kind(flecs::OnUpdate)
|
||||
.each([this](ActionNodeList &list, const Input &input) {
|
||||
if (input.control & 32)
|
||||
std::cout << "act pressed" << std::endl;
|
||||
if (list.busy)
|
||||
return;
|
||||
if (input.act_pressed && list.selected >= 0) {
|
||||
std::cout << list.dynamicNodes[list.selected]
|
||||
.props.dump(4)
|
||||
<< std::endl;
|
||||
flecs::entity_t townid =
|
||||
list.dynamicNodes[list.selected]
|
||||
.props["town"]
|
||||
.get<flecs::entity_t>();
|
||||
flecs::entity town = ECS::get().entity(townid);
|
||||
int index = list.dynamicNodes[list.selected]
|
||||
.props["index"]
|
||||
.get<int>();
|
||||
for (auto it = actionWords.begin();
|
||||
it != actionWords.end(); it++) {
|
||||
if (it->first ==
|
||||
list.dynamicNodes[list.selected]
|
||||
.action) {
|
||||
(*it->second)(
|
||||
town, index,
|
||||
list.dynamicNodes
|
||||
[list.selected]
|
||||
.action);
|
||||
list.busy = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!ECS::get<GUI>().enabled)
|
||||
list.busy = false;
|
||||
});
|
||||
SimpleWordHandler *handler = OGRE_NEW SimpleWordHandler;
|
||||
addWordHandler("talk", handler);
|
||||
}
|
||||
|
||||
void PlayerActionModule::addWordHandler(const Ogre::String &word,
|
||||
ActionWordHandler *handler)
|
||||
{
|
||||
actionWords.insert({ word, handler });
|
||||
}
|
||||
|
||||
void PlayerActionModule::removeWordHandler(const Ogre::String &word,
|
||||
ActionWordHandler *handler)
|
||||
{
|
||||
for (auto it = actionWords.begin(); it != actionWords.end();) {
|
||||
if (it->first == word && it->second == handler)
|
||||
it = actionWords.erase(it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
struct LuaWordHandler : PlayerActionModule::ActionWordHandler {
|
||||
lua_State *L;
|
||||
int ref;
|
||||
void operator()(flecs::entity town, int index,
|
||||
const Ogre::String &word) override
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
lua_pushinteger(L, town.id());
|
||||
lua_pushinteger(L, index);
|
||||
lua_pushstring(L, word.c_str());
|
||||
if (lua_pcall(L, 3, 0, 0)) {
|
||||
Ogre::LogManager::getSingleton().stream()
|
||||
<< lua_tostring(L, -1);
|
||||
OgreAssert(false, "Lua error");
|
||||
}
|
||||
}
|
||||
};
|
||||
void PlayerActionModule::addLuaWordHandler(const Ogre::String &word,
|
||||
lua_State *L, int ref)
|
||||
{
|
||||
struct LuaWordHandler *handler = OGRE_NEW LuaWordHandler;
|
||||
handler->L = L;
|
||||
handler->ref = ref;
|
||||
addWordHandler(word, handler);
|
||||
}
|
||||
|
||||
void PlayerActionModule::removeLuaWordHandler(const Ogre::String &word,
|
||||
lua_State *L, int ref)
|
||||
{
|
||||
for (auto it = actionWords.begin(); it != actionWords.end();) {
|
||||
LuaWordHandler *handler =
|
||||
static_cast<LuaWordHandler *>(it->second);
|
||||
if (it->first == word && handler->L == L && handler->ref == ref)
|
||||
it = actionWords.erase(it);
|
||||
else
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
int PlayerActionModule::setupLuaActionHandler(lua_State *L)
|
||||
{
|
||||
luaL_checktype(L, 1, LUA_TSTRING);
|
||||
luaL_checktype(L, 2, LUA_TFUNCTION);
|
||||
Ogre::String word = lua_tostring(L, 1);
|
||||
lua_pushvalue(L, 2);
|
||||
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
addLuaWordHandler(word, L, ref);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ActionNodeList::build()
|
||||
{
|
||||
indexObj = std::make_shared<ActionNodeList::indexObject>(nodes);
|
||||
dynamicNodes.clear();
|
||||
dynamicNodes.insert(dynamicNodes.end(), nodes.begin(), nodes.end());
|
||||
ECS::get().query_builder<const NPCActionNodes>().each(
|
||||
[&](flecs::entity e, const NPCActionNodes &anodes) {
|
||||
dynamicNodes.insert(dynamicNodes.end(),
|
||||
anodes.anodes.begin(),
|
||||
anodes.anodes.end());
|
||||
});
|
||||
|
||||
indexObj = std::make_shared<ActionNodeList::indexObject>(dynamicNodes);
|
||||
indexObj->index.buildIndex();
|
||||
dirty = false;
|
||||
std::cout << "index built" << std::endl;
|
||||
}
|
||||
|
||||
bool ActionNodeList::query(const Ogre::Vector3 &position,
|
||||
std::vector<size_t> &points)
|
||||
std::vector<size_t> &points,
|
||||
std::vector<float> &distances)
|
||||
{
|
||||
if (dirty)
|
||||
build();
|
||||
build();
|
||||
std::vector<size_t> tmppoints;
|
||||
std::vector<float> tmpdistances;
|
||||
points.clear();
|
||||
points.reserve(4);
|
||||
distances.clear();
|
||||
distances.reserve(4);
|
||||
tmppoints.resize(4);
|
||||
tmpdistances.resize(4);
|
||||
nanoflann::KNNResultSet<float> resultSet(4);
|
||||
@@ -106,9 +311,10 @@ bool ActionNodeList::query(const Ogre::Vector3 &position,
|
||||
nanoflann::SearchParameters());
|
||||
int i;
|
||||
for (i = 0; i < resultSet.size(); i++)
|
||||
if (tmpdistances[i] < 25.0f)
|
||||
if (tmpdistances[i] < 25.0f) {
|
||||
points.push_back(tmppoints[i]);
|
||||
distances.push_back(tmpdistances[i]);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user