Clone of UAS2 @ https://github.com/drudgedance/uas2

SimpleAI.cpp 6.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294
  1. /*
  2. * This file is part of UAS2.
  3. *
  4. * UAS2 is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * UAS2 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 UASv1; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. */
  17. /**
  18. * @file SimpleAI.cpp
  19. * Implements functionality for monster AI.
  20. */
  21. #include "SimpleAI.h"
  22. #include "MasterServer.h"
  23. #ifdef _DEBUG
  24. #undef THIS_FILE
  25. static char THIS_FILE[]=__FILE__;
  26. #define new DEBUG_NEW
  27. #endif
  28. DWORD SimpleAI::Monsters[MAX_MONSTERS][8];
  29. time_t SimpleAI::NextActionTime;
  30. time_t SimpleAI::longtime;
  31. /***************
  32. * constructors/destructors
  33. **************/
  34. SimpleAI::SimpleAI()
  35. {
  36. for(DWORD i = 0; i < MAX_MONSTERS; i++)
  37. {
  38. Monsters[i][0] = 0; // GUID
  39. Monsters[i][1] = 0; // Next Action Time
  40. Monsters[i][2] = 0; // Action
  41. Monsters[i][3] = 0; // Target GUID
  42. Monsters[i][4] = 0; // Engaged in Combat
  43. Monsters[i][5] = 0; // Is Moving
  44. Monsters[i][6] = 0;
  45. Monsters[i][7] = 0;
  46. }
  47. time(&NextActionTime + ACTION_DELAY);
  48. }
  49. SimpleAI::~SimpleAI()
  50. {
  51. }
  52. void SimpleAI::MoveMonsters( )
  53. {
  54. for (int i = 0; i < MAX_MONSTERS; i++)
  55. {
  56. if ( Monsters[i][5] == 1)
  57. {
  58. cMonster* pcMonster = (cMonster *) cWorldManager::FindObject( Monsters[i][0] );
  59. cClient* pcClient = cClient::FindClient( pcMonster->m_dwTargetGUID );
  60. if ( pcMonster->m_fHasTarget && pcClient)
  61. {
  62. pcMonster->m_TargetLocation = pcClient->m_pcAvatar->m_Location;
  63. }
  64. if (cPhysics::Get3DRange( pcMonster->m_Location, pcMonster->m_TargetLocation ) > 0.07 || !pcMonster->m_fHasTarget )
  65. {
  66. cVelocity tarVel = cPhysics::GetTargetVelocity( pcMonster->m_Location, pcMonster->m_TargetLocation );
  67. cLocation newLoc = cPhysics::VelocityMove(pcMonster->m_Location, tarVel, 0.5f);
  68. if ( HIWORD(newLoc.m_dwLandBlock) != HIWORD(pcMonster->m_Location.m_dwLandBlock) )
  69. {
  70. cWorldManager::MoveRemObject( pcMonster );
  71. pcMonster->m_Location = newLoc;
  72. cWorldManager::MoveAddObject( pcMonster );
  73. }
  74. else
  75. pcMonster->m_Location = newLoc;
  76. pcMonster->m_Location.m_flZ = cPhysics::GetLandZ( newLoc );
  77. if ( cPhysics::Get3DRange( pcMonster->m_Location, pcMonster->m_TargetLocation ) < 0.01 )
  78. {
  79. SimpleAI::SetMovingComplete( pcMonster->m_dwGUID );
  80. pcMonster->m_fHasTarget = false;
  81. cMessage cmPos = pcMonster->SetPosition();
  82. cWorldManager::SendToAllInFocus( pcMonster->m_Location, cmPos, 3 );
  83. pcMonster->m_iPosUpdateCount = 0;
  84. }
  85. pcMonster->m_iPosUpdateCount++;
  86. if (pcMonster->m_iPosUpdateCount >= 4)
  87. {
  88. cMessage cmPos = pcMonster->SetPosition();
  89. cWorldManager::SendToAllInFocus( pcMonster->m_Location, cmPos, 3 );
  90. pcMonster->m_iPosUpdateCount = 0;
  91. }
  92. }
  93. }
  94. }
  95. }
  96. bool SimpleAI::AddMonster(DWORD dwGUID)
  97. {
  98. bool fAdded = false;
  99. for(int i = 0; i < MAX_MONSTERS; i++)
  100. {
  101. if(Monsters[i][0] == 0)
  102. {
  103. time(&longtime);
  104. Monsters[i][0] = dwGUID;
  105. Monsters[i][1] = longtime + ACTION_DELAY;
  106. i = MAX_MONSTERS + 1;
  107. fAdded = true;
  108. }
  109. }
  110. return fAdded;
  111. }
  112. bool SimpleAI::RemoveMonster(DWORD dwGUID)
  113. {
  114. bool fRemoved = false;
  115. for(int i = 0; i < MAX_MONSTERS; i++)
  116. {
  117. if(Monsters[i][0] == dwGUID)
  118. {
  119. Monsters[i][0] = 0;
  120. Monsters[i][1] = 0;
  121. Monsters[i][2] = 0;
  122. Monsters[i][3] = 0;
  123. Monsters[i][4] = 0;
  124. Monsters[i][5] = 0;
  125. Monsters[i][6] = 0;
  126. Monsters[i][7] = 0;
  127. i = MAX_MONSTERS + 1;
  128. fRemoved = true;
  129. }
  130. }
  131. return fRemoved;
  132. }
  133. void SimpleAI::ExecuteActions( )
  134. {
  135. for(int i = 0; i < MAX_MONSTERS; i++)
  136. {
  137. time(&longtime);
  138. if((Monsters[i][0] != 0)&&(longtime > Monsters[i][1] ))
  139. {
  140. srand( timeGetTime( ) );
  141. int iRand = rand( );
  142. iRand = (iRand > 6400) ? iRand % 6400 : iRand;
  143. iRand = (iRand < 1600) ? 1600 + iRand : iRand;
  144. int delay = iRand/100;
  145. Monsters[i][1] = longtime + delay;
  146. cObject* pcObject = cWorldManager::FindObject( Monsters[i][0] );
  147. if(pcObject)
  148. {
  149. cMonsterServer::ProcessAction(Monsters[i][0],Monsters[i][2], Monsters[i][4], Monsters[i][3]);
  150. }
  151. else
  152. {
  153. //Nothing to do
  154. }
  155. }
  156. }
  157. }
  158. void SimpleAI::SetAction( DWORD dwGUID, DWORD dwEvent, WORD wDelay )
  159. {
  160. for(int i = 0; i < MAX_MONSTERS; i++)
  161. {
  162. if(Monsters[i][0] == dwGUID)
  163. {
  164. Monsters[i][1] = longtime + wDelay;
  165. Monsters[i][2] = dwEvent;
  166. Monsters[i][3] = 0;
  167. i = MAX_MONSTERS + 1;
  168. }
  169. }
  170. }
  171. void SimpleAI::SetMoving( DWORD dwGUID )
  172. {
  173. for (int i=0; i < MAX_MONSTERS; i++)
  174. {
  175. if ( Monsters[i][0] == dwGUID )
  176. {
  177. Monsters[i][5] = 1;
  178. i = MAX_MONSTERS + 1;
  179. }
  180. }
  181. }
  182. void SimpleAI::SetMovingComplete( DWORD dwGUID )
  183. {
  184. for (int i=0; i < MAX_MONSTERS; i++)
  185. {
  186. if ( Monsters[i][0] == dwGUID )
  187. {
  188. Monsters[i][5] = 0;
  189. i = MAX_MONSTERS + 1;
  190. }
  191. }
  192. }
  193. void SimpleAI::SetUnderAttack( DWORD dwGUID, DWORD dwTarget )
  194. {
  195. for(int i = 0; i < MAX_MONSTERS; i++)
  196. {
  197. if(Monsters[i][0] == dwGUID)
  198. {
  199. if(Monsters[i][4] == 1)
  200. {
  201. Monsters[i][1] = longtime + 0;
  202. Monsters[i][2] = 5;
  203. //Monsters[i][3] = dwTarget;
  204. Monsters[i][4] = 1; // Engaged in Combat
  205. }
  206. else
  207. {
  208. Monsters[i][1] = longtime + 0;
  209. Monsters[i][2] = 1;
  210. Monsters[i][3] = dwTarget;
  211. Monsters[i][4] = 1; // Engaged in Combat
  212. }
  213. i = MAX_MONSTERS + 1;
  214. }
  215. }
  216. }
  217. void SimpleAI::SetAttackComplete( DWORD dwGUID )
  218. {
  219. for(int i = 0; i < MAX_MONSTERS; i++)
  220. {
  221. if(Monsters[i][0] == dwGUID)
  222. {
  223. Monsters[i][1] = longtime + 1;
  224. Monsters[i][2] = 7;
  225. Monsters[i][3] = 0;
  226. Monsters[i][4] = 0; // Dis-Engaged from Combat
  227. i = MAX_MONSTERS + 1;
  228. }
  229. }
  230. }
  231. void SimpleAI::SetAttackEvent( DWORD dwGUID, DWORD dwTarget, DWORD dwEvent, WORD wDelay )
  232. {
  233. for(int i = 0; i < MAX_MONSTERS; i++)
  234. {
  235. if(Monsters[i][0] == dwGUID)
  236. {
  237. Monsters[i][1] = longtime + wDelay;
  238. Monsters[i][2] = dwEvent;
  239. Monsters[i][3] = dwTarget;
  240. i = MAX_MONSTERS + 1;
  241. }
  242. }
  243. }
  244. void SimpleAI::SetTargetKilled( DWORD dwTarget )
  245. {
  246. for(int i = 0; i < MAX_MONSTERS; i++)
  247. {
  248. if(Monsters[i][3] == dwTarget)
  249. {
  250. Monsters[i][1] = 5;
  251. Monsters[i][2] = 0;
  252. Monsters[i][3] = 0;
  253. Monsters[i][4] = 0; // Disengaged from combat
  254. }
  255. }
  256. }