OSPRITEA.cpp 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OSPRITEA.CPP
  21. //Description : Object SpriteArray
  22. #include <ALL.h>
  23. #include <OVGA.h>
  24. #include <OSTR.h>
  25. #include <OSYS.h>
  26. #include <OSPRTRES.h>
  27. #include <OSPRITE.h>
  28. #include <OUNIT.h>
  29. #ifdef DEBUG
  30. #include <OBULLET.h>
  31. #include <OTORNADO.h>
  32. //### begin alex 3/10 ###//
  33. static int num_of_unit;
  34. //#### end alex 3/10 ####//
  35. #endif
  36. //--------- Begin of function SpriteArray::SpriteArray ---------//
  37. //
  38. // <int> initArraySize - the initial size of this array.
  39. //
  40. SpriteArray::SpriteArray(int initArraySize) : DynArrayB(sizeof(Sprite*),initArraySize, DEFAULT_REUSE_INTERVAL_DAYS)
  41. {
  42. }
  43. //----------- End of function SpriteArray::SpriteArray ---------//
  44. //--------- Begin of function SpriteArray::~SpriteArray ---------//
  45. //
  46. SpriteArray::~SpriteArray()
  47. {
  48. deinit();
  49. }
  50. //----------- End of function SpriteArray::~SpriteArray ---------//
  51. //--------- Begin of function SpriteArray::init ---------//
  52. //
  53. void SpriteArray::init()
  54. {
  55. restart_recno = 1;
  56. }
  57. //----------- End of function SpriteArray::init ---------//
  58. //--------- Begin of function SpriteArray::deinit ---------//
  59. //
  60. // All firms should be deleted when the system terminated
  61. //
  62. // Chain : delete nation --> delete firm --> delete job --> delete item
  63. //
  64. // Some data is corrupted when the some firms still exist when
  65. // the system terminated
  66. //
  67. void SpriteArray::deinit()
  68. {
  69. if( size()==0 )
  70. return;
  71. //----- delete sprite objects ------//
  72. Sprite* emptyPtr = NULL;
  73. Sprite* spritePtr;
  74. for( int i=1 ; i<=size() ; i++ )
  75. {
  76. spritePtr = (Sprite*) get_ptr(i);
  77. if( spritePtr )
  78. delete spritePtr;
  79. update( &emptyPtr, i ); // set the pointer in SpriteArray to NULL, so is_deleted() can return correct result, this is needed as Unit::deinit() will call is_deleted()
  80. }
  81. //-------- zap the array -----------//
  82. zap();
  83. }
  84. //----------- End of function SpriteArray::deinit ---------//
  85. //--------- Begin of function SpriteArray::add ---------//
  86. void SpriteArray::add(Sprite *newSprite)
  87. {
  88. linkin(&newSprite);
  89. newSprite->sprite_recno = recno();
  90. }
  91. //----------- End of function SpriteArray::add -----------//
  92. //--------- Begin of function SpriteArray::add_sorted ---------//
  93. //
  94. // Add the sprite into the array in a sorted order.
  95. //
  96. // <Sprite*> spritePtr - pointer to the sprite to be added
  97. //
  98. // Note: it does not call Sprite::init_recno() as it is supposed to be used by disp_sprite_array
  99. // only and sprites to be added are existing sprites only.
  100. //
  101. // return : <int> - the recno of the newly added sprite in SpriteArray.
  102. //
  103. void SpriteArray::add_sorted(Sprite *newSprite)
  104. {
  105. int l=0, r=size(), x=0;
  106. int addY = newSprite->abs_y2;
  107. int testY = addY + 1;
  108. //---------------------------------------------------------------------//
  109. // Use a binary search to find the right location to add the new sprite.
  110. //---------------------------------------------------------------------//
  111. while (r > l)
  112. {
  113. x = (l + r) / 2;
  114. testY = operator[](x+1)->abs_y2; // the one to be compared with the adding one.
  115. if (addY < testY)
  116. r = x;
  117. else
  118. l = x + 1;
  119. if (addY == testY)
  120. break;
  121. }
  122. if (addY >= testY)
  123. x++;
  124. insert_at(x+1, &newSprite);
  125. }
  126. //----------- End of function SpriteArray::add_sorted -----------//
  127. //--------- Begin of function SpriteArray::del ---------//
  128. void SpriteArray::del(int recNo)
  129. {
  130. Sprite* spritePtr = (Sprite*) get_ptr(recNo);
  131. err_when( !spritePtr );
  132. delete spritePtr;
  133. linkout(recNo);
  134. }
  135. //----------- End of function SpriteArray::del -----------//
  136. //--------- Begin of function SpriteArray::process ---------//
  137. void SpriteArray::process()
  138. {
  139. #define SYS_YIELD_INTERVAL 20
  140. Sprite* spritePtr;
  141. int arraySize = size();
  142. if(arraySize<1)
  143. return; // no unit for process
  144. int i = restart_recno;
  145. //unit_search_node_used = 0; // reset unit_search_node_used for each process
  146. //### begin alex 3/10 ###//
  147. //int oldRecno = restart_recno;
  148. //restart_recno = 0;
  149. int newRecno = 0;
  150. //#### end alex 3/10 ####//
  151. int sysYieldCount = arraySize - arraySize%SYS_YIELD_INTERVAL;
  152. //### begin alex 3/10 ###//
  153. #ifdef DEBUG
  154. num_of_unit = 0;
  155. #endif
  156. //#### end alex 3/10 ####//
  157. for(int j=arraySize; j; --j, ++i) //for(int j=1; j<=arraySize; j++, i++)
  158. {
  159. //-------- system yield ---------//
  160. if(j==sysYieldCount)
  161. {
  162. sysYieldCount -= SYS_YIELD_INTERVAL;
  163. sys.yield();
  164. }
  165. if(i>arraySize)
  166. i = 1;
  167. spritePtr = (Sprite*)get_ptr(i);
  168. if(!spritePtr)
  169. continue;
  170. if(spritePtr->remain_attack_delay)
  171. spritePtr->remain_attack_delay--;
  172. if(spritePtr->cur_x==-1) // cur_x == -1 if the unit has removed from the map and gone into a firm
  173. continue;
  174. //### begin alex 3/10 ###//
  175. #ifdef DEBUG
  176. num_of_unit++;
  177. #endif
  178. //#### end alex 3/10 ####//
  179. //------- process sprite --------//
  180. err_when(!spritePtr->sprite_info->need_turning && spritePtr->cur_dir!=spritePtr->final_dir);
  181. #ifdef DEBUG
  182. unsigned long profileStartTime = m.get_time();
  183. #endif
  184. spritePtr->pre_process(); // it's actually calling Unit::pre_process() and other derived Unit classes
  185. #ifdef DEBUG
  186. unit_profile_time += m.get_time() - profileStartTime;
  187. #endif
  188. //-----------------------------------------------------//
  189. // note: for unit cur_x == -1, the unit is invisible and
  190. // no pre_process is done.
  191. //
  192. // for unit cur_x == -2, eg caravan, the unit is
  193. // invisible but pre_process is still processed.
  194. // However, sprite cur_action should be skipped.
  195. //-----------------------------------------------------//
  196. //if( spritePtr->cur_x == -1 )
  197. if( get_ptr(i)==NULL ) // in case pre_process() kills the current Sprite
  198. continue;
  199. if(spritePtr->cur_x<0) //if( spritePtr->cur_x == -1 || spritePtr->cur_x==-2)
  200. continue;
  201. #ifdef DEBUG
  202. long startTime;
  203. #endif
  204. #ifdef DEBUG
  205. profileStartTime = m.get_time();
  206. #endif
  207. switch(spritePtr->cur_action)
  208. {
  209. case SPRITE_IDLE:
  210. #ifdef DEBUG
  211. startTime = m.get_time();
  212. #endif
  213. spritePtr->process_idle();
  214. #ifdef DEBUG
  215. sprite_idle_profile_time += m.get_time() - startTime;
  216. #endif
  217. break;
  218. case SPRITE_READY_TO_MOVE:
  219. spritePtr->cur_action = SPRITE_IDLE; // to avoid problems of insensitive of mouse cursor
  220. spritePtr->process_idle();
  221. break;
  222. case SPRITE_MOVE:
  223. #ifdef DEBUG
  224. startTime = m.get_time();
  225. #endif
  226. spritePtr->process_move();
  227. #ifdef DEBUG
  228. sprite_move_profile_time += m.get_time() - startTime;
  229. #endif
  230. break;
  231. case SPRITE_WAIT:
  232. #ifdef DEBUG
  233. startTime = m.get_time();
  234. #endif
  235. spritePtr->process_wait();
  236. #ifdef DEBUG
  237. sprite_wait_profile_time += m.get_time() - startTime;
  238. #endif
  239. break;
  240. case SPRITE_ATTACK:
  241. #ifdef DEBUG
  242. startTime = m.get_time();
  243. #endif
  244. spritePtr->process_attack();
  245. #ifdef DEBUG
  246. sprite_attack_profile_time += m.get_time() - startTime;
  247. #endif
  248. break;
  249. case SPRITE_TURN:
  250. spritePtr->process_turn();
  251. break;
  252. case SPRITE_SHIP_EXTRA_MOVE: // for ship only
  253. spritePtr->process_extra_move();
  254. break; // do nothing
  255. case SPRITE_DIE:
  256. if( spritePtr->process_die() )
  257. {
  258. die(i);
  259. spritePtr = NULL;
  260. }
  261. break;
  262. }
  263. #ifdef DEBUG
  264. sprite_array_profile_time += m.get_time() - profileStartTime;
  265. #endif
  266. //----- can use other reasonable value to replace MIN_BACKGROUND_NODE_USED_UP ----//
  267. //### begin alex 3/10 ###//
  268. //if(!restart_recno && seek_path.total_node_avail<MIN_BACKGROUND_NODE_USED_UP)
  269. // restart_recno = i+1;
  270. if(!newRecno && seek_path.total_node_avail<MIN_BACKGROUND_NODE_USED_UP)
  271. newRecno = i+1;
  272. //#### end alex 3/10 ####//
  273. if(!is_deleted(i) && spritePtr)
  274. {
  275. if(spritePtr->guard_count > 0)
  276. {
  277. if(++spritePtr->guard_count > GUARD_COUNT_MAX )
  278. spritePtr->guard_count = 0;
  279. }
  280. }
  281. }
  282. //### begin alex 3/10 ###//
  283. //if(!restart_recno)
  284. // restart_recno = oldRecno;
  285. if(newRecno)
  286. restart_recno = newRecno;
  287. //#### end alex 3/10 ####//
  288. #ifdef DEBUG
  289. if(this==&unit_array || this==&bullet_array || this==&tornado_array)
  290. m.set_random_seed(m.get_random_seed() + restart_recno);
  291. #endif
  292. }
  293. //----------- End of function SpriteArray::process -----------//
  294. #ifdef DEBUG
  295. //------- Begin of function SpriteArray::operator[] -----//
  296. Sprite* SpriteArray::operator[](int recNo)
  297. {
  298. Sprite* spritePtr = (Sprite*) get_ptr(recNo);
  299. if( !spritePtr )
  300. err.run( "SpriteArray[] is deleted" );
  301. return spritePtr;
  302. }
  303. //--------- End of function SpriteArray::operator[] ----//
  304. #endif