forked from metin2/server
871 lines
19 KiB
C++
871 lines
19 KiB
C++
|
||
#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;
|
||
}
|
||
}
|
||
}
|