server/game/src/questlua.cpp

871 lines
19 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
strncpy(qi->szBoard, lua_tostring(L, 1), sizeof(qi->szBoard));
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;
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));
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;
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));
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 <20><>ũ<EFBFBD><C5A9>Ʈ <20>Լ<EFBFBD> <20><><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;
}
}
}