123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483 |
- /*
- * Seven Kingdoms: Ancient Adversaries
- *
- * Copyright 1997,1998 Enlight Software Ltd.
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
- //Filename : OUNITDRW.CPP
- //Description : Object Unit Drawing routines
- #include <OVGA.h>
- #include <OMOUSE.h>
- #include <OFONT.h>
- #include <OINFO.h>
- #include <OFIRMRES.h>
- #include <OIMGRES.h>
- #include <OPOWER.h>
- #include <OSYS.h>
- #include <OGAME.h>
- #include <ONATION.h>
- #include <OUNIT.h>
- #include <OCONFIG.h>
- #ifdef NO_DEBUG_UNIT
- #undef err_when
- #undef err_here
- #undef err_if
- #undef err_else
- #undef err_now
- #define err_when(cond)
- #define err_here()
- #define err_if(cond)
- #define err_else
- #define err_now(msg)
- #undef DEBUG
- #endif
- //--------- Begin of function Unit::draw ---------//
- //
- // update Unit::draw_outlined() also
- //
- void Unit::draw()
- {
- //--------- draw sprite on the zoom window ---------//
- int needMirror;
- SpriteFrame* spriteFrame = cur_sprite_frame(&needMirror);
- update_abs_pos(spriteFrame);
- err_when( !sprite_info->res_bitmap.init_flag );
- char* bitmapPtr = sprite_info->res_bitmap.read_imported(spriteFrame->bitmap_offset);
- //-------- check if the sprite is inside the view area --------//
- int x1 = abs_x1-World::view_top_x; // the sprite's position in the view window
- if( x1 <= -spriteFrame->width || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
- return;
- int y1 = abs_y1-World::view_top_y;
- if( y1 <= -spriteFrame->height || y1 >= ZOOM_HEIGHT )
- return;
- //------- decide which approach to use for displaying -----//
- int x2 = abs_x2-World::view_top_x;
- int y2 = abs_y2-World::view_top_y;
- //------- get the color remap table for this sprite ------//
- char* colorRemapTable = game.get_color_remap_table(nation_recno, 0); // selected_flag);
- //---- only portion of the sprite is inside the view area ------//
- if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
- {
- if( needMirror ) // if this direction needed to be mirrored
- {
- vga_back.put_bitmap_area_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
- max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
- }
- else
- {
- vga_back.put_bitmap_area_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
- max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
- }
- }
- //---- the whole sprite is inside the view area ------//
- else
- {
- //------ mirror-bilting for certain directions ------//
- if( needMirror ) // if this direction needed to be mirrored
- {
- vga_back.put_bitmap_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1,
- bitmapPtr, colorRemapTable );
- }
- else
- {
- vga_back.put_bitmap_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1,
- bitmapPtr, colorRemapTable );
- }
- }
- //---- display additional info for selected units ----//
- if( selected_flag )
- {
- draw_selected();
- //---- also draw square on units that this unit is attacking ----//
- if( action_mode==ACTION_ATTACK_UNIT )
- {
- if( !unit_array.is_deleted(action_para) )
- unit_array[action_para]->draw_selected();
- }
- else if( action_mode==ACTION_ATTACK_FIRM )
- {
- if( !firm_array.is_deleted(action_para) )
- firm_array[action_para]->draw_selected();
- }
- }
- //--------- if the unit is a spy ---------//
- else if( spy_recno &&
- (true_nation_recno() == nation_array.player_recno ||
- config.show_ai_info) )
- {
- int dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
- int dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
- int maxHitBarWidth = ZOOM_LOC_WIDTH * sprite_info->loc_width - 11;
- world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
- dispY1-3, image_icon.get_ptr("U_SPY") );
- }
- if( (is_own() || config.show_ai_info || skill.skill_id == SKILL_LEADING ) ) // || rank_id > RANK_SOLDIER) )
- {
- if( !selected_flag && config.show_all_unit_icon )
- draw_skill_icon();
- }
- }
- //----------- End of function Unit::draw -----------//
- //--------- Begin of function Unit::draw_selected ---------//
- //
- // Draw a square around the sprite if it has been selected.
- //
- void Unit::draw_selected()
- {
- //------- determine the hit bar type -------//
- #define HIT_BAR_TYPE_COUNT 3
- int hit_bar_color_array[HIT_BAR_TYPE_COUNT] = { 0xA8, 0xB4, 0xAC };
- int hit_bar_max_array[HIT_BAR_TYPE_COUNT] = { 50, 100, 200 };
- char hitBarColor;
- int hitBarMax;
- for( int i=0 ; i<HIT_BAR_TYPE_COUNT ; i++ )
- {
- if( max_hit_points <= hit_bar_max_array[i] || i==HIT_BAR_TYPE_COUNT-1 )
- {
- hitBarColor = hit_bar_color_array[i];
- hitBarMax = max_hit_points; // max( max_hit_points, hit_bar_max_array[i] );
- break;
- }
- }
- //----- draw the hit point bar in a buffer -----//
- enum { HIT_BAR_HEIGHT=3 };
- enum { HIT_BAR_LIGHT_BORDER = 0,
- HIT_BAR_DARK_BORDER = 3,
- HIT_BAR_BODY = 1 };
- enum { NO_BAR_LIGHT_BORDER = 0x40+11,
- NO_BAR_DARK_BORDER = 0x40+3,
- NO_BAR_BODY = 0x40+7 };
- //----- set the display coordination and width -----//
- int maxHitBarWidth, dispX1, dispY1;
- if( mobile_type == UNIT_LAND )
- {
- if( unit_res[unit_id]->unit_class == UNIT_CLASS_HUMAN )
- maxHitBarWidth = ZOOM_LOC_WIDTH - 11;
- else
- maxHitBarWidth = ZOOM_LOC_WIDTH;
- dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
- dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
- }
- else
- {
- maxHitBarWidth = ZOOM_LOC_WIDTH*2 - 22;
- dispX1 = ZOOM_X1 + cur_x - World::view_top_x - ZOOM_LOC_WIDTH/2 + 11;
- dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
- if( mobile_type == UNIT_AIR )
- dispY1 -= 20;
- }
- //----------- set other vars -----------//
- char* dataPtr = sys.common_data_buf;
- int curBarWidth = maxHitBarWidth * max_hit_points / hitBarMax;
- int pointX = (curBarWidth-1) * (int) hit_points / max_hit_points; // the separating point between the area with hit point and the area without
- err_when( max_hit_points > hitBarMax );
- err_when( hit_points > max_hit_points );
- *((short*)dataPtr) = curBarWidth;
- *(((short*)dataPtr)+1) = HIT_BAR_HEIGHT;
- dataPtr += sizeof(short) * 2;
- //--------- draw the hit bar ------------//
- // IMGinit( curBarWidth, HIT_BAR_HEIGHT );
- IMGbar( dataPtr, curBarWidth, 0, 0, pointX, 0, hitBarColor+HIT_BAR_LIGHT_BORDER ); // top - with hit
- if( pointX < curBarWidth-1 )
- IMGbar( dataPtr, curBarWidth, pointX+1, 0, curBarWidth-1, 0, NO_BAR_LIGHT_BORDER ); // top - without hit
- IMGbar( dataPtr, curBarWidth, 0, 0, 0, 2, hitBarColor+HIT_BAR_LIGHT_BORDER ); // left - with hit
- IMGbar( dataPtr, curBarWidth, 1, 2, pointX, 2, hitBarColor+HIT_BAR_DARK_BORDER ); // bottom - with hit
- if( pointX < curBarWidth-1 )
- IMGbar( dataPtr, curBarWidth, pointX+1, 2, curBarWidth-1, 2, NO_BAR_DARK_BORDER ); // bottom - without hit
- if( pointX == curBarWidth - 1 )
- IMGbar( dataPtr, curBarWidth, curBarWidth-1, 1, curBarWidth-1, 1, hitBarColor+HIT_BAR_DARK_BORDER ); // right -with hit
- else
- IMGbar( dataPtr, curBarWidth, curBarWidth-1, 1, curBarWidth-1, 1, NO_BAR_DARK_BORDER ); // right -without hit
- IMGbar( dataPtr, curBarWidth, 1, 1, min(pointX,curBarWidth-2), 1, hitBarColor+HIT_BAR_BODY ); // bar body
- if( pointX < curBarWidth - 2 )
- IMGbar( dataPtr, curBarWidth, pointX+1, 1, curBarWidth-2, 1, NO_BAR_BODY ); // bar body
- // IMGinit( VGA_WIDTH, VGA_HEIGHT );
- //--------- display the bar now ---------//
- world.zoom_matrix->put_bitmap_clip(dispX1, dispY1, sys.common_data_buf);
- //----- display skill/rank icon (only for own units) -----//
- if( is_own() || config.show_ai_info || skill.skill_id == SKILL_LEADING || rank_id > RANK_SOLDIER )
- {
- draw_skill_icon();
- }
- }
- //----------- End of function Unit::draw_selected -----------//
- //----------- Begin of function Unit::draw_skill_icon ----------//
- void Unit::draw_skill_icon()
- {
- if( !race_id ) // only for human units
- return;
- int maxHitBarWidth, dispX1, dispY1;
- if( mobile_type == UNIT_LAND )
- {
- if( unit_res[unit_id]->unit_class == UNIT_CLASS_HUMAN )
- maxHitBarWidth = ZOOM_LOC_WIDTH - 11;
- else
- maxHitBarWidth = ZOOM_LOC_WIDTH;
- dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
- dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
- }
- else
- {
- maxHitBarWidth = ZOOM_LOC_WIDTH*2 - 22;
- dispX1 = ZOOM_X1 + cur_x - World::view_top_x - ZOOM_LOC_WIDTH/2 + 11;
- dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
- if( mobile_type == UNIT_AIR )
- dispY1 -= 20;
- }
- String str;
- switch( rank_id )
- {
- case RANK_KING:
- str = "U_KING";
- break;
- case RANK_GENERAL:
- str = "U_GENE";
- break;
- case RANK_SOLDIER:
- if( skill.skill_id )
- {
- str = "U_";
- str += skill.skill_code_array[skill.skill_id-1];
- }
- else
- str = "";
- break;
- }
- int y=dispY1-3;
- if(*str)
- {
- world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
- dispY1-3, image_icon.get_ptr(str) );
- y=dispY1+10;
- }
- if( spy_recno &&
- (true_nation_recno() == nation_array.player_recno ||
- config.show_ai_info) )
- {
- world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
- y, image_icon.get_ptr("U_SPY") );
- }
- //### begin alex 7/10 ###//
- /*( force_move_flag )
- {
- if(is_own() || config.show_ai_info)
- world.zoom_matrix->put_bitmap_clip(dispX1,
- dispY1+5, image_icon.get_ptr("MEDAL1") );
- }*/
- //#### end alex 7/10 ####//
- }
- //----------- End of function Unit::draw_skill_icon ----------//
- //----------- Begin of function Unit::is_visible ----------//
- int Unit::is_shealth()
- {
- return config.fog_of_war && world.get_loc(next_x_loc(), next_y_loc())->visibility() < unit_res[unit_id]->shealth;
- }
- //----------- End of function Unit::is_visible ----------//
- //--------- Begin of function Unit::draw_outlined ---------//
- //
- void Unit::draw_outlined()
- {
- //--------- draw sprite on the zoom window ---------//
- int needMirror;
- SpriteFrame* spriteFrame = cur_sprite_frame(&needMirror);
- update_abs_pos(spriteFrame);
- err_when( !sprite_info->res_bitmap.init_flag );
- char* bitmapPtr = sprite_info->res_bitmap.read_imported(spriteFrame->bitmap_offset);
- //-------- check if the sprite is inside the view area --------//
- int x1 = abs_x1-World::view_top_x; // the sprite's position in the view window
- if( x1 <= -spriteFrame->width || x1 >= ZOOM_WIDTH ) // out of the view area, not even a slight part of it appears in the view area
- return;
- int y1 = abs_y1-World::view_top_y;
- if( y1 <= -spriteFrame->height || y1 >= ZOOM_HEIGHT )
- return;
- //------- decide which approach to use for displaying -----//
- int x2 = abs_x2-World::view_top_x;
- int y2 = abs_y2-World::view_top_y;
- //------- get the color remap table for this sprite ------//
- char* colorRemapTable = game.get_color_remap_table(nation_recno, 1);
- //---- only portion of the sprite is inside the view area ------//
- if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT )
- {
- if( needMirror ) // if this direction needed to be mirrored
- {
- vga_back.put_bitmap_area_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
- max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
- }
- else
- {
- vga_back.put_bitmap_area_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmapPtr,
- max(0,x1)-x1, max(0,y1)-y1, min(ZOOM_WIDTH-1,x2)-x1, min(ZOOM_HEIGHT-1,y2)-y1, colorRemapTable );
- }
- }
- //---- the whole sprite is inside the view area ------//
- else
- {
- //------ mirror-bilting for certain directions ------//
- if( needMirror ) // if this direction needed to be mirrored
- {
- vga_back.put_bitmap_trans_remap_decompress_hmirror( x1+ZOOM_X1, y1+ZOOM_Y1,
- bitmapPtr, colorRemapTable );
- }
- else
- {
- vga_back.put_bitmap_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1,
- bitmapPtr, colorRemapTable );
- }
- }
- //---- display additional info for selected units ----//
- if( selected_flag )
- {
- draw_selected();
- //---- also draw square on units that this unit is attacking ----//
- if( action_mode==ACTION_ATTACK_UNIT )
- {
- if( !unit_array.is_deleted(action_para) )
- unit_array[action_para]->draw_selected();
- }
- else if( action_mode==ACTION_ATTACK_FIRM )
- {
- if( !firm_array.is_deleted(action_para) )
- firm_array[action_para]->draw_selected();
- }
- }
- //--------- if the unit is a spy ---------//
- else if( spy_recno && true_nation_recno() == nation_array.player_recno )
- {
- int dispX1 = ZOOM_X1 + cur_x - World::view_top_x;
- int dispY1 = ZOOM_Y1 + cur_y - World::view_top_y - 20;
- int maxHitBarWidth = ZOOM_LOC_WIDTH * sprite_info->loc_width - 11;
- world.zoom_matrix->put_bitmap_clip(dispX1+maxHitBarWidth+1,
- dispY1-3, image_icon.get_ptr("U_SPY") );
- }
- if( (is_own() || config.show_ai_info || skill.skill_id == SKILL_LEADING || rank_id > RANK_SOLDIER) )
- {
- if( !selected_flag )
- {
- draw_skill_icon();
- }
- }
- }
- //----------- End of function Unit::draw_outlined -----------//
|