Advertisement
Guest User

oxevent.cpp

a guest
Jan 24th, 2021
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 13.29 KB | None | 0 0
  1. #include "stdafx.h"
  2. #include "constants.h"
  3. #include "config.h"
  4. #include "questmanager.h"
  5. #include "start_position.h"
  6. #include "packet.h"
  7. #include "buffer_manager.h"
  8. #include "log.h"
  9. #include "char.h"
  10. #include "char_manager.h"
  11. #include "OXEvent.h"
  12. #include "desc.h"
  13. #include "MultiLanguage.h"
  14. #include "desc_manager.h"
  15. bool COXEventManager::Initialize()
  16. {
  17. m_timedEvent = NULL;
  18. m_map_char.clear();
  19. m_map_attender.clear();
  20. m_vec_quiz.clear();
  21.  
  22. SetStatus(OXEVENT_FINISH);
  23.  
  24. return true;
  25. }
  26.  
  27. void COXEventManager::Destroy()
  28. {
  29. CloseEvent();
  30.  
  31. m_map_char.clear();
  32. m_map_attender.clear();
  33. m_vec_quiz.clear();
  34.  
  35. SetStatus(OXEVENT_FINISH);
  36. }
  37.  
  38. OXEventStatus COXEventManager::GetStatus()
  39. {
  40. BYTE ret = quest::CQuestManager::instance().GetEventFlag("oxevent_status");
  41.  
  42. switch (ret)
  43. {
  44. case 0 :
  45. return OXEVENT_FINISH;
  46.  
  47. case 1 :
  48. return OXEVENT_OPEN;
  49.  
  50. case 2 :
  51. return OXEVENT_CLOSE;
  52.  
  53. case 3 :
  54. return OXEVENT_QUIZ;
  55.  
  56. default :
  57. return OXEVENT_ERR;
  58. }
  59.  
  60. return OXEVENT_ERR;
  61. }
  62.  
  63. bool COXEventManager::IsLoadedQuizFiles()
  64. {
  65. if (m_vec_quiz.size() != LANGUAGE_MAX_NUM)
  66. {
  67. sys_err("OXEVENT: Table questions size error, please check all files.");
  68. return false;
  69. }
  70.  
  71. for (size_t i = 0; i < m_vec_quiz.size(); ++i)
  72. {
  73. if (!m_vec_quiz[i].size())
  74. {
  75. sys_err("OXEVENT: Not exist questions, please check all files.");
  76. return false;
  77. }
  78. }
  79.  
  80. return true;
  81. }
  82.  
  83. void COXEventManager::SetStatus(OXEventStatus status)
  84. {
  85. BYTE val = 0;
  86.  
  87. switch (status)
  88. {
  89. case OXEVENT_OPEN :
  90. val = 1;
  91. break;
  92.  
  93. case OXEVENT_CLOSE :
  94. val = 2;
  95. break;
  96.  
  97. case OXEVENT_QUIZ :
  98. val = 3;
  99. break;
  100.  
  101. case OXEVENT_FINISH :
  102. case OXEVENT_ERR :
  103. default :
  104. val = 0;
  105. break;
  106. }
  107. quest::CQuestManager::instance().RequestSetEventFlag("oxevent_status", val);
  108. }
  109.  
  110. bool COXEventManager::Enter(LPCHARACTER pkChar)
  111. {
  112. #ifdef ENABLE_OX_INVISIBILITY_SYSTEM
  113. if (GetStatus() == OXEVENT_FINISH && !pkChar->IsGM())
  114. {
  115. sys_log(0, "OXEVENT : map finished. but char enter. %s", pkChar->GetName());
  116. return false;
  117. }
  118. #else
  119. if (GetStatus() == OXEVENT_FINISH)
  120. {
  121. sys_log(0, "OXEVENT : map finished. but char enter. %s", pkChar->GetName());
  122. return false;
  123. }
  124. #endif
  125.  
  126. PIXEL_POSITION pos = pkChar->GetXYZ();
  127.  
  128. if (pos.x == 896500 && pos.y == 24600)
  129. {
  130. return EnterAttender(pkChar);
  131. }
  132. #ifdef ENABLE_OX_INVISIBILITY_SYSTEM
  133. else if (pos.x == 896300 && pos.y == 28900 || pkChar->IsGM())
  134. {
  135. return EnterAudience(pkChar);
  136. }
  137. #else
  138. else if (pos.x == 896300 && pos.y == 28900)
  139. {
  140. return EnterAudience(pkChar);
  141. }
  142. #endif
  143. else
  144. {
  145. sys_log(0, "OXEVENT : wrong pos enter %d %d", pos.x, pos.y);
  146. return false;
  147. }
  148.  
  149. return false;
  150. }
  151.  
  152. bool COXEventManager::EnterAttender(LPCHARACTER pkChar)
  153. {
  154. if (!CheckIpAddress(pkChar))
  155. return false; // // Will send you to your empire, if you are not GM
  156.  
  157. DWORD pid = pkChar->GetPlayerID();
  158. m_map_char.insert(std::make_pair(pid, pid));
  159. m_map_attender.insert(std::make_pair(pid, pid));
  160.  
  161. return true;
  162. }
  163.  
  164. bool COXEventManager::EnterAudience(LPCHARACTER pkChar)
  165. {
  166. DWORD pid = pkChar->GetPlayerID();
  167.  
  168. m_map_char.insert(std::make_pair(pid, pid));
  169.  
  170. return true;
  171. }
  172.  
  173. bool COXEventManager::AddQuiz(const char* pszLanguage, const char* pszQuestion, bool answer)
  174. {
  175. unsigned char level = CLanguageManager::instance().GetKeyInstanceVectorByLang(pszLanguage);
  176.  
  177. if (m_vec_quiz.size() < (size_t) level + 1)
  178. m_vec_quiz.resize(level + 1);
  179.  
  180. struct tag_Quiz tmpQuiz;
  181. strlcpy(tmpQuiz.Quiz, pszQuestion, sizeof(tmpQuiz.Quiz));
  182. tmpQuiz.answer = answer;
  183.  
  184. m_vec_quiz[level].push_back(tmpQuiz);
  185. return true;
  186. }
  187.  
  188. bool COXEventManager::ShowQuizList(LPCHARACTER pkChar)
  189. {
  190. int c = 0;
  191.  
  192. for (size_t i = 0; i < m_vec_quiz.size(); ++i)
  193. {
  194. for (size_t j = 0; j < m_vec_quiz[i].size(); ++j, ++c)
  195. {
  196. //pkChar->ChatPacket(CHAT_TYPE_INFO, "%d %s %s", m_vec_quiz[i][j].level, m_vec_quiz[i][j].Quiz, m_vec_quiz[i][j].answer ? LC_TEXT_CONVERT_LANGUAGE(//pkChar->GetLanguage(), "참") : LC_TEXT_CONVERT_LANGUAGE(//pkChar->GetLanguage(), "거짓"));
  197. }
  198. }
  199.  
  200. pkChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT_CONVERT_LANGUAGE(pkChar->GetLanguage(), "총 퀴즈 수: %d"), c);
  201. return true;
  202. }
  203.  
  204. void COXEventManager::ClearQuiz()
  205. {
  206. for (unsigned int i = 0; i < m_vec_quiz.size(); ++i)
  207. {
  208. m_vec_quiz[i].clear();
  209. }
  210.  
  211. m_vec_quiz.clear();
  212. }
  213.  
  214. EVENTINFO(OXEventInfoData)
  215. {
  216. bool answer;
  217.  
  218. OXEventInfoData()
  219. : answer( false )
  220. {
  221. }
  222. };
  223.  
  224. EVENTFUNC(oxevent_timer)
  225. {
  226. static BYTE flag = 0;
  227. OXEventInfoData* info = dynamic_cast<OXEventInfoData*>(event->info);
  228.  
  229. if ( info == NULL )
  230. {
  231. sys_err( "oxevent_timer> <Factor> Null pointer" );
  232. return 0;
  233. }
  234.  
  235. switch (flag)
  236. {
  237. case 0:
  238. SendNoticeMap(LC_TEXT("10초뒤 판정하겠습니다."), OXEVENT_MAP_INDEX, true);
  239. flag++;
  240. return PASSES_PER_SEC(10);
  241.  
  242. case 1:
  243. SendNoticeMap(LC_TEXT("정답은"), OXEVENT_MAP_INDEX, true);
  244.  
  245. if (info->answer == true)
  246. {
  247. COXEventManager::instance().CheckAnswer(true);
  248. SendNoticeMap(LC_TEXT("O 입니다"), OXEVENT_MAP_INDEX, true);
  249. }
  250. else
  251. {
  252. COXEventManager::instance().CheckAnswer(false);
  253. SendNoticeMap(LC_TEXT("X 입니다"), OXEVENT_MAP_INDEX, true);
  254. }
  255.  
  256. if (LC_IsJapan())
  257. {
  258. SendNoticeMap("Š?????X‚?O‚ ˆ?‚????B", OXEVENT_MAP_INDEX, true);
  259. }
  260. else
  261. {
  262. SendNoticeMap(LC_TEXT("5초 뒤 틀리신 분들을 바깥으로 이동 시키겠습니다."), OXEVENT_MAP_INDEX, true);
  263. }
  264.  
  265. flag++;
  266. return PASSES_PER_SEC(5);
  267.  
  268. case 2:
  269. COXEventManager::instance().WarpToAudience();
  270. COXEventManager::instance().SetStatus(OXEVENT_CLOSE);
  271. SendNoticeMap(LC_TEXT("다음 문제 준비해주세요."), OXEVENT_MAP_INDEX, true);
  272. flag = 0;
  273. break;
  274. }
  275. return 0;
  276. }
  277.  
  278. bool COXEventManager::Quiz(int timelimit)
  279. {
  280. unsigned char level = 1;
  281.  
  282. if (m_vec_quiz.size() == 0)
  283. return false;
  284.  
  285. if (level > m_vec_quiz.size())
  286. level = m_vec_quiz.size() - 1;
  287.  
  288. if (m_vec_quiz[level].size() <= 0)
  289. return false;
  290.  
  291. if (timelimit < 0)
  292. timelimit = 30;
  293.  
  294. int idx = number(0, m_vec_quiz[level].size() - 1);
  295.  
  296. SendNoticeMap(("문제 입니다."), OXEVENT_MAP_INDEX, true);
  297. CLanguageManager::instance().SendLanguageNoticeMap(m_vec_quiz, idx);
  298. SendNoticeMap(("맞으면 O, 틀리면 X로 이동해주세요"), OXEVENT_MAP_INDEX, true);
  299.  
  300. if (m_timedEvent)
  301. event_cancel(&m_timedEvent);
  302.  
  303. OXEventInfoData* answer = AllocEventInfo<OXEventInfoData>();
  304. answer->answer = m_vec_quiz[level][idx].answer;
  305.  
  306. timelimit -= 15;
  307. m_timedEvent = event_create(oxevent_timer, answer, PASSES_PER_SEC(timelimit));
  308. SetStatus(OXEVENT_QUIZ);
  309. #ifdef ENABLE_OX_INVISIBILITY_SYSTEM
  310. itertype(m_map_attender) iter = m_map_attender.begin();
  311.  
  312. LPCHARACTER pkChar = NULL;
  313. for (; iter != m_map_attender.end(); ++iter) {
  314. pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
  315.  
  316. if (pkChar){
  317. if (!pkChar->IsGM()){
  318. if (pkChar->IsAffectFlag(AFF_INVISIBILITY)){
  319. sys_err("%s already invisible", pkChar->GetName());
  320. }
  321. else {
  322. pkChar->AddAffect(AFFECT_INVISIBILITY, POINT_NONE, 0, AFF_INVISIBILITY, 30, 0, true);
  323. pkChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT("You passed the Invisible mode! You will continue this way until you answer the question."));
  324. }
  325. }
  326. }
  327. }
  328.  
  329. itertype(m_map_char) iter2 = m_map_char.begin();
  330.  
  331. LPCHARACTER pkChar2 = NULL;
  332. for (; iter2 != m_map_char.end(); ++iter2) {
  333. pkChar2 = CHARACTER_MANAGER::instance().FindByPID(iter2->second);
  334.  
  335. if (pkChar2){
  336. if (pkChar2->IsGM()){
  337. pkChar2->ChatPacket(CHAT_TYPE_COMMAND, "MakeVisibleOX");
  338. }
  339. }
  340. }
  341. #endif
  342.  
  343. for (int i = 0; i < m_vec_quiz.size(); i++)
  344. m_vec_quiz[i].erase(m_vec_quiz[i].begin() + idx);
  345. return true;
  346. }
  347.  
  348. bool COXEventManager::CheckAnswer(bool answer)
  349. {
  350. if (m_map_attender.size() <= 0) return true;
  351.  
  352. itertype(m_map_attender) iter = m_map_attender.begin();
  353. itertype(m_map_attender) iter_tmp;
  354.  
  355. m_map_miss.clear();
  356.  
  357. int rect[4];
  358. if (answer != true)
  359. {
  360. rect[0] = 892600;
  361. rect[1] = 22900;
  362. rect[2] = 896300;
  363. rect[3] = 26400;
  364. }
  365. else
  366. {
  367. rect[0] = 896600;
  368. rect[1] = 22900;
  369. rect[2] = 900300;
  370. rect[3] = 26400;
  371. }
  372.  
  373. LPCHARACTER pkChar = NULL;
  374. PIXEL_POSITION pos;
  375. for (; iter != m_map_attender.end();)
  376. {
  377. pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
  378. if (pkChar != NULL)
  379. {
  380. #ifdef ENABLE_OX_INVISIBILITY_SYSTEM
  381. if (!pkChar->IsGM()){
  382. if (pkChar->IsAffectFlag(AFF_INVISIBILITY)){
  383. pkChar->RemoveAffect(AFFECT_INVISIBILITY);
  384. }
  385. else{
  386. sys_err("%s isn't invisible", pkChar->GetName());
  387. }
  388. }
  389. else {
  390. pkChar->ChatPacket(CHAT_TYPE_COMMAND, "RemoveTitleOX");
  391. }
  392. #endif
  393. pos = pkChar->GetXYZ();
  394.  
  395. if (pos.x < rect[0] || pos.x > rect[2] || pos.y < rect[1] || pos.y > rect[3])
  396. {
  397. pkChar->EffectPacket(SE_FAIL);
  398. iter_tmp = iter;
  399. iter++;
  400. m_map_attender.erase(iter_tmp);
  401. m_map_miss.insert(std::make_pair(pkChar->GetPlayerID(), pkChar->GetPlayerID()));
  402. }
  403. else
  404. {
  405. pkChar->ChatPacket(CHAT_TYPE_INFO, LC_TEXT_CONVERT_LANGUAGE(pkChar->GetLanguage(), "정답입니다!"));
  406. // pkChar->CreateFly(number(FLY_FIREWORK1, FLY_FIREWORK6), pkChar);
  407. char chatbuf[256];
  408. int len = snprintf(chatbuf, sizeof(chatbuf),
  409. "%s %u %u", number(0, 1) == 1 ? "cheer1" : "cheer2", (DWORD)pkChar->GetVID(), 0);
  410.  
  411. // 리턴값이 sizeof(chatbuf) 이상일 경우 truncate되었다는 뜻..
  412. if (len < 0 || len >= (int) sizeof(chatbuf))
  413. len = sizeof(chatbuf) - 1;
  414.  
  415. // \0 문자 포함
  416. ++len;
  417.  
  418. TPacketGCChat pack_chat;
  419. pack_chat.header = HEADER_GC_CHAT;
  420. pack_chat.size = sizeof(TPacketGCChat) + len;
  421. pack_chat.type = CHAT_TYPE_COMMAND;
  422. pack_chat.id = 0;
  423.  
  424. TEMP_BUFFER buf;
  425. buf.write(&pack_chat, sizeof(TPacketGCChat));
  426. buf.write(chatbuf, len);
  427.  
  428. pkChar->PacketAround(buf.read_peek(), buf.size());
  429. pkChar->EffectPacket(SE_SUCCESS);
  430.  
  431. ++iter;
  432. }
  433. }
  434. else
  435. {
  436. itertype(m_map_char) err = m_map_char.find(iter->first);
  437. if (err != m_map_char.end()) m_map_char.erase(err);
  438.  
  439. itertype(m_map_miss) err2 = m_map_miss.find(iter->first);
  440. if (err2 != m_map_miss.end()) m_map_miss.erase(err2);
  441.  
  442. iter_tmp = iter;
  443. ++iter;
  444. m_map_attender.erase(iter_tmp);
  445. }
  446. }
  447. return true;
  448. }
  449.  
  450. void COXEventManager::WarpToAudience()
  451. {
  452. if (m_map_miss.size() <= 0) return;
  453.  
  454. itertype(m_map_miss) iter = m_map_miss.begin();
  455. LPCHARACTER pkChar = NULL;
  456.  
  457. for (; iter != m_map_miss.end(); ++iter)
  458. {
  459. pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
  460.  
  461. if (pkChar != NULL)
  462. {
  463. switch ( number(0, 3))
  464. {
  465. case 0 : pkChar->Show(OXEVENT_MAP_INDEX, 896300, 28900); break;
  466. case 1 : pkChar->Show(OXEVENT_MAP_INDEX, 890900, 28100); break;
  467. case 2 : pkChar->Show(OXEVENT_MAP_INDEX, 896600, 20500); break;
  468. case 3 : pkChar->Show(OXEVENT_MAP_INDEX, 902500, 28100); break;
  469. default : pkChar->Show(OXEVENT_MAP_INDEX, 896300, 28900); break;
  470. }
  471. }
  472. }
  473.  
  474. m_map_miss.clear();
  475. }
  476.  
  477. bool COXEventManager::CloseEvent()
  478. {
  479. if (m_timedEvent != NULL) {
  480. event_cancel(&m_timedEvent);
  481. }
  482.  
  483. itertype(m_map_char) iter = m_map_char.begin();
  484.  
  485. LPCHARACTER pkChar = NULL;
  486. for (; iter != m_map_char.end(); ++iter)
  487. {
  488. pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
  489.  
  490. if (pkChar != NULL)
  491. pkChar->WarpSet(EMPIRE_START_X(pkChar->GetEmpire()), EMPIRE_START_Y(pkChar->GetEmpire()));
  492. }
  493.  
  494. m_map_char.clear();
  495.  
  496. return true;
  497. }
  498.  
  499. bool COXEventManager::LogWinner()
  500. {
  501. itertype(m_map_attender) iter = m_map_attender.begin();
  502.  
  503. for (; iter != m_map_attender.end(); ++iter)
  504. {
  505. LPCHARACTER pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
  506.  
  507. if (pkChar)
  508. LogManager::instance().CharLog(pkChar, 0, "OXEVENT", "LastManStanding");
  509. }
  510.  
  511. return true;
  512. }
  513.  
  514. bool COXEventManager::CheckIpAddress(LPCHARACTER ch) const
  515. {
  516. BYTE bIPCount = 0;
  517. for (MapEventChar::const_iterator it = m_map_attender.begin(); it != m_map_attender.end(); ++it)
  518. {
  519. LPCHARACTER tch = CHARACTER_MANAGER::Instance().FindByPID(it->second);
  520. if (tch && tch->GetDesc() && !strcmp(ch->GetDesc()->GetHostName(), tch->GetDesc()->GetHostName()))
  521. bIPCount++;
  522. }
  523.  
  524. const BYTE MaxPlayer = 2;
  525. return (bIPCount < MaxPlayer);
  526. }
  527.  
  528.  
  529. void COXEventManager::RemoveFromAttenderList(DWORD dwPID)
  530. {
  531. m_map_attender.erase(dwPID);
  532. }
  533.  
  534. bool COXEventManager::GiveItemToAttender(DWORD dwItemVnum, BYTE count)
  535. {
  536. itertype(m_map_attender) iter = m_map_attender.begin();
  537.  
  538. for (; iter != m_map_attender.end(); ++iter)
  539. {
  540. LPCHARACTER pkChar = CHARACTER_MANAGER::instance().FindByPID(iter->second);
  541.  
  542. if (pkChar)
  543. {
  544. pkChar->AutoGiveItem(dwItemVnum, count);
  545. LogManager::instance().ItemLog(pkChar->GetPlayerID(), 0, count, dwItemVnum, "OXEVENT_REWARD", "", pkChar->GetDesc()->GetHostName(), dwItemVnum);
  546. }
  547. }
  548.  
  549. return true;
  550. }
  551.  
  552.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement