HeroicOp.cpp 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302
  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<vector<HeroicOPStarter*>::iterator> temp;
  48. HeroicOPStarter* starter = 0;
  49. // If no wheel is set we are dealing with a starter chain still.
  50. if (!m_wheel) {
  51. // Loop through the starter chains
  52. for (itr = starters.begin(); itr != starters.end(); itr++) {
  53. starter = *itr;
  54. // See if the icon matches the ability at our current stage, if not add it to a list to be removed
  55. if (starter->abilities[m_currentStage] == icon)
  56. ret = true;
  57. else
  58. temp.push_back(itr);
  59. }
  60. if (ret) {
  61. // ret = true so we had a match, first thing to do is remove those that didn't match
  62. vector<vector<HeroicOPStarter*>::iterator>::iterator remove_itr;
  63. for (remove_itr = temp.begin(); remove_itr != temp.end(); remove_itr++)
  64. starters.erase(*remove_itr);
  65. // now advance the current stage
  66. m_currentStage++;
  67. // Temp pointer to hold the completed chain, if any
  68. HeroicOPStarter* complete_starter = 0;
  69. // now loop through those that are left and check the next stage abilities for a 0xFFFF
  70. for (itr = starters.begin(); itr != starters.end(); itr++) {
  71. starter = *itr;
  72. // Found one that is 0xFFFF, means the starter chain is done, get a wheel and reset the stage to 0
  73. if ((starter->abilities[m_currentStage] = 0xFFFF)) {
  74. // reset the stage
  75. ResetStage();
  76. // geth the wheel
  77. m_wheel = master_ho_list.GetWheel(starter);
  78. // store the starter chain that is completed
  79. complete_starter = starter;
  80. // set the start time to now
  81. SetStartTime(Timer::GetCurrentTime2());
  82. // set the total time to complete the real to was the admin set in rules (default 10.0f)
  83. SetTotalTime(rule_manager.GetGlobalRule(R_Zone, HOTime)->GetFloat());
  84. // We set a wheel so we are done, kill the loop
  85. break;
  86. }
  87. }
  88. // Check to see if the completed start chain pointer was set
  89. if (complete_starter) {
  90. // clear the starter list
  91. starters.clear();
  92. // 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
  93. starters.push_back(complete_starter);
  94. }
  95. }
  96. }
  97. else {
  98. // Wheel was set so we need to check the order it needs to be completed in.
  99. if (m_wheel->order == 0) {
  100. // No order
  101. // Flag used to see if we can shift the wheel
  102. bool can_shift = true;
  103. // Check the icons and flag the ability as countered if there is a match
  104. for (int8 i = 0; i < 6; i++) {
  105. if (countered[i] == 1) {
  106. // progress made on this wheel so we can't shift it
  107. can_shift = false;
  108. }
  109. if (m_wheel->abilities[i] == icon) {
  110. countered[i] = 1;
  111. ret = true;
  112. }
  113. }
  114. if (ret) {
  115. // As we found a match lets loop through to see if we completed the ho
  116. bool finished = true;
  117. for (int8 i = 0; i < 6; i++) {
  118. // if the ability is not 0xFFFF and countered is 0 then we still have more to go
  119. if (m_wheel->abilities[i] != 0xFFFF && countered[i] == 0) {
  120. finished = false;
  121. break;
  122. }
  123. }
  124. // is we finished the ho set the complete flag
  125. if (finished)
  126. SetComplete(2);
  127. }
  128. if (!ret && can_shift && m_wheel->shift_icon == icon) {
  129. // can shift, icon matched shift icon, and no progress made
  130. ret = ShiftWheel();
  131. }
  132. }
  133. else {
  134. // In order
  135. // Check to see if we can shift the wheel
  136. if (countered[0] == 0 && icon == m_wheel->shift_icon) {
  137. // Can only shift the icon if nothing has completed yet (countered[0] = 0)
  138. ret = ShiftWheel();
  139. }
  140. // Check the current stage and compare it to the icon
  141. else if (m_wheel->abilities[m_currentStage] == icon) {
  142. // Is a match so flag this stage as done
  143. countered[m_currentStage] = 1;
  144. // Advance the stage
  145. m_currentStage++;
  146. // Set the return value to true
  147. ret = true;
  148. // Check the next stage, if it is over 6 or equal to 0xFFFF flag the HO as complete
  149. if (m_currentStage > 6 || m_wheel->abilities[m_currentStage] == 0xFFFF)
  150. SetComplete(2);
  151. }
  152. }
  153. }
  154. return ret;
  155. }
  156. void HeroicOP::AddStarterChain(HeroicOPStarter* starter) {
  157. starters.push_back(starter);
  158. }
  159. bool HeroicOP::ShiftWheel() {
  160. // Can only shift once so if we already have return out
  161. if (HasShifted())
  162. return false;
  163. // Clear the wheel
  164. m_wheel = 0;
  165. // Get a new Wheel
  166. SetWheel(master_ho_list.GetWheel(starters.at(0)));
  167. // Set the ho as shifted
  168. m_shifted = true;
  169. return true;
  170. }
  171. MasterHeroicOPList::MasterHeroicOPList() {
  172. }
  173. MasterHeroicOPList::~MasterHeroicOPList() {
  174. map<int8, map<HeroicOPStarter*, vector<HeroicOPWheel*> > >::iterator itr;
  175. map<HeroicOPStarter*, vector<HeroicOPWheel*> >::iterator itr2;
  176. vector<HeroicOPWheel*>::iterator itr3;
  177. vector<HeroicOPStarter*> temp;
  178. vector<HeroicOPStarter*>::iterator itr4;
  179. // loop through the m_hoList to delete the pointers
  180. for (itr = m_hoList.begin(); itr != m_hoList.end(); itr++) {
  181. // loop through the second map of the m_hoList
  182. for (itr2 = itr->second.begin(); itr2 != itr->second.end(); itr2++) {
  183. // loop through the vector of the second map and delete the pointers
  184. for (itr3 = itr2->second.begin(); itr3 != itr2->second.end(); itr3++)
  185. safe_delete(*itr3);
  186. // clear the vector
  187. itr2->second.clear();
  188. // put the starter in a temp list to delete later
  189. temp.push_back(itr2->first);
  190. }
  191. // clear the seond map
  192. itr->second.clear();
  193. }
  194. // clear the m_hoList
  195. m_hoList.clear();
  196. // Delete the starters
  197. for (itr4 = temp.begin(); itr4 != temp.end(); itr4++)
  198. safe_delete(*itr4);
  199. // clear the temp vector
  200. temp.clear();
  201. }
  202. void MasterHeroicOPList::AddStarter(int8 start_class, HeroicOPStarter* starter) {
  203. if (m_hoList.count(start_class) == 0 || m_hoList[start_class].count(starter) == 0) {
  204. m_hoList[start_class][starter]; // This adds the starter with out giving it a vector of wheels yet.
  205. }
  206. }
  207. void MasterHeroicOPList::AddWheel(int32 starter_id, HeroicOPWheel* wheel) {
  208. map<int8, map<HeroicOPStarter*, vector<HeroicOPWheel*> > >::iterator itr;
  209. map<HeroicOPStarter*, vector<HeroicOPWheel*> >::iterator itr2;
  210. bool found = false;
  211. // Loop through the list and add the wheel to the correct starter
  212. for (itr = m_hoList.begin(); itr != m_hoList.end(); itr++) {
  213. for (itr2 = itr->second.begin(); itr2 != itr->second.end(); itr2++) {
  214. if (itr2->first->id == starter_id) {
  215. // Found a match, add the wheel, set the flag to break the first loop, and break this loop
  216. itr2->second.push_back(wheel);
  217. found = true;
  218. break;
  219. }
  220. }
  221. // If we found a match break the first loop
  222. if (found)
  223. break;
  224. }
  225. // No match found give an error.
  226. if (!found)
  227. LogWrite(SPELL__ERROR, 0, "HO", "Attempted to add a wheel to a starter (%u) that doesn't exsist", starter_id);
  228. }
  229. HeroicOP* MasterHeroicOPList::GetHeroicOP(int8 class_id) {
  230. if (m_hoList.count(class_id) == 0) {
  231. LogWrite(SPELL__ERROR, 0, "HO", "No HO's found for the given class (%i)", class_id);
  232. return 0;
  233. }
  234. map<HeroicOPStarter*, vector<HeroicOPWheel*> >::iterator itr;
  235. HeroicOP* ret = new HeroicOP();
  236. // Loop through the starters for this class and add them to the HO
  237. for (itr = m_hoList[class_id].begin(); itr != m_hoList[class_id].end(); itr++)
  238. ret->AddStarterChain(itr->first);
  239. return ret;
  240. }
  241. HeroicOPWheel* MasterHeroicOPList::GetWheel(HeroicOPStarter* starter) {
  242. if (!starter)
  243. return 0;
  244. if (m_hoList.count(starter->start_class) == 0) {
  245. LogWrite(SPELL__ERROR, 0, "HO", "Start class (%u) not found", starter->start_class);
  246. return 0;
  247. }
  248. if (m_hoList[starter->start_class].count(starter) == 0) {
  249. LogWrite(SPELL__ERROR, 0, "HO", "Wheel not found for the provided starter (%u)", starter->id);
  250. return 0;
  251. }
  252. int index = MakeRandomInt(0, m_hoList[starter->start_class][starter].size() - 1);
  253. return m_hoList[starter->start_class][starter].at(index);
  254. }