server/game/src/questlua.cpp

871 lines
19 KiB
C++
Raw Normal View History

2022-03-05 12:44:06 +02:00
#include "stdafx.h"
#include <sstream>
#include "questmanager.h"
#include "questlua.h"
#include "config.h"
#include "desc.h"
#include "char.h"
#include "char_manager.h"
#include "buffer_manager.h"
#include "db.h"
#include "xmas_event.h"
#include "locale_service.h"
#include "regen.h"
#include "affect.h"
#include "guild.h"
#include "guild_manager.h"
#include "sectree_manager.h"
#undef sys_err
#ifndef __WIN32__
#define sys_err(fmt, args...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, ##args)
#else
#define sys_err(fmt, ...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, __VA_ARGS__)
#endif
namespace quest
{
using namespace std;
string ScriptToString(const string& str)
{
lua_State* L = CQuestManager::instance().GetLuaState();
int x = lua_gettop(L);
int errcode = lua_dobuffer(L, ("return "+str).c_str(), str.size()+7, "ScriptToString");
string retstr;
if (!errcode)
{
if (lua_isstring(L,-1))
retstr = lua_tostring(L, -1);
}
else
{
sys_err("LUA ScriptRunError (code:%d src:[%s])", errcode, str.c_str());
}
lua_settop(L,x);
return retstr;
}
void FSetWarpLocation::operator() (LPCHARACTER ch)
{
if (ch->IsPC())
{
ch->SetWarpLocation (map_index, x, y);
}
}
void FSetQuestFlag::operator() (LPCHARACTER ch)
{
if (!ch->IsPC())
return;
PC * pPC = CQuestManager::instance().GetPCForce(ch->GetPlayerID());
if (pPC)
pPC->SetFlag(flagname, value);
}
bool FPartyCheckFlagLt::operator() (LPCHARACTER ch)
{
if (!ch->IsPC())
return false;
PC * pPC = CQuestManager::instance().GetPCForce(ch->GetPlayerID());
bool returnBool;
if (pPC)
{
int flagValue = pPC->GetFlag(flagname);
if (value > flagValue)
returnBool = true;
else
returnBool = false;
}
return returnBool;
}
FPartyChat::FPartyChat(int ChatType, const char* str) : iChatType(ChatType), str(str)
{
}
void FPartyChat::operator() (LPCHARACTER ch)
{
ch->ChatPacket(iChatType, "%s", str);
}
void FPartyClearReady::operator() (LPCHARACTER ch)
{
ch->RemoveAffect(AFFECT_DUNGEON_READY);
}
void FSendPacket::operator() (LPENTITY ent)
{
if (ent->IsType(ENTITY_CHARACTER))
{
LPCHARACTER ch = (LPCHARACTER) ent;
if (ch->GetDesc())
{
ch->GetDesc()->Packet(buf.read_peek(), buf.size());
}
}
}
void FSendPacketToEmpire::operator() (LPENTITY ent)
{
if (ent->IsType(ENTITY_CHARACTER))
{
LPCHARACTER ch = (LPCHARACTER) ent;
if (ch->GetDesc())
{
if (ch->GetEmpire() == bEmpire)
ch->GetDesc()->Packet(buf.read_peek(), buf.size());
}
}
}
void FWarpEmpire::operator() (LPENTITY ent)
{
if (ent->IsType(ENTITY_CHARACTER))
{
LPCHARACTER ch = (LPCHARACTER) ent;
if (ch->IsPC() && ch->GetEmpire() == m_bEmpire)
{
ch->WarpSet(m_x, m_y, m_lMapIndexTo);
}
}
}
FBuildLuaGuildWarList::FBuildLuaGuildWarList(lua_State * lua_state) : L(lua_state), m_count(1)
{
lua_newtable(lua_state);
}
void FBuildLuaGuildWarList::operator() (DWORD g1, DWORD g2)
{
CGuild* g = CGuildManager::instance().FindGuild(g1);
if (!g)
return;
if (g->GetGuildWarType(g2) == GUILD_WAR_TYPE_FIELD)
return;
if (g->GetGuildWarState(g2) != GUILD_WAR_ON_WAR)
return;
lua_newtable(L);
lua_pushnumber(L, g1);
lua_rawseti(L, -2, 1);
lua_pushnumber(L, g2);
lua_rawseti(L, -2, 2);
lua_rawseti(L, -2, m_count++);
}
bool IsScriptTrue(const char* code, int size)
{
if (size==0)
return true;
lua_State* L = CQuestManager::instance().GetLuaState();
int x = lua_gettop(L);
int errcode = lua_dobuffer(L, code, size, "IsScriptTrue");
int bStart = lua_toboolean(L, -1);
if (errcode)
{
char buf[100];
snprintf(buf, sizeof(buf), "LUA ScriptRunError (code:%%d src:[%%%ds])", size);
sys_err(buf, errcode, code);
}
lua_settop(L,x);
return bStart != 0;
}
void combine_lua_string(lua_State * L, ostringstream & s)
{
char buf[32];
int n = lua_gettop(L);
int i;
for (i = 1; i <= n; ++i)
{
if (lua_isstring(L,i))
//printf("%s\n",lua_tostring(L,i));
s << lua_tostring(L, i);
else if (lua_isnumber(L, i))
{
snprintf(buf, sizeof(buf), "%.14g\n", lua_tonumber(L,i));
s << buf;
}
}
}
int highscore_show(lua_State* L)
{
CQuestManager & q = CQuestManager::instance();
const char * pszBoardName = lua_tostring(L, 1);
DWORD mypid = q.GetCurrentCharacterPtr()->GetPlayerID();
bool bOrder = (int) lua_tonumber(L, 2) != 0 ? true : false;
DBManager::instance().ReturnQuery(QID_HIGHSCORE_SHOW, mypid, NULL,
"SELECT h.pid, p.name, h.value FROM highscore%s as h, player%s as p WHERE h.board = '%s' AND h.pid = p.id ORDER BY h.value %s LIMIT 10",
get_table_postfix(), get_table_postfix(), pszBoardName, bOrder ? "DESC" : "");
return 0;
}
int highscore_register(lua_State* L)
{
CQuestManager & q = CQuestManager::instance();
THighscoreRegisterQueryInfo * qi = M2_NEW THighscoreRegisterQueryInfo;
2022-03-05 19:59:39 +02:00
strncpy(qi->szBoard, lua_tostring(L, 1), sizeof(qi->szBoard));
2022-03-05 12:44:06 +02:00
qi->dwPID = q.GetCurrentCharacterPtr()->GetPlayerID();
qi->iValue = (int) lua_tonumber(L, 2);
qi->bOrder = (int) lua_tonumber(L, 3);
DBManager::instance().ReturnQuery(QID_HIGHSCORE_REGISTER, qi->dwPID, qi,
"SELECT value FROM highscore%s WHERE board='%s' AND pid=%u", get_table_postfix(), qi->szBoard, qi->dwPID);
return 1;
}
//
// "member" Lua functions
//
int member_chat(lua_State* L)
{
ostringstream s;
combine_lua_string(L, s);
CQuestManager::Instance().GetCurrentPartyMember()->ChatPacket(CHAT_TYPE_TALKING, "%s", s.str().c_str());
return 0;
}
int member_clear_ready(lua_State* L)
{
LPCHARACTER ch = CQuestManager::instance().GetCurrentPartyMember();
ch->RemoveAffect(AFFECT_DUNGEON_READY);
return 0;
}
int member_set_ready(lua_State* L)
{
LPCHARACTER ch = CQuestManager::instance().GetCurrentPartyMember();
ch->AddAffect(AFFECT_DUNGEON_READY, POINT_NONE, 0, AFF_DUNGEON_READY, 65535, 0, true);
return 0;
}
int mob_spawn(lua_State* L)
{
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4))
{
sys_err("invalid argument");
return 0;
}
DWORD mob_vnum = (DWORD)lua_tonumber(L, 1);
int local_x = (int) lua_tonumber(L, 2)*100;
int local_y = (int) lua_tonumber(L, 3)*100;
2022-03-05 12:44:06 +02:00
float radius = (float) lua_tonumber(L, 4)*100;
bool bAggressive = lua_toboolean(L, 5);
DWORD count = (lua_isnumber(L, 6))?(DWORD) lua_tonumber(L, 6):1;
if (count == 0)
count = 1;
else if (count > 10)
{
sys_err("count bigger than 10");
count = 10;
}
LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(ch->GetMapIndex());
if (pMap == NULL) {
return 0;
}
DWORD dwQuestIdx = CQuestManager::instance().GetCurrentPC()->GetCurrentQuestIndex();
bool ret = false;
LPCHARACTER mob = NULL;
while (count--)
{
for (int loop = 0; loop < 8; ++loop)
{
float angle = number(0, 999) * M_PI * 2 / 1000;
float r = number(0, 999) * radius / 1000;
int x = local_x + pMap->m_setting.iBaseX + (int)(r * cos(angle));
int y = local_y + pMap->m_setting.iBaseY + (int)(r * sin(angle));
2022-03-05 12:44:06 +02:00
mob = CHARACTER_MANAGER::instance().SpawnMob(mob_vnum, ch->GetMapIndex(), x, y, 0);
if (mob)
break;
}
if (mob)
{
if (bAggressive)
mob->SetAggressive();
mob->SetQuestBy(dwQuestIdx);
if (!ret)
{
ret = true;
lua_pushnumber(L, (DWORD) mob->GetVID());
}
}
}
if (!ret)
lua_pushnumber(L, 0);
return 1;
}
int mob_spawn_group(lua_State* L)
{
if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4) || !lua_isnumber(L, 6))
{
sys_err("invalid argument");
lua_pushnumber(L, 0);
return 1;
}
DWORD group_vnum = (DWORD)lua_tonumber(L, 1);
int local_x = (int) lua_tonumber(L, 2) * 100;
int local_y = (int) lua_tonumber(L, 3) * 100;
2022-03-05 12:44:06 +02:00
float radius = (float) lua_tonumber(L, 4) * 100;
bool bAggressive = lua_toboolean(L, 5);
DWORD count = (DWORD) lua_tonumber(L, 6);
if (count == 0)
count = 1;
else if (count > 10)
{
sys_err("count bigger than 10");
count = 10;
}
LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(ch->GetMapIndex());
if (pMap == NULL) {
lua_pushnumber(L, 0);
return 1;
}
DWORD dwQuestIdx = CQuestManager::instance().GetCurrentPC()->GetCurrentQuestIndex();
bool ret = false;
LPCHARACTER mob = NULL;
while (count--)
{
for (int loop = 0; loop < 8; ++loop)
{
float angle = number(0, 999) * M_PI * 2 / 1000;
float r = number(0, 999)*radius/1000;
int x = local_x + pMap->m_setting.iBaseX + (int)(r * cos(angle));
int y = local_y + pMap->m_setting.iBaseY + (int)(r * sin(angle));
2022-03-05 12:44:06 +02:00
mob = CHARACTER_MANAGER::instance().SpawnGroup(group_vnum, ch->GetMapIndex(), x, y, x, y, NULL, bAggressive);
if (mob)
break;
}
if (mob)
{
mob->SetQuestBy(dwQuestIdx);
if (!ret)
{
ret = true;
lua_pushnumber(L, (DWORD) mob->GetVID());
}
}
}
if (!ret)
lua_pushnumber(L, 0);
return 1;
}
//
// global Lua functions
//
//
// Registers Lua function table
//
void CQuestManager::AddLuaFunctionTable(const char * c_pszName, luaL_reg * preg)
{
lua_newtable(L);
while ((preg->name))
{
lua_pushstring(L, preg->name);
lua_pushcfunction(L, preg->func);
lua_rawset(L, -3);
preg++;
}
lua_setglobal(L, c_pszName);
}
void CQuestManager::BuildStateIndexToName(const char* questName)
{
int x = lua_gettop(L);
lua_getglobal(L, questName);
if (lua_isnil(L,-1))
{
sys_err("QUEST wrong quest state file for quest %s",questName);
lua_settop(L,x);
return;
}
for (lua_pushnil(L); lua_next(L, -2);)
{
if (lua_isstring(L, -2) && lua_isnumber(L, -1))
{
lua_pushvalue(L, -2);
lua_rawset(L, -4);
}
else
{
lua_pop(L, 1);
}
}
lua_settop(L, x);
}
/**
* @version 05/06/08 Bang2ni - __get_guildid_byname <EFBFBD><EFBFBD>ũ<EFBFBD><EFBFBD>Ʈ <EFBFBD>Լ<EFBFBD> <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
bool CQuestManager::InitializeLua()
{
L = lua_open();
luaopen_base(L);
luaopen_table(L);
luaopen_string(L);
luaopen_math(L);
//TEMP
luaopen_io(L);
luaopen_debug(L);
RegisterAffectFunctionTable();
RegisterBuildingFunctionTable();
RegisterDungeonFunctionTable();
RegisterGameFunctionTable();
RegisterGuildFunctionTable();
RegisterHorseFunctionTable();
#ifdef __PET_SYSTEM__
RegisterPetFunctionTable();
#endif
RegisterITEMFunctionTable();
RegisterMarriageFunctionTable();
RegisterNPCFunctionTable();
RegisterPartyFunctionTable();
RegisterPCFunctionTable();
RegisterQuestFunctionTable();
RegisterTargetFunctionTable();
RegisterArenaFunctionTable();
RegisterForkedFunctionTable();
RegisterMonarchFunctionTable();
RegisterOXEventFunctionTable();
RegisterMgmtFunctionTable();
RegisterBattleArenaFunctionTable();
RegisterDanceEventFunctionTable();
RegisterDragonLairFunctionTable();
RegisterSpeedServerFunctionTable();
RegisterDragonSoulFunctionTable();
{
luaL_reg member_functions[] =
{
{ "chat", member_chat },
{ "set_ready", member_set_ready },
{ "clear_ready", member_clear_ready },
{ NULL, NULL }
};
AddLuaFunctionTable("member", member_functions);
}
{
luaL_reg highscore_functions[] =
{
{ "register", highscore_register },
{ "show", highscore_show },
{ NULL, NULL }
};
AddLuaFunctionTable("highscore", highscore_functions);
}
{
luaL_reg mob_functions[] =
{
{ "spawn", mob_spawn },
{ "spawn_group", mob_spawn_group },
{ NULL, NULL }
};
AddLuaFunctionTable("mob", mob_functions);
}
//
// global namespace functions
//
RegisterGlobalFunctionTable(L);
// LUA_INIT_ERROR_MESSAGE
{
char settingsFileName[256];
snprintf(settingsFileName, sizeof(settingsFileName), "%s/settings.lua", LocaleService_GetBasePath().c_str());
int settingsLoadingResult = lua_dofile(L, settingsFileName);
sys_log(0, "LoadSettings(%s), returns %d", settingsFileName, settingsLoadingResult);
if (settingsLoadingResult != 0)
{
sys_err("LOAD_SETTINS_FAILURE(%s)", settingsFileName);
return false;
}
}
{
char questlibFileName[256];
snprintf(questlibFileName, sizeof(questlibFileName), "%s/questlib.lua", LocaleService_GetQuestPath().c_str());
int questlibLoadingResult = lua_dofile(L, questlibFileName);
sys_log(0, "LoadQuestlib(%s), returns %d", questlibFileName, questlibLoadingResult);
if (questlibLoadingResult != 0)
{
sys_err("LOAD_QUESTLIB_FAILURE(%s)", questlibFileName);
return false;
}
}
if (LC_IsEurope())
{
char translateFileName[256];
snprintf(translateFileName, sizeof(translateFileName), "%s/translate.lua", LocaleService_GetBasePath().c_str());
int translateLoadingResult = lua_dofile(L, translateFileName);
sys_log(0, "LoadTranslate(%s), returns %d", translateFileName, translateLoadingResult);
if (translateLoadingResult != 0)
{
sys_err("LOAD_TRANSLATE_ERROR(%s)", translateFileName);
return false;
}
}
{
char questLocaleFileName[256];
if (LC_IsEurope())
{
snprintf(questLocaleFileName, sizeof(questLocaleFileName), "%s/locale.lua", g_stQuestDir.c_str());
}
else
{
snprintf(questLocaleFileName, sizeof(questLocaleFileName), "%s/locale_%s.lua", g_stQuestDir.c_str(), g_stLocale.c_str());
}
int questLocaleLoadingResult = lua_dofile(L, questLocaleFileName);
sys_log(0, "LoadQuestLocale(%s), returns %d", questLocaleFileName, questLocaleLoadingResult);
if (questLocaleLoadingResult != 0)
{
sys_err("LoadQuestLocale(%s) FAILURE", questLocaleFileName);
return false;
}
}
// END_OF_LUA_INIT_ERROR_MESSAGE
for (itertype(g_setQuestObjectDir) it = g_setQuestObjectDir.begin(); it != g_setQuestObjectDir.end(); ++it)
{
const string& stQuestObjectDir = *it;
char buf[PATH_MAX];
snprintf(buf, sizeof(buf), "%s/state/", stQuestObjectDir.c_str());
DIR * pdir = opendir(buf);
int iQuestIdx = 0;
if (pdir)
{
dirent * pde;
while ((pde = readdir(pdir)))
{
if (pde->d_name[0] == '.')
continue;
snprintf(buf + 11, sizeof(buf) - 11, "%s", pde->d_name);
RegisterQuest(pde->d_name, ++iQuestIdx);
int ret = lua_dofile(L, (stQuestObjectDir + "/state/" + pde->d_name).c_str());
sys_log(0, "QUEST: loading %s, returns %d", (stQuestObjectDir + "/state/" + pde->d_name).c_str(), ret);
BuildStateIndexToName(pde->d_name);
}
closedir(pdir);
}
}
lua_setgcthreshold(L, 0);
lua_newtable(L);
lua_setglobal(L, "__codecache");
return true;
}
void CQuestManager::GotoSelectState(QuestState& qs)
{
lua_checkstack(qs.co, 1);
//int n = lua_gettop(L);
int n = luaL_getn(qs.co, -1);
qs.args = n;
//cout << "select here (1-" << qs.args << ")" << endl;
//
ostringstream os;
os << "[QUESTION ";
for (int i=1; i<=n; i++)
{
lua_rawgeti(qs.co,-1,i);
if (lua_isstring(qs.co,-1))
{
//printf("%d\t%s\n",i,lua_tostring(qs.co,-1));
if (i != 1)
os << "|";
os << i << ";" << lua_tostring(qs.co,-1);
}
else
{
sys_err("SELECT wrong data %s", lua_typename(qs.co, -1));
sys_err("here");
}
lua_pop(qs.co,1);
}
os << "]";
AddScript(os.str());
qs.suspend_state = SUSPEND_STATE_SELECT;
if ( test_server )
sys_log( 0, "%s", m_strScript.c_str() );
SendScript();
}
EVENTINFO(confirm_timeout_event_info)
{
DWORD dwWaitPID;
DWORD dwReplyPID;
confirm_timeout_event_info()
: dwWaitPID( 0 )
, dwReplyPID( 0 )
{
}
};
EVENTFUNC(confirm_timeout_event)
{
confirm_timeout_event_info * info = dynamic_cast<confirm_timeout_event_info *>(event->info);
if ( info == NULL )
{
sys_err( "confirm_timeout_event> <Factor> Null pointer" );
return 0;
}
LPCHARACTER chWait = CHARACTER_MANAGER::instance().FindByPID(info->dwWaitPID);
LPCHARACTER chReply = NULL; //CHARACTER_MANAGER::info().FindByPID(info->dwReplyPID);
if (chReply)
{
// <20>ð<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>˾Ƽ<CBBE> <20><><EFBFBD><EFBFBD>
}
if (chWait)
{
CQuestManager::instance().Confirm(info->dwWaitPID, CONFIRM_TIMEOUT);
}
return 0;
}
void CQuestManager::GotoConfirmState(QuestState & qs)
{
qs.suspend_state = SUSPEND_STATE_CONFIRM;
DWORD dwVID = (DWORD) lua_tonumber(qs.co, -3);
const char* szMsg = lua_tostring(qs.co, -2);
int iTimeout = (int) lua_tonumber(qs.co, -1);
sys_log(0, "GotoConfirmState vid %u msg '%s', timeout %d", dwVID, szMsg, iTimeout);
// 1. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6BFA1> Ȯ<><C8AE>â <20><><EFBFBD><EFBFBD>
// 2. <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ȯ<><C8AE> <20><><EFBFBD>ٸ<EFBFBD><D9B8>ٰ<EFBFBD> ǥ<><C7A5><EFBFBD>ϴ<EFBFBD> â <20><><EFBFBD><EFBFBD>
// 3. Ÿ<>Ӿƿ<D3BE> <20><><EFBFBD><EFBFBD><>Ӿƿ<D3BE> <20>Ǹ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> â <20>ݰ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ե<EFBFBD> â <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>)
// 1
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>׳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6BFA1> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ʴ´<CAB4>. Ÿ<>Ӿƿ<D3BE><C6BF><EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> <20>Ѿ<D1BE>Ե<EFBFBD>
LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(dwVID);
if (ch && ch->IsPC())
{
ch->ConfirmWithMsg(szMsg, iTimeout, GetCurrentCharacterPtr()->GetPlayerID());
}
// 2
GetCurrentPC()->SetConfirmWait((ch && ch->IsPC())?ch->GetPlayerID():0);
ostringstream os;
os << "[CONFIRM_WAIT timeout;" << iTimeout << "]";
AddScript(os.str());
SendScript();
// 3
confirm_timeout_event_info* info = AllocEventInfo<confirm_timeout_event_info>();
info->dwWaitPID = GetCurrentCharacterPtr()->GetPlayerID();
info->dwReplyPID = (ch && ch->IsPC()) ? ch->GetPlayerID() : 0;
event_create(confirm_timeout_event, info, PASSES_PER_SEC(iTimeout));
}
void CQuestManager::GotoSelectItemState(QuestState& qs)
{
qs.suspend_state = SUSPEND_STATE_SELECT_ITEM;
AddScript("[SELECT_ITEM]");
SendScript();
}
void CQuestManager::GotoInputState(QuestState & qs)
{
qs.suspend_state = SUSPEND_STATE_INPUT;
AddScript("[INPUT]");
SendScript();
// <20>ð<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>
//event_create(input_timeout_event, dwEI, PASSES_PER_SEC(iTimeout));
}
void CQuestManager::GotoPauseState(QuestState & qs)
{
qs.suspend_state = SUSPEND_STATE_PAUSE;
AddScript("[NEXT]");
SendScript();
}
void CQuestManager::GotoEndState(QuestState & qs)
{
AddScript("[DONE]");
SendScript();
}
//
// * OpenState
//
// The beginning of script
//
QuestState CQuestManager::OpenState(const string& quest_name, int state_index)
{
QuestState qs;
qs.args=0;
qs.st = state_index;
qs.co = lua_newthread(L);
qs.ico = lua_ref(L, 1/*qs.co*/);
return qs;
}
//
// * RunState
//
// decides script to wait for user input, or finish
//
bool CQuestManager::RunState(QuestState & qs)
{
ClearError();
m_CurrentRunningState = &qs;
int ret = lua_resume(qs.co, qs.args);
if (ret == 0)
{
if (lua_gettop(qs.co) == 0)
{
// end of quest
GotoEndState(qs);
return false;
}
if (!strcmp(lua_tostring(qs.co, 1), "select"))
{
GotoSelectState(qs);
return true;
}
if (!strcmp(lua_tostring(qs.co, 1), "wait"))
{
GotoPauseState(qs);
return true;
}
if (!strcmp(lua_tostring(qs.co, 1), "input"))
{
GotoInputState(qs);
return true;
}
if (!strcmp(lua_tostring(qs.co, 1), "confirm"))
{
GotoConfirmState(qs);
return true;
}
if (!strcmp(lua_tostring(qs.co, 1), "select_item"))
{
GotoSelectItemState(qs);
return true;
}
}
else
{
sys_err("LUA_ERROR: %s", lua_tostring(qs.co, 1));
}
WriteRunningStateToSyserr();
SetError();
GotoEndState(qs);
return false;
}
//
// * CloseState
//
// makes script end
//
void CQuestManager::CloseState(QuestState& qs)
{
if (qs.co)
{
//cerr << "ICO "<<qs.ico <<endl;
lua_unref(L, qs.ico);
qs.co = 0;
}
}
}