OUNITDRW.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483
  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 : OUNITDRW.CPP
  21. //Description : Object Unit Drawing routines
  22. #include <OVGA.h>
  23. #include <OMOUSE.h>
  24. #include <OFONT.h>
  25. #include <OINFO.h>
  26. #include <OFIRMRES.h>
  27. #include <OIMGRES.h>
  28. #include <OPOWER.h>
  29. #include <OSYS.h>
  30. #include <OGAME.h>
  31. #include <ONATION.h>
  32. #include <OUNIT.h>
  33. #include <OCONFIG.h>
  34. #ifdef NO_DEBUG_UNIT
  35. #undef err_when
  36. #undef err_here
  37. #undef err_if
  38. #undef err_else
  39. #undef err_now
  40. #define err_when(cond)
  41. #define err_here()
  42. #define err_if(cond)
  43. #define err_else
  44. #define err_now(msg)
  45. #undef DEBUG
  46. #endif
  47. //--------- Begin of function Unit::draw ---------//
  48. //
  49. // update Unit::draw_outlined() also
  50. //
  51. void Unit::draw()
  52. {
  53. //--------- draw sprite on the zoom window ---------//
  54. int needMirror;
  55. SpriteFrame* spriteFrame = cur_sprite_frame(&needMirror);
  56. update_abs_pos(spriteFrame);
  57. err_when( !sprite_info->res_bitmap.init_flag );
  58. char* bitmapPtr = sprite_info->res_bitmap.read_imported(spriteFrame->bitmap_offset);
  59. //-------- check if the sprite is inside the view area --------//
  60. int x1 = abs_x1-World::view_top_x; // the sprite's position in the view window
  61. if( x1 <= -spriteFrame->width || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
  62. return;
  63. int y1 = abs_y1-World::view_top_y;
  64. if( y1 <= -spriteFrame->height || y1 >= ZOOM_HEIGHT )
  65. return;
  66. //------- decide which approach to use for displaying -----//
  67. int x2 = abs_x2-World::view_top_x;
  68. int y2 = abs_y2-World::view_top_y;
  69. //------- get the color remap table for this sprite ------//
  70. char* colorRemapTable = game.get_color_remap_table(nation_recno, 0); // selected_flag);
  71. //---- only portion of the sprite is inside the view area ------//
  72. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  73. {
  74. if( needMirror ) // if this direction needed to be mirrored
  75. {
  76. vga_back.put_bitmap_area_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
  77. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
  78. }
  79. else
  80. {
  81. vga_back.put_bitmap_area_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
  82. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
  83. }
  84. }
  85. //---- the whole sprite is inside the view area ------//
  86. else
  87. {
  88. //------ mirror-bilting for certain directions ------//
  89. if( needMirror ) // if this direction needed to be mirrored
  90. {
  91. vga_back.put_bitmap_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1,
  92. bitmapPtr, colorRemapTable );
  93. }
  94. else
  95. {
  96. vga_back.put_bitmap_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1,
  97. bitmapPtr, colorRemapTable );
  98. }
  99. }
  100. //---- display additional info for selected units ----//
  101. if( selected_flag )
  102. {
  103. draw_selected();
  104. //---- also draw square on units that this unit is attacking ----//
  105. if( action_mode==ACTION_ATTACK_UNIT )
  106. {
  107. if( !unit_array.is_deleted(action_para) )
  108. unit_array[action_para]->draw_selected();
  109. }
  110. else if( action_mode==ACTION_ATTACK_FIRM )
  111. {
  112. if( !firm_array.is_deleted(action_para) )
  113. firm_array[action_para]->draw_selected();
  114. }
  115. }
  116. //--------- if the unit is a spy ---------//
  117. else if( spy_recno &&
  118. (true_nation_recno() == nation_array.player_recno ||
  119. config.show_ai_info) )
  120. {
  121. int dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
  122. int dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
  123. int maxHitBarWidth = ZOOM_LOC_WIDTH * sprite_info->loc_width - 11;
  124. world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
  125. dispY1-3, image_icon.get_ptr("U_SPY") );
  126. }
  127. if( (is_own() || config.show_ai_info || skill.skill_id == SKILL_LEADING ) ) // || rank_id > RANK_SOLDIER) )
  128. {
  129. if( !selected_flag && config.show_all_unit_icon )
  130. draw_skill_icon();
  131. }
  132. }
  133. //----------- End of function Unit::draw -----------//
  134. //--------- Begin of function Unit::draw_selected ---------//
  135. //
  136. // Draw a square around the sprite if it has been selected.
  137. //
  138. void Unit::draw_selected()
  139. {
  140. //------- determine the hit bar type -------//
  141. #define HIT_BAR_TYPE_COUNT 3
  142. int hit_bar_color_array[HIT_BAR_TYPE_COUNT] = { 0xA8, 0xB4, 0xAC };
  143. int hit_bar_max_array[HIT_BAR_TYPE_COUNT] = { 50, 100, 200 };
  144. char hitBarColor;
  145. int hitBarMax;
  146. for( int i=0 ; i<HIT_BAR_TYPE_COUNT ; i++ )
  147. {
  148. if( max_hit_points <= hit_bar_max_array[i] || i==HIT_BAR_TYPE_COUNT-1 )
  149. {
  150. hitBarColor = hit_bar_color_array[i];
  151. hitBarMax = max_hit_points; // max( max_hit_points, hit_bar_max_array[i] );
  152. break;
  153. }
  154. }
  155. //----- draw the hit point bar in a buffer -----//
  156. enum { HIT_BAR_HEIGHT=3 };
  157. enum { HIT_BAR_LIGHT_BORDER = 0,
  158. HIT_BAR_DARK_BORDER = 3,
  159. HIT_BAR_BODY = 1 };
  160. enum { NO_BAR_LIGHT_BORDER = 0x40+11,
  161. NO_BAR_DARK_BORDER = 0x40+3,
  162. NO_BAR_BODY = 0x40+7 };
  163. //----- set the display coordination and width -----//
  164. int maxHitBarWidth, dispX1, dispY1;
  165. if( mobile_type == UNIT_LAND )
  166. {
  167. if( unit_res[unit_id]->unit_class == UNIT_CLASS_HUMAN )
  168. maxHitBarWidth = ZOOM_LOC_WIDTH - 11;
  169. else
  170. maxHitBarWidth = ZOOM_LOC_WIDTH;
  171. dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
  172. dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
  173. }
  174. else
  175. {
  176. maxHitBarWidth = ZOOM_LOC_WIDTH*2 - 22;
  177. dispX1 = ZOOM_X1 + cur_x - World::view_top_x - ZOOM_LOC_WIDTH/2 + 11;
  178. dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
  179. if( mobile_type == UNIT_AIR )
  180. dispY1 -= 20;
  181. }
  182. //----------- set other vars -----------//
  183. char* dataPtr = sys.common_data_buf;
  184. int curBarWidth = maxHitBarWidth * max_hit_points / hitBarMax;
  185. int pointX = (curBarWidth-1) * (int) hit_points / max_hit_points; // the separating point between the area with hit point and the area without
  186. err_when( max_hit_points > hitBarMax );
  187. err_when( hit_points > max_hit_points );
  188. *((short*)dataPtr) = curBarWidth;
  189. *(((short*)dataPtr)+1) = HIT_BAR_HEIGHT;
  190. dataPtr += sizeof(short) * 2;
  191. //--------- draw the hit bar ------------//
  192. // IMGinit( curBarWidth, HIT_BAR_HEIGHT );
  193. IMGbar( dataPtr, curBarWidth, 0, 0, pointX, 0, hitBarColor+HIT_BAR_LIGHT_BORDER ); // top - with hit
  194. if( pointX < curBarWidth-1 )
  195. IMGbar( dataPtr, curBarWidth, pointX+1, 0, curBarWidth-1, 0, NO_BAR_LIGHT_BORDER ); // top - without hit
  196. IMGbar( dataPtr, curBarWidth, 0, 0, 0, 2, hitBarColor+HIT_BAR_LIGHT_BORDER ); // left - with hit
  197. IMGbar( dataPtr, curBarWidth, 1, 2, pointX, 2, hitBarColor+HIT_BAR_DARK_BORDER ); // bottom - with hit
  198. if( pointX < curBarWidth-1 )
  199. IMGbar( dataPtr, curBarWidth, pointX+1, 2, curBarWidth-1, 2, NO_BAR_DARK_BORDER ); // bottom - without hit
  200. if( pointX == curBarWidth - 1 )
  201. IMGbar( dataPtr, curBarWidth, curBarWidth-1, 1, curBarWidth-1, 1, hitBarColor+HIT_BAR_DARK_BORDER ); // right -with hit
  202. else
  203. IMGbar( dataPtr, curBarWidth, curBarWidth-1, 1, curBarWidth-1, 1, NO_BAR_DARK_BORDER ); // right -without hit
  204. IMGbar( dataPtr, curBarWidth, 1, 1, min(pointX,curBarWidth-2), 1, hitBarColor+HIT_BAR_BODY ); // bar body
  205. if( pointX < curBarWidth - 2 )
  206. IMGbar( dataPtr, curBarWidth, pointX+1, 1, curBarWidth-2, 1, NO_BAR_BODY ); // bar body
  207. // IMGinit( VGA_WIDTH, VGA_HEIGHT );
  208. //--------- display the bar now ---------//
  209. world.zoom_matrix->put_bitmap_clip(dispX1, dispY1, sys.common_data_buf);
  210. //----- display skill/rank icon (only for own units) -----//
  211. if( is_own() || config.show_ai_info || skill.skill_id == SKILL_LEADING || rank_id > RANK_SOLDIER )
  212. {
  213. draw_skill_icon();
  214. }
  215. }
  216. //----------- End of function Unit::draw_selected -----------//
  217. //----------- Begin of function Unit::draw_skill_icon ----------//
  218. void Unit::draw_skill_icon()
  219. {
  220. if( !race_id ) // only for human units
  221. return;
  222. int maxHitBarWidth, dispX1, dispY1;
  223. if( mobile_type == UNIT_LAND )
  224. {
  225. if( unit_res[unit_id]->unit_class == UNIT_CLASS_HUMAN )
  226. maxHitBarWidth = ZOOM_LOC_WIDTH - 11;
  227. else
  228. maxHitBarWidth = ZOOM_LOC_WIDTH;
  229. dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
  230. dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
  231. }
  232. else
  233. {
  234. maxHitBarWidth = ZOOM_LOC_WIDTH*2 - 22;
  235. dispX1 = ZOOM_X1 + cur_x - World::view_top_x - ZOOM_LOC_WIDTH/2 + 11;
  236. dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
  237. if( mobile_type == UNIT_AIR )
  238. dispY1 -= 20;
  239. }
  240. String str;
  241. switch( rank_id )
  242. {
  243. case RANK_KING:
  244. str = "U_KING";
  245. break;
  246. case RANK_GENERAL:
  247. str = "U_GENE";
  248. break;
  249. case RANK_SOLDIER:
  250. if( skill.skill_id )
  251. {
  252. str = "U_";
  253. str += skill.skill_code_array[skill.skill_id-1];
  254. }
  255. else
  256. str = "";
  257. break;
  258. }
  259. int y=dispY1-3;
  260. if(*str)
  261. {
  262. world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
  263. dispY1-3, image_icon.get_ptr(str) );
  264. y=dispY1+10;
  265. }
  266. if( spy_recno &&
  267. (true_nation_recno() == nation_array.player_recno ||
  268. config.show_ai_info) )
  269. {
  270. world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
  271. y, image_icon.get_ptr("U_SPY") );
  272. }
  273. //### begin alex 7/10 ###//
  274. /*( force_move_flag )
  275. {
  276. if(is_own() || config.show_ai_info)
  277. world.zoom_matrix->put_bitmap_clip(dispX1,
  278. dispY1+5, image_icon.get_ptr("MEDAL1") );
  279. }*/
  280. //#### end alex 7/10 ####//
  281. }
  282. //----------- End of function Unit::draw_skill_icon ----------//
  283. //----------- Begin of function Unit::is_visible ----------//
  284. int Unit::is_shealth()
  285. {
  286. return config.fog_of_war && world.get_loc(next_x_loc(), next_y_loc())->visibility() < unit_res[unit_id]->shealth;
  287. }
  288. //----------- End of function Unit::is_visible ----------//
  289. //--------- Begin of function Unit::draw_outlined ---------//
  290. //
  291. void Unit::draw_outlined()
  292. {
  293. //--------- draw sprite on the zoom window ---------//
  294. int needMirror;
  295. SpriteFrame* spriteFrame = cur_sprite_frame(&needMirror);
  296. update_abs_pos(spriteFrame);
  297. err_when( !sprite_info->res_bitmap.init_flag );
  298. char* bitmapPtr = sprite_info->res_bitmap.read_imported(spriteFrame->bitmap_offset);
  299. //-------- check if the sprite is inside the view area --------//
  300. int x1 = abs_x1-World::view_top_x; // the sprite's position in the view window
  301. if( x1 <= -spriteFrame->width || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
  302. return;
  303. int y1 = abs_y1-World::view_top_y;
  304. if( y1 <= -spriteFrame->height || y1 >= ZOOM_HEIGHT )
  305. return;
  306. //------- decide which approach to use for displaying -----//
  307. int x2 = abs_x2-World::view_top_x;
  308. int y2 = abs_y2-World::view_top_y;
  309. //------- get the color remap table for this sprite ------//
  310. char* colorRemapTable = game.get_color_remap_table(nation_recno, 1);
  311. //---- only portion of the sprite is inside the view area ------//
  312. if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
  313. {
  314. if( needMirror ) // if this direction needed to be mirrored
  315. {
  316. vga_back.put_bitmap_area_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
  317. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
  318. }
  319. else
  320. {
  321. vga_back.put_bitmap_area_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
  322. max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
  323. }
  324. }
  325. //---- the whole sprite is inside the view area ------//
  326. else
  327. {
  328. //------ mirror-bilting for certain directions ------//
  329. if( needMirror ) // if this direction needed to be mirrored
  330. {
  331. vga_back.put_bitmap_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1,
  332. bitmapPtr, colorRemapTable );
  333. }
  334. else
  335. {
  336. vga_back.put_bitmap_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1,
  337. bitmapPtr, colorRemapTable );
  338. }
  339. }
  340. //---- display additional info for selected units ----//
  341. if( selected_flag )
  342. {
  343. draw_selected();
  344. //---- also draw square on units that this unit is attacking ----//
  345. if( action_mode==ACTION_ATTACK_UNIT )
  346. {
  347. if( !unit_array.is_deleted(action_para) )
  348. unit_array[action_para]->draw_selected();
  349. }
  350. else if( action_mode==ACTION_ATTACK_FIRM )
  351. {
  352. if( !firm_array.is_deleted(action_para) )
  353. firm_array[action_para]->draw_selected();
  354. }
  355. }
  356. //--------- if the unit is a spy ---------//
  357. else if( spy_recno && true_nation_recno() == nation_array.player_recno )
  358. {
  359. int dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
  360. int dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
  361. int maxHitBarWidth = ZOOM_LOC_WIDTH * sprite_info->loc_width - 11;
  362. world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
  363. dispY1-3, image_icon.get_ptr("U_SPY") );
  364. }
  365. if( (is_own() || config.show_ai_info || skill.skill_id == SKILL_LEADING || rank_id > RANK_SOLDIER) )
  366. {
  367. if( !selected_flag )
  368. {
  369. draw_skill_icon();
  370. }
  371. }
  372. }
  373. //----------- End of function Unit::draw_outlined -----------//