HeroicOp.cpp 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. /*
  2. EQ2Emulator: Everquest II Server Emulator
  3. Copyright (C) 2007 EQ2EMulator Development Team (http://www.eq2emulator.net)
  4. This file is part of EQ2Emulator.
  5. EQ2Emulator is free software: you can redistribute it and/or modify
  6. it under the terms of the GNU General Public License as published by
  7. the Free Software Foundation, either version 3 of the License, or
  8. (at your option) any later version.
  9. EQ2Emulator is distributed in the hope that it will be useful,
  10. but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with EQ2Emulator. If not, see <http://www.gnu.org/licenses/>.
  15. */
  16. #include "HeroicOp.h"
  17. #include "../../common/Log.h"
  18. #include "../Rules/Rules.h"
  19. extern MasterHeroicOPList master_ho_list;
  20. extern RuleManager rule_manager;
  21. HeroicOP::HeroicOP() {
  22. m_complete = 0;
  23. m_currentStage = 0;
  24. m_wheel = 0;
  25. m_target = 0;
  26. m_startTime = 0;
  27. m_totalTime = 0;
  28. m_shifted = false;
  29. for (int8 i = 0; i < 6; i++)
  30. countered[i] = 0;
  31. }
  32. HeroicOP::~HeroicOP() {
  33. starters.clear();
  34. }
  35. void HeroicOP::SetWheel(HeroicOPWheel* val) {
  36. if (!m_wheel)
  37. m_wheel = val;
  38. else
  39. LogWrite(SPELL__ERROR, 0, "HO", "Attempted to set the wheel on a heroic op with a wheel already set");
  40. }
  41. void HeroicOP::SetTarget(int32 val) {
  42. m_target = val;
  43. }
  44. bool HeroicOP::UpdateHeroicOP(int16 icon) {
  45. bool ret = false;
  46. vector<HeroicOPStarter*>::iterator itr;
  47. vector<HeroicOPStarter*> temp;
  48. HeroicOPStarter* starter = 0;
  49. LogWrite(SPELL__DEBUG, 0, "HO", "Current Stage %u, wheel exists: %u, looking for icon %u", m_currentStage, m_wheel ? 1 : 0, icon);
  50. // If no wheel is set we are dealing with a starter chain still.
  51. if (!m_wheel) {
  52. // Loop through the starter chains
  53. for (itr = starters.begin(); itr != starters.end(); itr++) {
  54. starter = *itr;
  55. // See if the icon matches the ability at our current stage, if not add it to a list to be removed
  56. if (starter->abilities[m_currentStage] == icon)
  57. ret = true;
  58. else
  59. temp.push_back(*itr);
  60. }
  61. if (ret) {
  62. // ret = true so we had a match, first thing to do is remove those that didn't match
  63. vector<HeroicOPStarter*>::iterator remove_itr;
  64. for (remove_itr = temp.begin(); remove_itr != temp.end(); remove_itr++)
  65. {
  66. std::vector<HeroicOPStarter*>::iterator it = std::find(starters.begin(), starters.end(), *remove_itr);
  67. starters.erase(it);
  68. }
  69. // now advance the current stage
  70. m_currentStage++;
  71. // Temp pointer to hold the completed chain, if any
  72. HeroicOPStarter* complete_starter = 0;
  73. // now loop through those that are left and check the next stage abilities for a 0xFFFF
  74. for (itr = starters.begin(); itr != starters.end(); itr++) {
  75. starter = *itr;
  76. // Found one that is 0xFFFF, means the starter chain is done, get a wheel and reset the stage to 0
  77. if ((starter->abilities[m_currentStage] == 0xFFFF)) {
  78. LogWrite(SPELL__DEBUG, 0, "HO", "Current Stage %u, starter reset (new stage 0)", m_currentStage);
  79. // reset the stage
  80. ResetStage();
  81. // geth the wheel
  82. m_wheel = master_ho_list.GetWheel(starter);
  83. // store the starter chain that is completed
  84. complete_starter = starter;
  85. // set the start time to now
  86. SetStartTime(Timer::GetCurrentTime2());
  87. // set the total time to complete the real to was the admin set in rules (default 10.0f)
  88. SetTotalTime(rule_manager.GetGlobalRule(R_Zone, HOTime)->GetFloat());
  89. // We set a wheel so we are done, kill the loop
  90. break;
  91. }
  92. }
  93. // Check to see if the completed start chain pointer was set
  94. if (complete_starter) {
  95. LogWrite(SPELL__DEBUG, 0, "HO", "Current Stage %u, complete_starter set", m_currentStage);
  96. // clear the starter list
  97. starters.clear();
  98. // add the completed starter back in, we do this in case we need this starter again we can just do starters.at(0), for example shifting the wheel
  99. starters.push_back(complete_starter);
  100. }
  101. }
  102. }
  103. else {
  104. LogWrite(SPELL__DEBUG, 0, "HO", "Current Stage %u, wheel order: %u", m_currentStage, m_wheel->order);
  105. // Wheel was set so we need to check the order it needs to be completed in.
  106. if (m_wheel->order == 0) {
  107. // No order
  108. // Flag used to see if we can shift the wheel
  109. bool can_shift = true;
  110. // Check the icons and flag the ability as countered if there is a match
  111. for (int8 i = 0; i < 6; i++) {
  112. if (countered[i] == 1) {
  113. // progress made on this wheel so we can't shift it
  114. can_shift = false;
  115. }
  116. if (m_wheel->abilities[i] == icon) {
  117. countered[i] = 1;
  118. ret = true;
  119. }
  120. }
  121. if (ret) {
  122. // As we found a match lets loop through to see if we completed the ho
  123. bool finished = true;
  124. for (int8 i = 0; i < 6; i++) {
  125. // if the ability is not 0xFFFF and countered is 0 then we still have more to go
  126. if (m_wheel->abilities[i] != 0xFFFF && countered[i] == 0) {
  127. finished = false;
  128. break;
  129. }
  130. }
  131. // is we finished the ho set the complete flag
  132. if (finished)
  133. SetComplete(2);
  134. }
  135. if (!ret && can_shift && m_wheel->shift_icon == icon) {
  136. // can shift, icon matched shift icon, and no progress made
  137. ret = ShiftWheel();
  138. }
  139. }
  140. else {
  141. // In order
  142. // Check to see if we can shift the wheel
  143. if (countered[0] == 0 && icon == m_wheel->shift_icon) {
  144. // Can only shift the icon if nothing has completed yet (countered[0] = 0)
  145. ret = ShiftWheel();
  146. }
  147. // Check the current stage and compare it to the icon
  148. else if (m_wheel->abilities[m_currentStage] == icon) {
  149. // Is a match so flag this stage as done
  150. countered[m_currentStage] = 1;
  151. // Advance the stage
  152. m_currentStage++;
  153. // Set the return value to true
  154. ret = true;
  155. // Check the next stage, if it is over 6 or equal to 0xFFFF flag the HO as complete
  156. if (m_currentStage > 6 || m_wheel->abilities[m_currentStage] == 0xFFFF)
  157. SetComplete(2);
  158. }
  159. }
  160. }
  161. return ret;
  162. }
  163. void HeroicOP::AddStarterChain(HeroicOPStarter* starter) {
  164. starters.push_back(starter);
  165. }
  166. bool HeroicOP::ShiftWheel() {
  167. // Can only shift once so if we already have return out
  168. if (HasShifted())
  169. return false;
  170. // Clear the wheel
  171. m_wheel = 0;
  172. // Get a new Wheel
  173. SetWheel(master_ho_list.GetWheel(starters.at(0)));
  174. // Set the ho as shifted
  175. m_shifted = true;
  176. return true;
  177. }
  178. MasterHeroicOPList::MasterHeroicOPList() {
  179. }
  180. MasterHeroicOPList::~MasterHeroicOPList() {
  181. map<int8, map<HeroicOPStarter*, vector<HeroicOPWheel*> > >::iterator itr;
  182. map<HeroicOPStarter*, vector<HeroicOPWheel*> >::iterator itr2;
  183. vector<HeroicOPWheel*>::iterator itr3;
  184. vector<HeroicOPStarter*> temp;
  185. vector<HeroicOPStarter*>::iterator itr4;
  186. // loop through the m_hoList to delete the pointers
  187. for (itr = m_hoList.begin(); itr != m_hoList.end(); itr++) {
  188. // loop through the second map of the m_hoList
  189. for (itr2 = itr->second.begin(); itr2 != itr->second.end(); itr2++) {
  190. // loop through the vector of the second map and delete the pointers
  191. for (itr3 = itr2->second.begin(); itr3 != itr2->second.end(); itr3++)
  192. safe_delete(*itr3);
  193. // clear the vector
  194. itr2->second.clear();
  195. // put the starter in a temp list to delete later
  196. temp.push_back(itr2->first);
  197. }
  198. // clear the seond map
  199. itr->second.clear();
  200. }
  201. // clear the m_hoList
  202. m_hoList.clear();
  203. // Delete the starters
  204. for (itr4 = temp.begin(); itr4 != temp.end(); itr4++)
  205. safe_delete(*itr4);
  206. // clear the temp vector
  207. temp.clear();
  208. }
  209. void MasterHeroicOPList::AddStarter(int8 start_class, HeroicOPStarter* starter) {
  210. if (m_hoList.count(start_class) == 0 || m_hoList[start_class].count(starter) == 0) {
  211. m_hoList[start_class][starter]; // This adds the starter with out giving it a vector of wheels yet.
  212. }
  213. }
  214. void MasterHeroicOPList::AddWheel(int32 starter_id, HeroicOPWheel* wheel) {
  215. map<int8, map<HeroicOPStarter*, vector<HeroicOPWheel*> > >::iterator itr;
  216. map<HeroicOPStarter*, vector<HeroicOPWheel*> >::iterator itr2;
  217. bool found = false;
  218. // Loop through the list and add the wheel to the correct starter
  219. for (itr = m_hoList.begin(); itr != m_hoList.end(); itr++) {
  220. for (itr2 = itr->second.begin(); itr2 != itr->second.end(); itr2++) {
  221. if (itr2->first->id == starter_id) {
  222. // Found a match, add the wheel, set the flag to break the first loop, and break this loop
  223. itr2->second.push_back(wheel);
  224. found = true;
  225. break;
  226. }
  227. }
  228. // If we found a match break the first loop
  229. if (found)
  230. break;
  231. }
  232. // No match found give an error.
  233. if (!found)
  234. LogWrite(SPELL__DEBUG, 0, "HO", "Attempted to add a wheel to a starter (%u) that doesn't exsist", starter_id);
  235. }
  236. HeroicOP* MasterHeroicOPList::GetHeroicOP(int8 class_id) {
  237. if (m_hoList.count(class_id) == 0) {
  238. LogWrite(SPELL__ERROR, 0, "HO", "No HO's found for the given class (%i)", class_id);
  239. return 0;
  240. }
  241. map<HeroicOPStarter*, vector<HeroicOPWheel*> >::iterator itr;
  242. HeroicOP* ret = new HeroicOP();
  243. // Loop through the starters for this class and add them to the HO
  244. for (itr = m_hoList[class_id].begin(); itr != m_hoList[class_id].end(); itr++)
  245. ret->AddStarterChain(itr->first);
  246. return ret;
  247. }
  248. HeroicOPWheel* MasterHeroicOPList::GetWheel(HeroicOPStarter* starter) {
  249. if (!starter)
  250. return 0;
  251. if (m_hoList.count(starter->start_class) == 0) {
  252. LogWrite(SPELL__ERROR, 0, "HO", "Start class (%u) not found", starter->start_class);
  253. return 0;
  254. }
  255. if (m_hoList[starter->start_class].count(starter) == 0) {
  256. LogWrite(SPELL__ERROR, 0, "HO", "Wheel not found for the provided starter (%u)", starter->id);
  257. return 0;
  258. }
  259. int index = MakeRandomInt(0, m_hoList[starter->start_class][starter].size() - 1);
  260. if(index < m_hoList[starter->start_class][starter].size())
  261. return m_hoList[starter->start_class][starter].at(index);
  262. else
  263. LogWrite(SPELL__ERROR, 0, "HO", "Wheel index %u for heroic_ops starter ID %u NOT Found!! Wheel starter_class %u, wheel size: %u. Wheels that match starter_link_id -> Starter 'id' missing.", index, starter->id, starter->start_class, m_hoList[starter->start_class][starter].size());
  264. return nullptr;
  265. }