HeroicOp.cpp 9.2 KB

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