Advertisement
Guest User

questlua.cpp

a guest
Jul 17th, 2015
37
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. #include "stdafx.h"
  3.  
  4. #include <sstream>
  5.  
  6. #include "questmanager.h"
  7. #include "questlua.h"
  8. #include "config.h"
  9. #include "desc.h"
  10. #include "char.h"
  11. #include "char_manager.h"
  12. #include "buffer_manager.h"
  13. #include "db.h"
  14. #include "xmas_event.h"
  15. #include "locale_service.h"
  16. #include "regen.h"
  17. #include "affect.h"
  18. #include "guild.h"
  19. #include "guild_manager.h"
  20. #include "sectree_manager.h"
  21.  
  22. #undef sys_err
  23. #ifndef __WIN32__
  24. #define sys_err(fmt, args...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, ##args)
  25. #else
  26. #define sys_err(fmt, ...) quest::CQuestManager::instance().QuestError(__FUNCTION__, __LINE__, fmt, __VA_ARGS__)
  27. #endif
  28.  
  29. namespace quest
  30. {
  31. using namespace std;
  32.  
  33. string ScriptToString(const string& str)
  34. {
  35. lua_State* L = CQuestManager::instance().GetLuaState();
  36. int x = lua_gettop(L);
  37.  
  38. int errcode = lua_dobuffer(L, ("return "+str).c_str(), str.size()+7, "ScriptToString");
  39. string retstr;
  40. if (!errcode)
  41. {
  42. if (lua_isstring(L,-1))
  43. retstr = lua_tostring(L, -1);
  44. }
  45. else
  46. {
  47. sys_err("LUA ScriptRunError (code:%d src:[%s])", errcode, str.c_str());
  48. }
  49. lua_settop(L,x);
  50. return retstr;
  51. }
  52.  
  53. void FSetWarpLocation::operator() (LPCHARACTER ch)
  54. {
  55. if (ch->IsPC())
  56. {
  57. ch->SetWarpLocation (map_index, x, y);
  58. }
  59. }
  60.  
  61. void FSetQuestFlag::operator() (LPCHARACTER ch)
  62. {
  63. if (!ch->IsPC())
  64. return;
  65.  
  66. PC * pPC = CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  67.  
  68. if (pPC)
  69. pPC->SetFlag(flagname, value);
  70. }
  71.  
  72. bool FPartyCheckFlagLt::operator() (LPCHARACTER ch)
  73. {
  74. if (!ch->IsPC())
  75. return false;
  76.  
  77. PC * pPC = CQuestManager::instance().GetPCForce(ch->GetPlayerID());
  78. bool returnBool;
  79. if (pPC)
  80. {
  81. int flagValue = pPC->GetFlag(flagname);
  82. if (value > flagValue)
  83. returnBool = true;
  84. else
  85. returnBool = false;
  86. }
  87.  
  88. return returnBool;
  89. }
  90.  
  91. FPartyChat::FPartyChat(int ChatType, const char* str) : iChatType(ChatType), str(str)
  92. {
  93. }
  94.  
  95. void FPartyChat::operator() (LPCHARACTER ch)
  96. {
  97. ch->ChatPacket(iChatType, "%s", str);
  98. }
  99.  
  100. void FPartyClearReady::operator() (LPCHARACTER ch)
  101. {
  102. ch->RemoveAffect(AFFECT_DUNGEON_READY);
  103. }
  104.  
  105. void FSendPacket::operator() (LPENTITY ent)
  106. {
  107. if (ent->IsType(ENTITY_CHARACTER))
  108. {
  109. LPCHARACTER ch = (LPCHARACTER) ent;
  110.  
  111. if (ch->GetDesc())
  112. {
  113. ch->GetDesc()->Packet(buf.read_peek(), buf.size());
  114. }
  115. }
  116. }
  117.  
  118. void FSendPacketToEmpire::operator() (LPENTITY ent)
  119. {
  120. if (ent->IsType(ENTITY_CHARACTER))
  121. {
  122. LPCHARACTER ch = (LPCHARACTER) ent;
  123.  
  124. if (ch->GetDesc())
  125. {
  126. if (ch->GetEmpire() == bEmpire)
  127. ch->GetDesc()->Packet(buf.read_peek(), buf.size());
  128. }
  129. }
  130. }
  131.  
  132. void FWarpEmpire::operator() (LPENTITY ent)
  133. {
  134. if (ent->IsType(ENTITY_CHARACTER))
  135. {
  136. LPCHARACTER ch = (LPCHARACTER) ent;
  137.  
  138. if (ch->IsPC() && ch->GetEmpire() == m_bEmpire)
  139. {
  140. ch->WarpSet(m_x, m_y, m_lMapIndexTo);
  141. }
  142. }
  143. }
  144.  
  145. FBuildLuaGuildWarList::FBuildLuaGuildWarList(lua_State * lua_state) : L(lua_state), m_count(1)
  146. {
  147. lua_newtable(lua_state);
  148. }
  149.  
  150. void FBuildLuaGuildWarList::operator() (DWORD g1, DWORD g2)
  151. {
  152. CGuild* g = CGuildManager::instance().FindGuild(g1);
  153.  
  154. if (!g)
  155. return;
  156.  
  157. if (g->GetGuildWarType(g2) == GUILD_WAR_TYPE_FIELD)
  158. return;
  159.  
  160. if (g->GetGuildWarState(g2) != GUILD_WAR_ON_WAR)
  161. return;
  162.  
  163. lua_newtable(L);
  164. lua_pushnumber(L, g1);
  165. lua_rawseti(L, -2, 1);
  166. lua_pushnumber(L, g2);
  167. lua_rawseti(L, -2, 2);
  168. lua_rawseti(L, -2, m_count++);
  169. }
  170.  
  171. bool IsScriptTrue(const char* code, int size)
  172. {
  173. if (size==0)
  174. return true;
  175.  
  176. lua_State* L = CQuestManager::instance().GetLuaState();
  177. int x = lua_gettop(L);
  178. int errcode = lua_dobuffer(L, code, size, "IsScriptTrue");
  179. int bStart = lua_toboolean(L, -1);
  180. if (errcode)
  181. {
  182. char buf[100];
  183. snprintf(buf, sizeof(buf), "LUA ScriptRunError (code:%%d src:[%%%ds])", size);
  184. sys_err(buf, errcode, code);
  185. }
  186. lua_settop(L,x);
  187. return bStart != 0;
  188. }
  189.  
  190. void combine_lua_string(lua_State * L, ostringstream & s)
  191. {
  192. char buf[32];
  193.  
  194. int n = lua_gettop(L);
  195. int i;
  196.  
  197. for (i = 1; i <= n; ++i)
  198. {
  199. if (lua_isstring(L,i))
  200. //printf("%s\n",lua_tostring(L,i));
  201. s << lua_tostring(L, i);
  202. else if (lua_isnumber(L, i))
  203. {
  204. snprintf(buf, sizeof(buf), "%.14g\n", lua_tonumber(L,i));
  205. s << buf;
  206. }
  207. }
  208. }
  209.  
  210. int highscore_show(lua_State* L)
  211. {
  212. CQuestManager & q = CQuestManager::instance();
  213. const char * pszBoardName = lua_tostring(L, 1);
  214. DWORD mypid = q.GetCurrentCharacterPtr()->GetPlayerID();
  215. bool bOrder = (int) lua_tonumber(L, 2) != 0 ? true : false;
  216.  
  217. DBManager::instance().ReturnQuery(QID_HIGHSCORE_SHOW, mypid, NULL,
  218. "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",
  219. get_table_postfix(), get_table_postfix(), pszBoardName, bOrder ? "DESC" : "");
  220. return 0;
  221. }
  222.  
  223. int highscore_register(lua_State* L)
  224. {
  225. CQuestManager & q = CQuestManager::instance();
  226.  
  227. THighscoreRegisterQueryInfo * qi = M2_NEW THighscoreRegisterQueryInfo;
  228.  
  229. strlcpy(qi->szBoard, lua_tostring(L, 1), sizeof(qi->szBoard));
  230. qi->dwPID = q.GetCurrentCharacterPtr()->GetPlayerID();
  231. qi->iValue = (int) lua_tonumber(L, 2);
  232. qi->bOrder = (int) lua_tonumber(L, 3);
  233.  
  234. DBManager::instance().ReturnQuery(QID_HIGHSCORE_REGISTER, qi->dwPID, qi,
  235. "SELECT value FROM highscore%s WHERE board='%s' AND pid=%u", get_table_postfix(), qi->szBoard, qi->dwPID);
  236. return 1;
  237. }
  238.  
  239. //
  240. // "member" Lua functions
  241. //
  242. int member_chat(lua_State* L)
  243. {
  244. ostringstream s;
  245. combine_lua_string(L, s);
  246. CQuestManager::Instance().GetCurrentPartyMember()->ChatPacket(CHAT_TYPE_TALKING, "%s", s.str().c_str());
  247. return 0;
  248. }
  249.  
  250. int member_clear_ready(lua_State* L)
  251. {
  252. LPCHARACTER ch = CQuestManager::instance().GetCurrentPartyMember();
  253. ch->RemoveAffect(AFFECT_DUNGEON_READY);
  254. return 0;
  255. }
  256.  
  257. int member_set_ready(lua_State* L)
  258. {
  259. LPCHARACTER ch = CQuestManager::instance().GetCurrentPartyMember();
  260. ch->AddAffect(AFFECT_DUNGEON_READY, POINT_NONE, 0, AFF_DUNGEON_READY, 65535, 0, true);
  261. return 0;
  262. }
  263.  
  264. int mob_spawn(lua_State* L)
  265. {
  266. if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4))
  267. {
  268. sys_err("invalid argument");
  269. return 0;
  270. }
  271.  
  272. DWORD mob_vnum = (DWORD)lua_tonumber(L, 1);
  273. long local_x = (long) lua_tonumber(L, 2)*100;
  274. long local_y = (long) lua_tonumber(L, 3)*100;
  275. float radius = (float) lua_tonumber(L, 4)*100;
  276. bool bAggressive = lua_toboolean(L, 5);
  277. DWORD count = (lua_isnumber(L, 6))?(DWORD) lua_tonumber(L, 6):1;
  278.  
  279. if (count == 0)
  280. count = 1;
  281. else if (count > 10)
  282. {
  283. sys_err("count bigger than 10");
  284. count = 10;
  285. }
  286.  
  287. LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
  288. LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(ch->GetMapIndex());
  289. if (pMap == NULL) {
  290. return 0;
  291. }
  292. DWORD dwQuestIdx = CQuestManager::instance().GetCurrentPC()->GetCurrentQuestIndex();
  293.  
  294. bool ret = false;
  295. LPCHARACTER mob = NULL;
  296.  
  297. while (count--)
  298. {
  299. for (int loop = 0; loop < 8; ++loop)
  300. {
  301. float angle = number(0, 999) * M_PI * 2 / 1000;
  302. float r = number(0, 999) * radius / 1000;
  303.  
  304. long x = local_x + pMap->m_setting.iBaseX + (long)(r * cos(angle));
  305. long y = local_y + pMap->m_setting.iBaseY + (long)(r * sin(angle));
  306.  
  307. mob = CHARACTER_MANAGER::instance().SpawnMob(mob_vnum, ch->GetMapIndex(), x, y, 0);
  308.  
  309. if (mob)
  310. break;
  311. }
  312.  
  313. if (mob)
  314. {
  315. if (bAggressive)
  316. mob->SetAggressive();
  317.  
  318. mob->SetQuestBy(dwQuestIdx);
  319.  
  320. if (!ret)
  321. {
  322. ret = true;
  323. lua_pushnumber(L, (DWORD) mob->GetVID());
  324. }
  325. }
  326. }
  327.  
  328. if (!ret)
  329. lua_pushnumber(L, 0);
  330.  
  331. return 1;
  332. }
  333.  
  334. int mob_spawn_group(lua_State* L)
  335. {
  336. if (!lua_isnumber(L, 1) || !lua_isnumber(L, 2) || !lua_isnumber(L, 3) || !lua_isnumber(L, 4) || !lua_isnumber(L, 6))
  337. {
  338. sys_err("invalid argument");
  339. lua_pushnumber(L, 0);
  340. return 1;
  341. }
  342.  
  343. DWORD group_vnum = (DWORD)lua_tonumber(L, 1);
  344. long local_x = (long) lua_tonumber(L, 2) * 100;
  345. long local_y = (long) lua_tonumber(L, 3) * 100;
  346. float radius = (float) lua_tonumber(L, 4) * 100;
  347. bool bAggressive = lua_toboolean(L, 5);
  348. DWORD count = (DWORD) lua_tonumber(L, 6);
  349.  
  350. if (count == 0)
  351. count = 1;
  352. else if (count > 10)
  353. {
  354. sys_err("count bigger than 10");
  355. count = 10;
  356. }
  357.  
  358. LPCHARACTER ch = CQuestManager::instance().GetCurrentCharacterPtr();
  359. LPSECTREE_MAP pMap = SECTREE_MANAGER::instance().GetMap(ch->GetMapIndex());
  360. if (pMap == NULL) {
  361. lua_pushnumber(L, 0);
  362. return 1;
  363. }
  364. DWORD dwQuestIdx = CQuestManager::instance().GetCurrentPC()->GetCurrentQuestIndex();
  365.  
  366. bool ret = false;
  367. LPCHARACTER mob = NULL;
  368.  
  369. while (count--)
  370. {
  371. for (int loop = 0; loop < 8; ++loop)
  372. {
  373. float angle = number(0, 999) * M_PI * 2 / 1000;
  374. float r = number(0, 999)*radius/1000;
  375.  
  376. long x = local_x + pMap->m_setting.iBaseX + (long)(r * cos(angle));
  377. long y = local_y + pMap->m_setting.iBaseY + (long)(r * sin(angle));
  378.  
  379. mob = CHARACTER_MANAGER::instance().SpawnGroup(group_vnum, ch->GetMapIndex(), x, y, x, y, NULL, bAggressive);
  380.  
  381. if (mob)
  382. break;
  383. }
  384.  
  385. if (mob)
  386. {
  387. mob->SetQuestBy(dwQuestIdx);
  388.  
  389. if (!ret)
  390. {
  391. ret = true;
  392. lua_pushnumber(L, (DWORD) mob->GetVID());
  393. }
  394. }
  395. }
  396.  
  397. if (!ret)
  398. lua_pushnumber(L, 0);
  399.  
  400. return 1;
  401. }
  402.  
  403. //
  404. // global Lua functions
  405. //
  406. //
  407. // Registers Lua function table
  408. //
  409. void CQuestManager::AddLuaFunctionTable(const char * c_pszName, luaL_reg * preg)
  410. {
  411. lua_newtable(L);
  412.  
  413. while ((preg->name))
  414. {
  415. lua_pushstring(L, preg->name);
  416. lua_pushcfunction(L, preg->func);
  417. lua_rawset(L, -3);
  418. preg++;
  419. }
  420.  
  421. lua_setglobal(L, c_pszName);
  422. }
  423.  
  424. void CQuestManager::BuildStateIndexToName(const char* questName)
  425. {
  426. int x = lua_gettop(L);
  427. lua_getglobal(L, questName);
  428.  
  429. if (lua_isnil(L,-1))
  430. {
  431. sys_err("QUEST wrong quest state file for quest %s",questName);
  432. lua_settop(L,x);
  433. return;
  434. }
  435.  
  436. for (lua_pushnil(L); lua_next(L, -2);)
  437. {
  438. if (lua_isstring(L, -2) && lua_isnumber(L, -1))
  439. {
  440. lua_pushvalue(L, -2);
  441. lua_rawset(L, -4);
  442. }
  443. else
  444. {
  445. lua_pop(L, 1);
  446. }
  447. }
  448.  
  449. lua_settop(L, x);
  450. }
  451.  
  452. /**
  453. * @version 05/06/08 Bang2ni - __get_guildid_byname 스크립트 함수 등록
  454. */
  455. bool CQuestManager::InitializeLua()
  456. {
  457. L = lua_open();
  458.  
  459. luaopen_base(L);
  460. luaopen_table(L);
  461. luaopen_string(L);
  462. luaopen_math(L);
  463. //TEMP
  464. luaopen_io(L);
  465. luaopen_debug(L);
  466.  
  467. RegisterAffectFunctionTable();
  468. RegisterBuildingFunctionTable();
  469. RegisterDungeonFunctionTable();
  470. RegisterGameFunctionTable();
  471. RegisterGuildFunctionTable();
  472. RegisterHorseFunctionTable();
  473. #ifdef __PET_SYSTEM__
  474. RegisterPetFunctionTable();
  475. #endif
  476. RegisterITEMFunctionTable();
  477. RegisterMarriageFunctionTable();
  478. RegisterNPCFunctionTable();
  479. RegisterPartyFunctionTable();
  480. RegisterPCFunctionTable();
  481. RegisterQuestFunctionTable();
  482. RegisterTargetFunctionTable();
  483. RegisterArenaFunctionTable();
  484. RegisterForkedFunctionTable();
  485. RegisterMonarchFunctionTable();
  486. RegisterOXEventFunctionTable();
  487. RegisterMgmtFunctionTable();
  488. RegisterBattleArenaFunctionTable();
  489. RegisterDanceEventFunctionTable();
  490. RegisterDragonLairFunctionTable();
  491. RegisterSpeedServerFunctionTable();
  492. RegisterDragonSoulFunctionTable();
  493. RegisterMysqlFunctionTable();
  494.  
  495. {
  496. luaL_reg member_functions[] =
  497. {
  498. { "chat", member_chat },
  499. { "set_ready", member_set_ready },
  500. { "clear_ready", member_clear_ready },
  501. { NULL, NULL }
  502. };
  503.  
  504. AddLuaFunctionTable("member", member_functions);
  505. }
  506.  
  507. {
  508. luaL_reg highscore_functions[] =
  509. {
  510. { "register", highscore_register },
  511. { "show", highscore_show },
  512. { NULL, NULL }
  513. };
  514.  
  515. AddLuaFunctionTable("highscore", highscore_functions);
  516. }
  517.  
  518. {
  519. luaL_reg mob_functions[] =
  520. {
  521. { "spawn", mob_spawn },
  522. { "spawn_group", mob_spawn_group },
  523. { NULL, NULL }
  524. };
  525.  
  526. AddLuaFunctionTable("mob", mob_functions);
  527. }
  528.  
  529. //
  530. // global namespace functions
  531. //
  532. RegisterGlobalFunctionTable(L);
  533.  
  534. // LUA_INIT_ERROR_MESSAGE
  535. {
  536. char settingsFileName[256];
  537. snprintf(settingsFileName, sizeof(settingsFileName), "%s/settings.lua", LocaleService_GetBasePath().c_str());
  538.  
  539. int settingsLoadingResult = lua_dofile(L, settingsFileName);
  540. sys_log(0, "LoadSettings(%s), returns %d", settingsFileName, settingsLoadingResult);
  541. if (settingsLoadingResult != 0)
  542. {
  543. sys_err("LOAD_SETTINS_FAILURE(%s)", settingsFileName);
  544. return false;
  545. }
  546. }
  547.  
  548. {
  549. char questlibFileName[256];
  550. snprintf(questlibFileName, sizeof(questlibFileName), "%s/questlib.lua", LocaleService_GetQuestPath().c_str());
  551.  
  552. int questlibLoadingResult = lua_dofile(L, questlibFileName);
  553. sys_log(0, "LoadQuestlib(%s), returns %d", questlibFileName, questlibLoadingResult);
  554. if (questlibLoadingResult != 0)
  555. {
  556. sys_err("LOAD_QUESTLIB_FAILURE(%s)", questlibFileName);
  557. return false;
  558. }
  559. }
  560.  
  561. if (LC_IsEurope())
  562. {
  563. char translateFileName[256];
  564. snprintf(translateFileName, sizeof(translateFileName), "%s/translate.lua", LocaleService_GetBasePath().c_str());
  565.  
  566. int translateLoadingResult = lua_dofile(L, translateFileName);
  567. sys_log(0, "LoadTranslate(%s), returns %d", translateFileName, translateLoadingResult);
  568. if (translateLoadingResult != 0)
  569. {
  570. sys_err("LOAD_TRANSLATE_ERROR(%s)", translateFileName);
  571. return false;
  572. }
  573. }
  574.  
  575. {
  576. char questLocaleFileName[256];
  577. if (LC_IsEurope())
  578. {
  579. snprintf(questLocaleFileName, sizeof(questLocaleFileName), "%s/locale.lua", g_stQuestDir.c_str());
  580. }
  581. else
  582. {
  583. snprintf(questLocaleFileName, sizeof(questLocaleFileName), "%s/locale_%s.lua", g_stQuestDir.c_str(), g_stLocale.c_str());
  584. }
  585.  
  586. int questLocaleLoadingResult = lua_dofile(L, questLocaleFileName);
  587. sys_log(0, "LoadQuestLocale(%s), returns %d", questLocaleFileName, questLocaleLoadingResult);
  588. if (questLocaleLoadingResult != 0)
  589. {
  590. sys_err("LoadQuestLocale(%s) FAILURE", questLocaleFileName);
  591. return false;
  592. }
  593. }
  594. // END_OF_LUA_INIT_ERROR_MESSAGE
  595.  
  596. for (itertype(g_setQuestObjectDir) it = g_setQuestObjectDir.begin(); it != g_setQuestObjectDir.end(); ++it)
  597. {
  598. const string& stQuestObjectDir = *it;
  599. char buf[PATH_MAX];
  600. snprintf(buf, sizeof(buf), "%s/state/", stQuestObjectDir.c_str());
  601. DIR * pdir = opendir(buf);
  602. int iQuestIdx = 0;
  603.  
  604. if (pdir)
  605. {
  606. dirent * pde;
  607.  
  608. while ((pde = readdir(pdir)))
  609. {
  610. if (pde->d_name[0] == '.')
  611. continue;
  612.  
  613. snprintf(buf + 11, sizeof(buf) - 11, "%s", pde->d_name);
  614.  
  615. RegisterQuest(pde->d_name, ++iQuestIdx);
  616. int ret = lua_dofile(L, (stQuestObjectDir + "/state/" + pde->d_name).c_str());
  617. sys_log(0, "QUEST: loading %s, returns %d", (stQuestObjectDir + "/state/" + pde->d_name).c_str(), ret);
  618.  
  619. BuildStateIndexToName(pde->d_name);
  620. }
  621.  
  622. closedir(pdir);
  623. }
  624. }
  625.  
  626. lua_setgcthreshold(L, 0);
  627.  
  628. lua_newtable(L);
  629. lua_setglobal(L, "__codecache");
  630. return true;
  631. }
  632.  
  633. void CQuestManager::GotoSelectState(QuestState& qs)
  634. {
  635. lua_checkstack(qs.co, 1);
  636.  
  637. //int n = lua_gettop(L);
  638. int n = luaL_getn(qs.co, -1);
  639. qs.args = n;
  640. //cout << "select here (1-" << qs.args << ")" << endl;
  641. //
  642.  
  643. ostringstream os;
  644. os << "[QUESTION ";
  645.  
  646. for (int i=1; i<=n; i++)
  647. {
  648. lua_rawgeti(qs.co,-1,i);
  649. if (lua_isstring(qs.co,-1))
  650. {
  651. //printf("%d\t%s\n",i,lua_tostring(qs.co,-1));
  652. if (i != 1)
  653. os << "|";
  654. os << i << ";" << lua_tostring(qs.co,-1);
  655. }
  656. else
  657. {
  658. sys_err("SELECT wrong data %s", lua_typename(qs.co, -1));
  659. sys_err("here");
  660. }
  661. lua_pop(qs.co,1);
  662. }
  663. os << "]";
  664.  
  665.  
  666. AddScript(os.str());
  667. qs.suspend_state = SUSPEND_STATE_SELECT;
  668. if ( test_server )
  669. sys_log( 0, "%s", m_strScript.c_str() );
  670. SendScript();
  671. }
  672.  
  673. EVENTINFO(confirm_timeout_event_info)
  674. {
  675. DWORD dwWaitPID;
  676. DWORD dwReplyPID;
  677.  
  678. confirm_timeout_event_info()
  679. : dwWaitPID( 0 )
  680. , dwReplyPID( 0 )
  681. {
  682. }
  683. };
  684.  
  685. EVENTFUNC(confirm_timeout_event)
  686. {
  687. confirm_timeout_event_info * info = dynamic_cast<confirm_timeout_event_info *>(event->info);
  688.  
  689. if ( info == NULL )
  690. {
  691. sys_err( "confirm_timeout_event> <Factor> Null pointer" );
  692. return 0;
  693. }
  694.  
  695. LPCHARACTER chWait = CHARACTER_MANAGER::instance().FindByPID(info->dwWaitPID);
  696. LPCHARACTER chReply = NULL; //CHARACTER_MANAGER::info().FindByPID(info->dwReplyPID);
  697.  
  698. if (chReply)
  699. {
  700. // 시간 지나면 알아서 닫힘
  701. }
  702.  
  703. if (chWait)
  704. {
  705. CQuestManager::instance().Confirm(info->dwWaitPID, CONFIRM_TIMEOUT);
  706. }
  707.  
  708. return 0;
  709. }
  710.  
  711. void CQuestManager::GotoConfirmState(QuestState & qs)
  712. {
  713. qs.suspend_state = SUSPEND_STATE_CONFIRM;
  714. DWORD dwVID = (DWORD) lua_tonumber(qs.co, -3);
  715. const char* szMsg = lua_tostring(qs.co, -2);
  716. int iTimeout = (int) lua_tonumber(qs.co, -1);
  717.  
  718. sys_log(0, "GotoConfirmState vid %u msg '%s', timeout %d", dwVID, szMsg, iTimeout);
  719.  
  720. // 1. 상대방에게 확인창 띄움
  721. // 2. 나에게 확인 기다린다고 표시하는 창 띄움
  722. // 3. 타임아웃 설정 (타임아웃 되면 상대방 창 닫고 나에게도 창 닫으라고 보냄)
  723.  
  724. // 1
  725. // 상대방이 없는 경우는 그냥 상대방에게 보내지 않는다. 타임아웃에 의해서 넘어가게됨
  726. LPCHARACTER ch = CHARACTER_MANAGER::instance().Find(dwVID);
  727. if (ch && ch->IsPC())
  728. {
  729. ch->ConfirmWithMsg(szMsg, iTimeout, GetCurrentCharacterPtr()->GetPlayerID());
  730. }
  731.  
  732. // 2
  733. GetCurrentPC()->SetConfirmWait((ch && ch->IsPC())?ch->GetPlayerID():0);
  734. ostringstream os;
  735. os << "[CONFIRM_WAIT timeout;" << iTimeout << "]";
  736. AddScript(os.str());
  737. SendScript();
  738.  
  739. // 3
  740. confirm_timeout_event_info* info = AllocEventInfo<confirm_timeout_event_info>();
  741.  
  742. info->dwWaitPID = GetCurrentCharacterPtr()->GetPlayerID();
  743. info->dwReplyPID = (ch && ch->IsPC()) ? ch->GetPlayerID() : 0;
  744.  
  745. event_create(confirm_timeout_event, info, PASSES_PER_SEC(iTimeout));
  746. }
  747.  
  748. void CQuestManager::GotoSelectItemState(QuestState& qs)
  749. {
  750. qs.suspend_state = SUSPEND_STATE_SELECT_ITEM;
  751. AddScript("[SELECT_ITEM]");
  752. SendScript();
  753. }
  754.  
  755. void CQuestManager::GotoInputState(QuestState & qs)
  756. {
  757. qs.suspend_state = SUSPEND_STATE_INPUT;
  758. AddScript("[INPUT]");
  759. SendScript();
  760.  
  761. // 시간 제한을 검
  762. //event_create(input_timeout_event, dwEI, PASSES_PER_SEC(iTimeout));
  763. }
  764.  
  765. void CQuestManager::GotoPauseState(QuestState & qs)
  766. {
  767. qs.suspend_state = SUSPEND_STATE_PAUSE;
  768. AddScript("[NEXT]");
  769. SendScript();
  770. }
  771.  
  772. void CQuestManager::GotoEndState(QuestState & qs)
  773. {
  774. AddScript("[DONE]");
  775. SendScript();
  776. }
  777.  
  778. //
  779. // * OpenState
  780. //
  781. // The beginning of script
  782. //
  783.  
  784. QuestState CQuestManager::OpenState(const string& quest_name, int state_index)
  785. {
  786. QuestState qs;
  787. qs.args=0;
  788. qs.st = state_index;
  789. qs.co = lua_newthread(L);
  790. qs.ico = lua_ref(L, 1/*qs.co*/);
  791. return qs;
  792. }
  793.  
  794. //
  795. // * RunState
  796. //
  797. // decides script to wait for user input, or finish
  798. //
  799. bool CQuestManager::RunState(QuestState & qs)
  800. {
  801. ClearError();
  802.  
  803. m_CurrentRunningState = &qs;
  804. int ret = lua_resume(qs.co, qs.args);
  805.  
  806. if (ret == 0)
  807. {
  808. if (lua_gettop(qs.co) == 0)
  809. {
  810. // end of quest
  811. GotoEndState(qs);
  812. return false;
  813. }
  814.  
  815. if (!strcmp(lua_tostring(qs.co, 1), "select"))
  816. {
  817. GotoSelectState(qs);
  818. return true;
  819. }
  820.  
  821. if (!strcmp(lua_tostring(qs.co, 1), "wait"))
  822. {
  823. GotoPauseState(qs);
  824. return true;
  825. }
  826.  
  827. if (!strcmp(lua_tostring(qs.co, 1), "input"))
  828. {
  829. GotoInputState(qs);
  830. return true;
  831. }
  832.  
  833. if (!strcmp(lua_tostring(qs.co, 1), "confirm"))
  834. {
  835. GotoConfirmState(qs);
  836. return true;
  837. }
  838.  
  839. if (!strcmp(lua_tostring(qs.co, 1), "select_item"))
  840. {
  841. GotoSelectItemState(qs);
  842. return true;
  843. }
  844. }
  845. else
  846. {
  847. sys_err("LUA_ERROR: %s", lua_tostring(qs.co, 1));
  848. }
  849.  
  850. WriteRunningStateToSyserr();
  851. SetError();
  852.  
  853. GotoEndState(qs);
  854. return false;
  855. }
  856.  
  857. //
  858. // * CloseState
  859. //
  860. // makes script end
  861. //
  862. void CQuestManager::CloseState(QuestState& qs)
  863. {
  864. if (qs.co)
  865. {
  866. //cerr << "ICO "<<qs.ico <<endl;
  867. lua_unref(L, qs.ico);
  868. qs.co = 0;
  869. }
  870. }
  871. }
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement