SabrehavenServer/src/talkaction.cpp
2019-09-16 20:38:16 +03:00

155 lines
4.0 KiB
C++

/**
* Tibia GIMUD Server - a free and open-source MMORPG server emulator
* Copyright (C) 2019 Sabrehaven and Mark Samman <mark.samman@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "otpch.h"
#include "player.h"
#include "talkaction.h"
#include "pugicast.h"
TalkActions::TalkActions()
: scriptInterface("TalkAction Interface")
{
scriptInterface.initState();
}
TalkActions::~TalkActions()
{
clear();
}
void TalkActions::clear()
{
talkActions.clear();
scriptInterface.reInitState();
}
LuaScriptInterface& TalkActions::getScriptInterface()
{
return scriptInterface;
}
std::string TalkActions::getScriptBaseName() const
{
return "talkactions";
}
Event* TalkActions::getEvent(const std::string& nodeName)
{
if (strcasecmp(nodeName.c_str(), "talkaction") != 0) {
return nullptr;
}
return new TalkAction(&scriptInterface);
}
bool TalkActions::registerEvent(Event* event, const pugi::xml_node&)
{
auto talkAction = std::unique_ptr<TalkAction>(static_cast<TalkAction*>(event)); // event is guaranteed to be a TalkAction
talkActions.push_front(std::move(*talkAction));
return true;
}
TalkActionResult_t TalkActions::playerSaySpell(Player* player, SpeakClasses type, const std::string& words) const
{
size_t wordsLength = words.length();
for (const TalkAction& talkAction : talkActions) {
const std::string& talkactionWords = talkAction.getWords();
size_t talkactionLength = talkactionWords.length();
if (wordsLength < talkactionLength || strncasecmp(words.c_str(), talkactionWords.c_str(), talkactionLength) != 0) {
continue;
}
std::string param;
if (wordsLength != talkactionLength) {
param = words.substr(talkactionLength);
if (param.front() != ' ') {
continue;
}
trim_left(param, ' ');
char separator = talkAction.getSeparator();
if (separator != ' ') {
if (!param.empty()) {
if (param.front() != separator) {
continue;
} else {
param.erase(param.begin());
}
}
}
}
if (talkAction.executeSay(player, param, type)) {
return TALKACTION_CONTINUE;
} else {
return TALKACTION_BREAK;
}
}
return TALKACTION_CONTINUE;
}
bool TalkAction::configureEvent(const pugi::xml_node& node)
{
pugi::xml_attribute wordsAttribute = node.attribute("words");
if (!wordsAttribute) {
std::cout << "[Error - TalkAction::configureEvent] Missing words for talk action or spell" << std::endl;
return false;
}
pugi::xml_attribute separatorAttribute = node.attribute("separator");
if (separatorAttribute) {
separator = pugi::cast<char>(separatorAttribute.value());
}
words = wordsAttribute.as_string();
return true;
}
std::string TalkAction::getScriptEventName() const
{
return "onSay";
}
bool TalkAction::executeSay(Player* player, const std::string& param, SpeakClasses type) const
{
//onSay(player, words, param, type)
if (!scriptInterface->reserveScriptEnv()) {
std::cout << "[Error - TalkAction::executeSay] Call stack overflow" << std::endl;
return false;
}
ScriptEnvironment* env = scriptInterface->getScriptEnv();
env->setScriptId(scriptId, scriptInterface);
lua_State* L = scriptInterface->getLuaState();
scriptInterface->pushFunction(scriptId);
LuaScriptInterface::pushUserdata<Player>(L, player);
LuaScriptInterface::setMetatable(L, -1, "Player");
LuaScriptInterface::pushString(L, words);
LuaScriptInterface::pushString(L, param);
lua_pushnumber(L, type);
return scriptInterface->callFunction(4);
}