Guest User

Untitled

a guest
Dec 30th, 2023
154
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.54 KB | None | 0 0
  1. #include "stdafx.h"
  2. #ifdef __ENABLE_BIOLOG_SYSTEM__
  3. #include "BiologSystemManager.hpp"
  4. #include "questmanager.h"
  5. #include "char.h"
  6. #include "packet.h"
  7. #include "buffer_manager.h"
  8. #include "desc_client.h"
  9. #include "char_manager.h"
  10. #include "p2p.h"
  11. #include "item_manager.h"
  12. #include "item.h"
  13. #include "utils.h"
  14.  
  15. #include "mob_manager.h"
  16.  
  17. #include "EventFunctionHandler.hpp"
  18.  
  19. #define __DEBUG_PRINT
  20. #ifdef __DEBUG_PRINT
  21. #include <iostream>
  22.  
  23. using std::cerr;
  24. using std::endl;
  25. #endif
  26.  
  27. /*******************************************************************\
  28. |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  29. |||| CBiologSystem - CLASS
  30. |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  31. \*******************************************************************/
  32.  
  33. /*******************************************************************\
  34. | [PUBLIC] (De-)Initialize Functions
  35. \*******************************************************************/
  36.  
  37. CBiologSystem::CBiologSystem(LPCHARACTER m_ch)
  38. : m_pkChar(m_ch)
  39. {
  40. s_current_biolog_reminder = "BIOLOG_MANAGER_ALERT";
  41. }
  42.  
  43. CBiologSystem::~CBiologSystem()
  44. {
  45. }
  46.  
  47. /*******************************************************************\
  48. | [PUBLIC] Update Functions
  49. \*******************************************************************/
  50.  
  51. void CBiologSystem::ResetMission()
  52. {
  53. m_pkChar->SetBiologCollectedItems(0);
  54. m_pkChar->SetBiologCooldown(0);
  55. ActiveAlert(false);
  56. }
  57.  
  58. /*******************************************************************\
  59. | [PUBLIC] General Functions
  60. \*******************************************************************/
  61.  
  62. void CBiologSystem::SendBiologInformation(bool bUpdate)
  63. {
  64. if (!m_pkChar)
  65. return;
  66.  
  67. auto bMission = m_pkChar->GetBiologMissions();
  68. auto iCount = m_pkChar->GetBiologCollectedItems();
  69. auto tWait = m_pkChar->GetBiologCooldown();
  70. auto tReminder = m_pkChar->GetBiologCooldownReminder();
  71.  
  72. TBiologMissionsProto* pMission = CBiologSystemManager::instance().GetMission(bMission);
  73. if (!pMission)
  74. {
  75. #ifdef __DEBUG_PRINT
  76. sys_err("SendBiologInformation -> cannot get mission %u by %s", bMission, m_pkChar->GetName());
  77. #endif
  78.  
  79. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "You done every mission!");
  80. return;
  81. }
  82.  
  83. TBiologRewardsProto* pReward = CBiologSystemManager::instance().GetReward(bMission);
  84. if (!pReward)
  85. {
  86. #ifdef __DEBUG_PRINT
  87. sys_err("SendBiologInformation -> cannot get reward %u by %s", bMission, m_pkChar->GetName());
  88. #endif
  89. return;
  90. }
  91.  
  92. TPacketGCBiologManagerInfo kInfo;
  93. memset(&kInfo, 0, sizeof(kInfo));
  94.  
  95. //copy data
  96. kInfo.bUpdate = bUpdate;
  97. kInfo.bRequiredLevel = pMission->bRequiredLevel;
  98. kInfo.iRequiredItem = pMission->iRequiredItem;
  99. kInfo.wGivenItems = iCount;
  100. kInfo.wRequiredItemCount = pMission->wRequiredItemCount;
  101. kInfo.iGlobalCooldown = pMission->iCooldown;
  102. kInfo.iCooldown = (tWait - get_global_time());
  103. kInfo.iCooldownReminder = tReminder;
  104. kInfo.bChance = pMission->bChance;
  105. kInfo.bApplyType = pReward->bApplyType;
  106. kInfo.lApplyValue = pReward->lApplyValue;
  107.  
  108. SendClientPacket(m_pkChar->GetDesc(), GC_BIOLOG_OPEN, &kInfo, sizeof(kInfo));
  109. }
  110.  
  111. void CBiologSystem::SendBiologItem(bool bAdditionalChance, bool bAdditionalTime)
  112. {
  113. if (!m_pkChar)
  114. return;
  115.  
  116. auto bMission = m_pkChar->GetBiologMissions();
  117. auto tWait = m_pkChar->GetBiologCooldown();
  118. auto iCount = m_pkChar->GetBiologCollectedItems();
  119.  
  120. // Getting actual biolog mission
  121. TBiologMissionsProto* pMission = CBiologSystemManager::instance().GetMission(bMission);
  122. if (!pMission || bMission == CBiologSystemManager::instance().m_mapMission_Proto.size())
  123. {
  124. //We have to inform players they've done every mission!
  125. #ifdef __DEBUG_PRINT
  126. cerr << "SendBiologItem -> cannot get mission of level " << bMission << " by " << m_pkChar->GetName() << endl;
  127. #endif
  128. return;
  129. }
  130.  
  131. // Checking required level
  132. if (m_pkChar->GetLevel() < pMission->bRequiredLevel)
  133. {
  134. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "You doesn't have enought level");
  135. return;
  136. }
  137.  
  138. // Counting required item
  139. if (m_pkChar->CountSpecifyItem(pMission->iRequiredItem) < 1)
  140. {
  141. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "You doesn't have required item!");
  142. return;
  143. }
  144.  
  145. // Checking time
  146. if (get_global_time() < tWait && bAdditionalTime)
  147. {
  148. if (m_pkChar->CountSpecifyItem(BIOLOG_TIME_ITEM) < 1)
  149. {
  150. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "You doesn't have required item for remove cooldown!");
  151. return;
  152. }
  153. else
  154. m_pkChar->RemoveSpecifyItem(BIOLOG_TIME_ITEM, 1);
  155. #ifdef __DEBUG_PRINT
  156. cerr << "SendBiologItem: Doesn't check time and remove item!" << endl;
  157. #endif
  158. }
  159.  
  160. if (get_global_time() < tWait && !bAdditionalTime)
  161. {
  162. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "You have to wait, you can try next time at: %s", GetFullDateFromTime(tWait).c_str());
  163. return;
  164. }
  165.  
  166. // Define variables
  167. BYTE chance = pMission->bChance;
  168.  
  169. if (bAdditionalChance)
  170. {
  171. LPITEM biologChanceItem = m_pkChar->FindSpecifyItem(BIOLOG_CHANCE_ITEM);
  172. if (biologChanceItem)
  173. {
  174. const int BIOLOG_CHANCE = biologChanceItem->GetValue(0);
  175.  
  176. if (BIOLOG_CHANCE > 0)
  177. {
  178. if (biologChanceItem->GetCount() > 1)
  179. {
  180. biologChanceItem->SetCount(biologChanceItem->GetCount() - 1);
  181. chance += BIOLOG_CHANCE;
  182.  
  183. #ifdef __DEBUG_PRINT
  184. cerr << "SendBiologItem: Intercase chance SUCCEED! percent before: " << chance - BIOLOG_CHANCE << " after " << chance << endl;
  185. #endif
  186. }
  187. else
  188. {
  189. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "You doesn't have required item for intercase chance!");
  190. return;
  191. }
  192. }
  193. else {
  194. #ifdef __DEBUG_PRINT
  195. cerr << "SendBiologItem: Intercase chance FAILED! item: " << BIOLOG_CHANCE_ITEM << " value0 == 0" << endl;
  196. #endif
  197. return;
  198. }
  199. }
  200. }
  201.  
  202. // Checking count
  203. if (iCount < pMission->wRequiredItemCount) // it means you haven't give all items
  204. {
  205. m_pkChar->RemoveSpecifyItem(pMission->iRequiredItem, 1);
  206.  
  207. if (chance >= number(1, 100))
  208. {
  209. // Update count
  210. m_pkChar->SetBiologCollectedItems(iCount + 1);
  211. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "This item is good!");
  212. } else
  213. m_pkChar->ChatPacket(CHAT_TYPE_INFO, "This item is not good, try next time later.");
  214.  
  215. // Update cooldown
  216. m_pkChar->SetBiologCooldown(get_global_time() + pMission->iCooldown);
  217.  
  218. // Active Alert
  219. if (m_pkChar->GetBiologCooldownReminder())
  220. ActiveAlert(true);
  221.  
  222. bool bSendInformation = true;
  223. // Compare current count with required count
  224. if (m_pkChar->GetBiologCollectedItems() == pMission->wRequiredItemCount)
  225. {
  226. #ifdef __DEBUG_PRINT
  227. cerr << "You give me all required items, right now you have to get reward!" << endl;
  228. #endif
  229.  
  230. // We have to give reward
  231. GiveRewardByMission(bMission);
  232.  
  233. // We have to reset mission
  234. ResetMission();
  235.  
  236. BYTE nextMission = bMission + 1;
  237. m_pkChar->SetBiologMissions(nextMission);
  238.  
  239. TBiologMissionsProto* pNextMission = CBiologSystemManager::instance().GetMission(nextMission);
  240. if (!pNextMission)
  241. {
  242. #ifdef __DEBUG_PRINT
  243. cerr << "You done every mission from biolog." << endl;
  244. #endif
  245. SendClientPacket(m_pkChar->GetDesc(), GC_BIOLOG_CLOSE, NULL, 0);
  246. bSendInformation = false;
  247. }
  248. }
  249.  
  250. // Update client!
  251. if (bSendInformation)
  252. SendBiologInformation(true);
  253.  
  254. #ifdef __DEBUG_PRINT
  255. cerr << "SendBiologItem: Level actual: " << m_pkChar->GetBiologMissions() << endl;
  256. cerr << "SendBiologItem: Counts: *" << m_pkChar->GetBiologCollectedItems() << "* : *" << pMission->wRequiredItemCount << "*" << endl;
  257. cerr << "SendBiologItem: Current time: " << GetFullDateFromTime(get_global_time()).c_str() << endl;
  258. cerr << "SendBiologItem: Next possible try: " << GetFullDateFromTime(get_global_time() + pMission->iCooldown).c_str() << endl;
  259. #endif
  260. }
  261. }
  262.  
  263. void CBiologSystem::GiveRewardByMission(BYTE bMission)
  264. {
  265. if (!m_pkChar)
  266. return;
  267.  
  268. TBiologRewardsProto* pReward = CBiologSystemManager::instance().GetReward(bMission);
  269. if (!pReward)
  270. {
  271. sys_err("GiveRewardByMission -> cannot get reward %u by %s", bMission, m_pkChar->GetName());
  272. return;
  273. }
  274.  
  275. #ifdef __DEBUG_PRINT
  276. cerr << "GiveRewardByMission -> Reward for mission: " << bMission << " by " << m_pkChar->GetName()
  277. << " type: " << pReward->bApplyType << " value: " << pReward->lApplyValue << endl;
  278. #endif
  279.  
  280. m_pkChar->AddAffect(AFFECTS[bMission], aApplyInfo[pReward->bApplyType].bPointType, pReward->lApplyValue, 0, BIOLOG_AFF_TIME, 0, true);
  281. }
  282.  
  283. bool CBiologSystem::GetBiologItemByMobVnum(LPCHARACTER pkKiller, WORD MonsterVnum, DWORD& ItemVnum, BYTE& bChance)
  284. {
  285. if (!pkKiller || !MonsterVnum)
  286. return false;
  287.  
  288. const CMob* pkMob = CMobManager::instance().Get(MonsterVnum);
  289. if (!pkMob)
  290. return false;
  291.  
  292. auto bMission = pkKiller->GetBiologMissions();
  293.  
  294. #ifdef __DEBUG_PRINT
  295. cerr << "GetBiologItemByMobVnum: #1 " << bMission << " by " << pkKiller->GetName() << endl;
  296. #endif
  297.  
  298. TBiologMissionsProto* pMission = CBiologSystemManager::instance().GetMission(bMission);
  299. if (!pMission)
  300. return false;
  301.  
  302. #ifdef __DEBUG_PRINT
  303. cerr << "GetBiologItemByMobVnum: #2 " << bMission << " by " << pkKiller->GetName() << endl;
  304. #endif
  305.  
  306. if (pkKiller->GetLevel() < pMission->bRequiredLevel)
  307. return false;
  308.  
  309. #ifdef __DEBUG_PRINT
  310. cerr << "GetBiologItemByMobVnum: #3 " << bMission << " by " << pkKiller->GetName() << endl;
  311. #endif
  312.  
  313. std::vector<TBiologMonstersProto*> monsters;
  314. if(!CBiologSystemManager::instance().GetMonsters(bMission, monsters))
  315. return false;
  316.  
  317. auto monster = std::find_if(monsters.begin(), monsters.end(), [MonsterVnum](TBiologMonstersProto* m) {
  318. return m->dwMonsterVnum == MonsterVnum;
  319. });
  320. if (monster == monsters.end())
  321. return false;
  322.  
  323. ItemVnum = pMission->iRequiredItem;
  324. bChance = static_cast<TBiologMonstersProto*>(*monster)->bChance;
  325.  
  326. return true;
  327. }
  328.  
  329. /*******************************************************************\
  330. | [PUBLIC] Alert Functions
  331. \*******************************************************************/
  332.  
  333. void CBiologSystem::ActiveAlert(bool bReminder)
  334. {
  335. if (bReminder)
  336. {
  337. m_pkChar->SetBiologCooldownReminder(1);
  338.  
  339. if (m_pkChar->GetBiologCooldown() < get_global_time())
  340. return;
  341.  
  342. if (!CEventFunctionHandler::Instance().FindEvent(s_current_biolog_reminder))
  343. {
  344. #ifdef __DEBUG_PRINT
  345. cerr << "ActiveAlert -> bCheck: " << m_pkChar->GetBiologCooldown() - get_global_time() << " by " << m_pkChar->GetName() << endl;
  346. #endif
  347.  
  348. CEventFunctionHandler::instance().AddEvent([this](SArgumentSupportImpl*)
  349. {
  350. BroadcastAlert();
  351. },
  352. (s_current_biolog_reminder), m_pkChar->GetBiologCooldown() - get_global_time());
  353.  
  354. #ifdef __DEBUG_PRINT
  355. cerr << "ActiveAlert -> when: " << m_pkChar->GetBiologCooldown() - get_global_time() << " by " << m_pkChar->GetName() << endl;
  356. #endif
  357. } else
  358. CEventFunctionHandler::instance().DelayEvent((s_current_biolog_reminder), m_pkChar->GetBiologCooldown() - get_global_time());
  359.  
  360. return;
  361. }
  362.  
  363. m_pkChar->SetBiologCooldownReminder(0);
  364. if (CEventFunctionHandler::Instance().FindEvent(s_current_biolog_reminder))
  365. {
  366. CEventFunctionHandler::Instance().RemoveEvent((s_current_biolog_reminder));
  367. }
  368. }
  369.  
  370. void CBiologSystem::BroadcastAlert()
  371. {
  372. SendClientPacket(m_pkChar->GetDesc(), GC_BIOLOG_ALERT, NULL, 0);
  373. }
  374.  
  375. /*******************************************************************\
  376. | [PUBLIC] Incoming Packet Functions
  377. \*******************************************************************/
  378.  
  379. int CBiologSystem::RecvClientPacket(BYTE bSubHeader, const char* c_pData, size_t uiBytes)
  380. {
  381. switch (bSubHeader)
  382. {
  383. case CG_BIOLOG_OPEN:
  384. {
  385. SendBiologInformation();
  386. return 0;
  387. }
  388. break;
  389.  
  390. case CG_BIOLOG_SEND:
  391. {
  392. if (uiBytes < sizeof(bool) + sizeof(bool))
  393. return -1;
  394.  
  395. bool bAdditionalChance = *(bool*)c_pData;
  396. c_pData += sizeof(bool);
  397. uiBytes -= sizeof(bool);
  398.  
  399. bool bAdditionalTime = *(bool*)c_pData;
  400. c_pData += sizeof(bool);
  401. uiBytes -= sizeof(bool);
  402.  
  403. #ifdef __DEBUG_PRINT
  404. cerr << "RecvClientPacket -> bSubHeader: " << bSubHeader << " by " << m_pkChar->GetName() << " bAdditionalChance: " << bAdditionalChance << " bAdditionalTime: " << bAdditionalTime << endl;
  405. #endif
  406. SendBiologItem(bAdditionalChance, bAdditionalTime);
  407. return sizeof(bool) + sizeof(bool);
  408. }
  409. break;
  410.  
  411. case CG_BIOLOG_TIMER:
  412. {
  413. if (uiBytes < sizeof(bool))
  414. return -1;
  415.  
  416. bool bReminder = *(bool*)c_pData;
  417. c_pData += sizeof(bool);
  418. uiBytes -= sizeof(bool);
  419.  
  420. ActiveAlert(bReminder);
  421. return sizeof(bool);
  422. }
  423. break;
  424. }
  425.  
  426. sys_err("invalid subheader %u", bSubHeader);
  427. return -1;
  428. }
  429.  
  430. /*******************************************************************\
  431. | [PUBLIC] Outgoing Packet Functions
  432. \*******************************************************************/
  433.  
  434. void CBiologSystem::SendClientPacket(LPDESC pkDesc, BYTE bSubHeader, const void* c_pvData, size_t iSize)
  435. {
  436. TPacketGCBiologManager packet;
  437. packet.bHeader = HEADER_GC_BIOLOG_MANAGER;
  438. packet.wSize = sizeof(packet) + iSize;
  439. packet.bSubHeader = bSubHeader;
  440.  
  441. TEMP_BUFFER buf;
  442. buf.write(&packet, sizeof(packet));
  443. if (iSize)
  444. buf.write(c_pvData, iSize);
  445.  
  446. pkDesc->Packet(buf.read_peek(), buf.size());
  447. }
  448.  
  449. void CBiologSystem::SendClientPacket(DWORD dwPID, BYTE bSubHeader, const void* c_pvData, size_t iSize)
  450. {
  451. LPCHARACTER pkChr = CHARACTER_MANAGER::instance().FindByPID(dwPID);
  452.  
  453. if (pkChr)
  454. {
  455. SendClientPacket(pkChr->GetDesc(), bSubHeader, c_pvData, iSize);
  456. }
  457. else
  458. {
  459. CCI* pkCCI = P2P_MANAGER::instance().FindByPID(dwPID);
  460. if (pkCCI)
  461. {
  462. pkCCI->pkDesc->SetRelay(pkCCI->szName);
  463. SendClientPacket(pkCCI->pkDesc, bSubHeader, c_pvData, iSize);
  464. }
  465. else
  466. sys_err("cannot send client packet to pid %u subheader %hu [cannot find player]", dwPID, bSubHeader);
  467. }
  468. }
  469.  
  470. /*******************************************************************\
  471. |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  472. |||| CBiologSystemManager - CLASS
  473. |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
  474. \*******************************************************************/
  475.  
  476. /*******************************************************************\
  477. | [PUBLIC] (De-)Initialize Functions
  478. \*******************************************************************/
  479.  
  480. CBiologSystemManager::CBiologSystemManager()
  481. {
  482. }
  483.  
  484. CBiologSystemManager::~CBiologSystemManager()
  485. {
  486. }
  487.  
  488. void CBiologSystemManager::InitializeMissions(TBiologMissionsProto* pData, size_t size)
  489. {
  490. for (size_t i{ 0 }; i < size; ++i, ++pData)
  491. {
  492. thecore_memcpy(&m_mapMission_Proto[pData->bMission], pData, sizeof(TBiologMissionsProto));
  493. }
  494. }
  495.  
  496. TBiologMissionsProto* CBiologSystemManager::GetMission(BYTE bMission)
  497. {
  498. TMissionProtoMap::iterator it = m_mapMission_Proto.find(bMission);
  499. if (it == m_mapMission_Proto.end())
  500. return NULL;
  501.  
  502. return &it->second;
  503. }
  504.  
  505. void CBiologSystemManager::InitializeRewards(TBiologRewardsProto* pData, size_t size)
  506. {
  507. for (size_t i{ 0 }; i < size; ++i, ++pData)
  508. {
  509. thecore_memcpy(&m_mapReward_Proto[pData->bMission], pData, sizeof(TBiologRewardsProto));
  510. }
  511. }
  512.  
  513. TBiologRewardsProto* CBiologSystemManager::GetReward(BYTE bMission)
  514. {
  515. TRewardProtoMap::iterator it = m_mapReward_Proto.find(bMission);
  516. if (it == m_mapReward_Proto.end())
  517. return NULL;
  518.  
  519. return &it->second;
  520. }
  521.  
  522. void CBiologSystemManager::InitializeMonsters(TBiologMonstersProto* pData, size_t size)
  523. {
  524. for (size_t i{ 0 }; i < size; ++i, ++pData)
  525. {
  526. m_mapMonsters_Proto[pData->bMission].push_back(pData);
  527. }
  528. }
  529.  
  530. bool CBiologSystemManager::GetMonsters(BYTE bMission, std::vector<TBiologMonstersProto*>& monsters)
  531. {
  532. auto it = m_mapMonsters_Proto.find(bMission);
  533. if (it == m_mapMonsters_Proto.end())
  534. return false;
  535.  
  536. monsters = it->second;
  537.  
  538. return true;
  539. }
  540.  
  541. #endif
  542.  
Advertisement
Add Comment
Please, Sign In to add comment