Much better narration/dialogue/action handling (and for lua too)
This commit is contained in:
@@ -72,7 +72,8 @@ struct TestNarrativeHandler : GUI::NarrationHandler {
|
||||
}
|
||||
void activate() override
|
||||
{
|
||||
_narration("Dialogue...", {});
|
||||
_narration("Greetings...", {});
|
||||
std::cout << getPropsJSON().dump(4) << std::endl;
|
||||
count = 0;
|
||||
}
|
||||
void event(const Ogre::String &evt) override
|
||||
@@ -101,11 +102,119 @@ struct TestNarrativeHandler : GUI::NarrationHandler {
|
||||
<< std::endl;
|
||||
}
|
||||
};
|
||||
struct LuaNarrationHandler : GUI::NarrationHandler {
|
||||
int ref;
|
||||
lua_State *L;
|
||||
LuaNarrationHandler(lua_State *L, int ref)
|
||||
: ref(ref)
|
||||
, L(L)
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
L,
|
||||
[](lua_State *L) {
|
||||
luaL_checktype(L, 1, LUA_TSTRING);
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
LuaNarrationHandler *handler =
|
||||
static_cast<LuaNarrationHandler *>(
|
||||
lua_touserdata(
|
||||
L,
|
||||
lua_upvalueindex(1)));
|
||||
Ogre::String event = lua_tostring(L, 1);
|
||||
std::vector<Ogre::String> choices;
|
||||
int choicesLen = (int)lua_rawlen(L, 2);
|
||||
choices.reserve(choicesLen);
|
||||
for (int i = 1; i <= choicesLen; ++i) {
|
||||
lua_rawgeti(L, 2, i);
|
||||
if (lua_isstring(L, -1))
|
||||
choices.push_back(
|
||||
lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
handler->_narration(event, choices);
|
||||
return 0;
|
||||
},
|
||||
1);
|
||||
lua_setfield(L, -2, "_narration");
|
||||
lua_pushlightuserdata(L, this);
|
||||
lua_pushcclosure(
|
||||
L,
|
||||
[](lua_State *L) {
|
||||
LuaNarrationHandler *handler =
|
||||
static_cast<LuaNarrationHandler *>(
|
||||
lua_touserdata(
|
||||
L,
|
||||
lua_upvalueindex(1)));
|
||||
handler->_finish();
|
||||
return 0;
|
||||
},
|
||||
1);
|
||||
lua_setfield(L, -2, "_finish");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
void finish() override
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
int type = lua_getfield(L, -1, "finish");
|
||||
OgreAssert(type == LUA_TFUNCTION, "bad finish()");
|
||||
lua_insert(L, -2);
|
||||
if (lua_pcall(L, 1, 0, 0) != 0) {
|
||||
std::cerr << lua_tostring(L, -1) << std::endl;
|
||||
OgreAssert(false, "lua error");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
_clear_narration();
|
||||
}
|
||||
void activate() override
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
int type = lua_getfield(L, -1, "activate");
|
||||
OgreAssert(type == LUA_TFUNCTION, "bad activate()");
|
||||
lua_insert(L, -2);
|
||||
if (lua_pcall(L, 1, 0, 0) != 0) {
|
||||
std::cerr << lua_tostring(L, -1) << std::endl;
|
||||
OgreAssert(false, "lua error");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
// _narration("Greetings...", {});
|
||||
// std::cout << getPropsJSON().dump(4) << std::endl;
|
||||
}
|
||||
void event(const Ogre::String &evt) override
|
||||
{
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
|
||||
int type = lua_getfield(L, -1, "event");
|
||||
OgreAssert(type == LUA_TFUNCTION, "bad event()");
|
||||
lua_insert(L, -2);
|
||||
lua_pushstring(L, evt.c_str());
|
||||
if (lua_pcall(L, 2, 0, 0) != 0) {
|
||||
std::cerr << lua_tostring(L, -1) << std::endl;
|
||||
OgreAssert(false, "lua error");
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct SimpleWordHandler : PlayerActionModule::ActionWordHandler {
|
||||
void operator()(flecs::entity town, int index,
|
||||
const Ogre::String &word) override
|
||||
{
|
||||
TestNarrativeHandler *handle = OGRE_NEW TestNarrativeHandler();
|
||||
const TownNPCs::NPCData &npc =
|
||||
town.get<TownNPCs>().npcs.at(index);
|
||||
flecs::entity e = npc.e;
|
||||
for (const auto &anode : e.get<NPCActionNodes>().anodes) {
|
||||
if (anode.action == word) {
|
||||
nlohmann::json props = anode.props;
|
||||
props["initiator"] =
|
||||
ECS::get<CharacterManagerModule>()
|
||||
.getPlayer()
|
||||
.id();
|
||||
props["recipient"] = e.id();
|
||||
handle->setProperties(props.dump());
|
||||
break;
|
||||
}
|
||||
}
|
||||
ECS::get_mut<GUI>().addNarrationHandler(handle);
|
||||
ECS::modified<GUI>();
|
||||
}
|
||||
@@ -205,8 +314,8 @@ PlayerActionModule::PlayerActionModule(flecs::world &ecs)
|
||||
if (!ECS::get<GUI>().enabled)
|
||||
list.busy = false;
|
||||
});
|
||||
SimpleWordHandler *handler = OGRE_NEW SimpleWordHandler;
|
||||
addWordHandler("talk", handler);
|
||||
// SimpleWordHandler *handler = OGRE_NEW SimpleWordHandler;
|
||||
// addWordHandler("talk", handler);
|
||||
}
|
||||
|
||||
void PlayerActionModule::addWordHandler(const Ogre::String &word,
|
||||
@@ -233,13 +342,39 @@ struct LuaWordHandler : PlayerActionModule::ActionWordHandler {
|
||||
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");
|
||||
if (lua_type(L, -1) == LUA_TFUNCTION) {
|
||||
luaL_checktype(L, -1, LUA_TFUNCTION);
|
||||
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");
|
||||
}
|
||||
} else if (lua_type(L, -1) == LUA_TTABLE) {
|
||||
luaL_checktype(L, -1, LUA_TTABLE);
|
||||
lua_pop(L, 1);
|
||||
LuaNarrationHandler *handle =
|
||||
OGRE_NEW LuaNarrationHandler(L, ref);
|
||||
const TownNPCs::NPCData &npc =
|
||||
town.get<TownNPCs>().npcs.at(index);
|
||||
flecs::entity e = npc.e;
|
||||
for (const auto &anode :
|
||||
e.get<NPCActionNodes>().anodes) {
|
||||
if (anode.action == word) {
|
||||
nlohmann::json props = anode.props;
|
||||
props["initiator"] =
|
||||
ECS::get<CharacterManagerModule>()
|
||||
.getPlayer()
|
||||
.id();
|
||||
props["recipient"] = e.id();
|
||||
handle->setProperties(props.dump());
|
||||
break;
|
||||
}
|
||||
}
|
||||
ECS::get_mut<GUI>().addNarrationHandler(handle);
|
||||
ECS::modified<GUI>();
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -268,11 +403,19 @@ void PlayerActionModule::removeLuaWordHandler(const Ogre::String &word,
|
||||
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);
|
||||
if (lua_type(L, 2) == LUA_TFUNCTION) {
|
||||
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);
|
||||
} else if (lua_type(L, 2) == LUA_TTABLE) {
|
||||
luaL_checktype(L, 2, LUA_TTABLE);
|
||||
Ogre::String word = lua_tostring(L, 1);
|
||||
lua_pushvalue(L, 2);
|
||||
int ref = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
addLuaWordHandler(word, L, ref);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user