/* * 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 . * */ //Filename : OFIRMRES.CPP //Description : Firm material resource object #include #include #include #include #include #include #if(defined(GERMAN) || defined(FRENCH) || defined(SPANISH)) #include #endif //---------- #define constant ------------// #define FIRM_DB "FIRM" #define FIRM_BUILD_DB "FBUILD" #define FIRM_FRAME_DB "FFRAME" #define FIRM_BITMAP_DB "FBITMAP" //------- Begin of function FirmRes::FirmRes -----------// FirmRes::FirmRes() { init_flag=0; } //--------- End of function FirmRes::FirmRes -----------// //---------- Begin of function FirmRes::init -----------// // // This function must be called after a map is generated. // void FirmRes::init() { deinit(); //----- open firm material bitmap resource file -------// String str; str = DIR_RES; str += "I_FIRM.RES"; res_bitmap.init_imported(str,1); // 1-read all into buffer //------- load database information --------// load_firm_bitmap(); // call load_firm_bitmap() first as load_firm_info() will need info loaded by load_firm_bitmap() load_firm_build(); load_firm_info(); //------------ set firm skill ------------// firm_res[FIRM_BASE]->firm_skill_id = SKILL_LEADING; firm_res[FIRM_CAMP]->firm_skill_id = SKILL_LEADING; firm_res[FIRM_MINE]->firm_skill_id = SKILL_MINING; firm_res[FIRM_FACTORY]->firm_skill_id = SKILL_MFT; firm_res[FIRM_RESEARCH]->firm_skill_id = SKILL_RESEARCH; firm_res[FIRM_WAR_FACTORY]->firm_skill_id = SKILL_MFT; //----------------------------------------// init_flag=1; } //---------- End of function FirmRes::init -----------// //---------- Begin of function FirmRes::deinit -----------// void FirmRes::deinit() { if( init_flag ) { mem_del(firm_info_array); mem_del(firm_build_array); mem_del(firm_bitmap_array); res_bitmap.deinit(); init_flag=0; } } //---------- End of function FirmRes::deinit -----------// //------- Begin of function FirmRes::load_firm_bitmap -------// // // Read in information of FBITMAP.DBF into memory array // void FirmRes::load_firm_bitmap() { FirmBitmapRec *firmBitmapRec; FirmBitmap *firmBitmap; int i; long bitmapOffset; Database *dbFirmBitmap = game_set.open_db(FIRM_BITMAP_DB); firm_bitmap_count = (short) dbFirmBitmap->rec_count(); firm_bitmap_array = (FirmBitmap*) mem_add( sizeof(FirmBitmap)*firm_bitmap_count ); //------ read in firm bitmap info array -------// memset( firm_bitmap_array, 0, sizeof(FirmBitmap) * firm_bitmap_count ); for( i=0 ; iread(i+1); firmBitmap = firm_bitmap_array+i; memcpy( &bitmapOffset, firmBitmapRec->bitmap_ptr, sizeof(long) ); firmBitmap->bitmap_ptr = res_bitmap.read_imported(bitmapOffset); firmBitmap->width = *((short*)firmBitmap->bitmap_ptr); firmBitmap->height = *(((short*)firmBitmap->bitmap_ptr)+1); firmBitmap->offset_x = m.atoi( firmBitmapRec->offset_x, firmBitmapRec->OFFSET_LEN ); firmBitmap->offset_y = m.atoi( firmBitmapRec->offset_y, firmBitmapRec->OFFSET_LEN ); firmBitmap->loc_width = m.atoi( firmBitmapRec->loc_width , firmBitmapRec->LOC_LEN ); firmBitmap->loc_height = m.atoi( firmBitmapRec->loc_height, firmBitmapRec->LOC_LEN ); firmBitmap->display_layer = firmBitmapRec->layer - '0'; } } //--------- End of function FirmRes::load_firm_bitmap ---------// //------- Begin of function FirmRes::load_firm_build -------// // // Read in information of FIRM.DBF into memory array // void FirmRes::load_firm_build() { FirmBuildRec *firmBuildRec; FirmFrameRec *firmFrameRec; FirmBuild *firmBuild; FirmBitmap *firmBitmap; int i, j, k, frameRecno, bitmapRecno; short *firstFrameArray; //---- read in firm count and initialize firm info array ----// Database *dbFirmBuild = game_set.open_db(FIRM_BUILD_DB); // only one database can be opened at a time, so we read FIRM.DBF first firm_build_count = (short) dbFirmBuild->rec_count(); firm_build_array = (FirmBuild*) mem_add( sizeof(FirmBuild)*firm_build_count ); memset( firm_build_array, 0, sizeof(FirmBuild) * firm_build_count ); //------ allocate an array for storing firstFrameRecno -----// firstFrameArray = (short*) mem_add( sizeof(short) * firm_build_count ); //---------- read in FBUILD.DBF ---------// for( i=0 ; iread(i+1); firmBuild = firm_build_array+i; m.rtrim_fld( firmBuild->build_code, firmBuildRec->race_code, firmBuild->BUILD_CODE_LEN ); firmBuild->animate_full_size = firmBuildRec->animate_full_size=='1'; firmBuild->race_id = m.atoi( firmBuildRec->race_id , firmBuildRec->RACE_ID_LEN ); firmBuild->frame_count = m.atoi( firmBuildRec->frame_count, firmBuildRec->FRAME_COUNT_LEN ); firmBuild->under_construction_bitmap_recno = m.atoi(firmBuildRec->under_construction_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN); // ##### begin Gilbert 18/10 ########// firmBuild->under_construction_bitmap_count = m.atoi(firmBuildRec->under_construction_bitmap_count, firmBuildRec->FRAME_COUNT_LEN); // ##### end Gilbert 18/10 ########// firmBuild->idle_bitmap_recno = m.atoi(firmBuildRec->idle_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN); firmBuild->ground_bitmap_recno = m.atoi(firmBuildRec->ground_bitmap_recno, firmBuildRec->BITMAP_RECNO_LEN); err_when( firmBuild->frame_count > MAX_FIRM_FRAME ); firstFrameArray[i] = m.atoi( firmBuildRec->first_frame, firmBuildRec->FIRST_FRAME_LEN ); } //-------- read in FFRAME.DBF --------// Database *dbFirmFrame = game_set.open_db(FIRM_FRAME_DB); int minOffsetX, minOffsetY; int maxX2, maxY2; for( i=0 ; iframe_count ; j++, frameRecno++ ) { firmFrameRec = (FirmFrameRec*) dbFirmFrame->read(frameRecno); //------ following animation frames, bitmap sections -----// firmBuild->first_bitmap_array[j] = m.atoi( firmFrameRec->first_bitmap, firmFrameRec->FIRST_BITMAP_LEN ); firmBuild->bitmap_count_array[j] = m.atoi( firmFrameRec->bitmap_count, firmFrameRec->BITMAP_COUNT_LEN ); firmBuild->frame_delay_array[j] = m.atoi( firmFrameRec->delay, firmFrameRec->DELAY_LEN ); //---- get the min offset_x, offset_y and max width, height ----// // // So we can get the largest area of all the frames in this building // and this will serve as a normal size setting for this building, // with variation from frame to frame // //--------------------------------------------------------------// firmBitmap = firm_bitmap_array + firmBuild->first_bitmap_array[j] - 1; for( k=firmBuild->bitmap_count_array[j] ; k>0 ; k--, firmBitmap++ ) { if( firmBitmap->offset_x < minOffsetX ) minOffsetX = firmBitmap->offset_x; if( firmBitmap->offset_y < minOffsetY ) minOffsetY = firmBitmap->offset_y; if( firmBitmap->offset_x + firmBitmap->width > maxX2 ) maxX2 = firmBitmap->offset_x + firmBitmap->width; if( firmBitmap->offset_y + firmBitmap->height > maxY2 ) maxY2 = firmBitmap->offset_y + firmBitmap->height; } } //------- set FirmBuild Info -------// bitmapRecno = firmBuild->first_bitmap_array[0]; //----- get the info of the first frame bitmap ----// firmBitmap = firm_bitmap_array + bitmapRecno - 1; firmBuild->loc_width = firmBitmap->loc_width; firmBuild->loc_height = firmBitmap->loc_height; firmBuild->min_offset_x = minOffsetX; firmBuild->min_offset_y = minOffsetY; firmBuild->max_bitmap_width = maxX2 - minOffsetX; firmBuild->max_bitmap_height = maxY2 - minOffsetY; //------ set firmBuild's under construction and idle bitmap recno -----// // ####### begin Gilbert 18/10 #######// if( firmBuild->under_construction_bitmap_recno==0 ) { firmBuild->under_construction_bitmap_recno = bitmapRecno; firmBuild->under_construction_bitmap_count = 1; } err_when(firmBuild->under_construction_bitmap_count == 0); // ####### end Gilbert 18/10 #######// if( firmBuild->idle_bitmap_recno==0 ) firmBuild->idle_bitmap_recno = bitmapRecno; } //------ free up the temporary array -------// mem_del( firstFrameArray ); } //--------- End of function FirmRes::load_firm_build ---------// //------- Begin of function FirmRes::load_firm_info -------// // // Read in information of FIRM.DBF into memory array // void FirmRes::load_firm_info() { FirmRec *firmRec; FirmInfo *firmInfo; FirmBuild *firmBuild; int i; //---- read in firm count and initialize firm info array ----// Database *dbFirm = game_set.open_db(FIRM_DB); // only one database can be opened at a time, so we read FIRM.DBF first firm_count = (short) dbFirm->rec_count(); firm_info_array = (FirmInfo*) mem_add( sizeof(FirmInfo)*firm_count ); memset( firm_info_array, 0, sizeof(FirmInfo) * firm_count ); //---------- read in FIRM.DBF ---------// for( i=0 ; iread(i+1); firmInfo = firm_info_array+i; m.rtrim_fld( firmInfo->name, firmRec->name, firmRec->NAME_LEN ); m.rtrim_fld( firmInfo->short_name, firmRec->short_name, firmRec->SHORT_NAME_LEN ); m.rtrim_fld( firmInfo->overseer_title, firmRec->overseer_title, firmRec->TITLE_LEN ); m.rtrim_fld( firmInfo->worker_title , firmRec->worker_title , firmRec->TITLE_LEN ); #if(defined(GERMAN) || defined(FRENCH) || defined(SPANISH)) translate.multi_to_win(firmInfo->name, firmInfo->NAME_LEN); translate.multi_to_win(firmInfo->short_name, firmInfo->SHORT_NAME_LEN); translate.multi_to_win(firmInfo->overseer_title, firmInfo->TITLE_LEN); translate.multi_to_win(firmInfo->worker_title, firmInfo->TITLE_LEN); #endif firmInfo->firm_id = i+1; firmInfo->tera_type = firmRec->tera_type-'0'; firmInfo->live_in_town = firmRec->live_in_town=='1'; firmInfo->max_hit_points = m.atoi( firmRec->hit_points, firmRec->HIT_POINTS_LEN ); firmInfo->first_build_id = m.atoi( firmRec->first_build, firmRec->FIRST_BUILD_LEN ); firmInfo->build_count = m.atoi( firmRec->build_count, firmRec->BUILD_COUNT_LEN ); firmInfo->need_overseer = firmInfo->overseer_title[0] && firmInfo->overseer_title[0] != ' '; firmInfo->need_worker = firmInfo->worker_title[0] && firmInfo->worker_title[0] != ' '; firmInfo->is_linkable_to_town = firmRec->is_linkable_to_town=='1'; firmInfo->setup_cost = m.atoi( firmRec->setup_cost, firmRec->COST_LEN ); firmInfo->year_cost = m.atoi( firmRec->year_cost, firmRec->COST_LEN ); firmInfo->buildable = firmInfo->setup_cost > 0; if( firmRec->all_know=='1' ) memset( firmInfo->nation_tech_level_array, 1, sizeof(firmInfo->nation_tech_level_array) ); //------- set loc_width & loc_height in FirmInfo --------// firmBuild = firm_build_array+firmInfo->first_build_id-1; firmInfo->loc_width = firmBuild->loc_width; firmInfo->loc_height = firmBuild->loc_height; //------------- set firm_race_id --------------// if( firmInfo->build_count==1 ) // if only one building style for this firm, take the race id. of the building as the race of the firm firmInfo->firm_race_id = (char) firmBuild->race_id; } } //--------- End of function FirmRes::load_firm_info ---------// //---------- Begin of function FirmRes::operator[] -----------// FirmInfo* FirmRes::operator[](int firmId) { err_if( firmId<1 || firmId>firm_count ) err_now( "FirmRes::operator[]" ); return firm_info_array+firmId-1; } //------------ End of function FirmRes::operator[] -----------// //-------- Start of function FirmInfo::can_build -------------// // // Whether unit of this race can build this firm or not. // // unitRecno - check whether this unit knows how to build // this firm. // int FirmInfo::can_build(int unitRecno) { if( !buildable ) return 0; Unit* unitPtr = unit_array[unitRecno]; if( !unitPtr->nation_recno ) return 0; if( !(get_nation_tech_level(unitPtr->nation_recno) > 0) ) return 0; //------ fortress of power ------// if( firm_id == FIRM_BASE ) // only if the nation has acquired the myth to build it { if( unitPtr->rank_id == RANK_GENERAL || unitPtr->rank_id == RANK_KING || unitPtr->skill.skill_id == SKILL_PRAYING || unitPtr->skill.skill_id == SKILL_CONSTRUCTION ) { //----- each nation can only build one seat of power -----// if( unitPtr->nation_recno > 0 && unitPtr->race_id > 0 && nation_array[unitPtr->nation_recno]->base_count_array[unitPtr->race_id-1] == 0 ) { //--- if this nation has acquired the needed scroll of power ---// return nation_array[unitPtr->nation_recno]->know_base_array[unitPtr->race_id-1]; } } return 0; } //------ a king or a unit with construction skill knows how to build all buildings -----// if( firm_race_id == 0 ) { if( unitPtr->rank_id == RANK_KING || unitPtr->skill.skill_id == SKILL_CONSTRUCTION ) return 1; } //----- if the firm is race specific, if the unit is right race, return true ----// if( firm_race_id == unitPtr->race_id ) return 1; //---- if the unit has the skill needed by the firm or the unit has general construction skill ----// if( firm_skill_id && firm_skill_id == unitPtr->skill.skill_id ) return 1; return 0; } //--------- End of function FirmInfo::can_build ---------------// //-------- Start of function FirmInfo::is_linkable_to_firm -------------// // int FirmInfo::is_linkable_to_firm(int linkFirmId) { switch(firm_id) { case FIRM_FACTORY: return linkFirmId==FIRM_MINE || linkFirmId==FIRM_MARKET || linkFirmId==FIRM_HARBOR; case FIRM_MINE: return linkFirmId==FIRM_FACTORY || linkFirmId==FIRM_MARKET || linkFirmId==FIRM_HARBOR; case FIRM_MARKET: return linkFirmId==FIRM_MINE || linkFirmId==FIRM_FACTORY || linkFirmId==FIRM_HARBOR; case FIRM_INN: // for an inn to scan for neighbor inns quickly, the link line is not displayed return linkFirmId==FIRM_INN; case FIRM_HARBOR: return linkFirmId==FIRM_MARKET || linkFirmId==FIRM_MINE || linkFirmId==FIRM_FACTORY; default: return 0; } } //--------- End of function FirmInfo::is_linkable_to_firm ---------------// //------ Start of function FirmInfo::default_link_status --------// // // return: 1 - the default status is // 0 - the default status is // int FirmInfo::default_link_status(int linkFirmId) { int rc; switch(firm_id) { case FIRM_MINE: rc = (linkFirmId!=FIRM_MARKET); break; case FIRM_FACTORY: rc = (linkFirmId==FIRM_MARKET) || (linkFirmId==FIRM_MINE); break; case FIRM_MARKET: rc = (linkFirmId==FIRM_FACTORY) || (linkFirmId==FIRM_HARBOR); break; case FIRM_HARBOR: rc = (linkFirmId==FIRM_MARKET) || (linkFirmId==FIRM_MINE) || (linkFirmId==FIRM_FACTORY); break; default: rc = 1; } if( rc ) return LINK_EE; else return LINK_DD; } //------- End of function FirmInfo::default_link_status -------// //-------- Start of function FirmInfo::get_build_id -------------// // // Give the build code and return the build id. // // buildCode - the build code // int FirmInfo::get_build_id(char* buildCode) { err_when( build_count<1 ); if( build_count==1 ) // if this firm has only one building type return first_build_id; int firmBuildId = first_build_id; for( int i=0 ; ibuild_code)==0 ) return firmBuildId; } err_here(); return 0; } //--------- End of function FirmInfo::get_build_id ---------------// //---- Begin of function FirmInfo::inc_nation_firm_count ----// void FirmInfo::inc_nation_firm_count(int nationRecno) { err_when( nationRecno<1 || nationRecno>nation_array.size() ); nation_firm_count_array[nationRecno-1]++; nation_array[nationRecno]->total_firm_count++; } //----- End of function FirmInfo::inc_nation_firm_count -----// //---- Begin of function FirmInfo::dec_nation_firm_count ----// void FirmInfo::dec_nation_firm_count(int nationRecno) { nation_firm_count_array[nationRecno-1]--; nation_array[nationRecno]->total_firm_count--; err_when( nation_firm_count_array[nationRecno-1] < 0 ); if( nation_firm_count_array[nationRecno-1] < 0 ) // run-time bug fixing nation_firm_count_array[nationRecno-1] = 0; } //----- End of function FirmInfo::dec_nation_firm_count -----// //--------- begin of function FirmBitmap::draw_at ---------// void FirmBitmap::draw_at(int absX, int absY, char *colorRemapTable, int displayLayer) { // -------- skip if display layer is not correct --------// if( !(displayLayer & display_layer)) return; //-------- check if the firm is within the view area --------// int x1 = absX + offset_x - World::view_top_x; int x2 = x1 + width -1; if( x1 >= ZOOM_WIDTH || x2 < 0) return; int y1 = absY + offset_y - World::view_top_y; int y2 = y1 + height -1; if( y1 >= ZOOM_HEIGHT || y2 < 0) return; //---- only portion of the sprite is inside the view area ------// if( x1 < 0 || x2 >= ZOOM_WIDTH || y1 < 0 || y2 >= ZOOM_HEIGHT ) { int srcX1 = x1<0 ? -x1 : 0; int srcY1 = y1<0 ? -y1 : 0; int srcX2 = x2>=ZOOM_WIDTH ? ZOOM_WIDTH-1-x1 : width-1; int srcY2 = y2>=ZOOM_HEIGHT ? ZOOM_HEIGHT-1-y1 : height-1; if( colorRemapTable ) { vga_back.put_bitmap_area_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, srcX1, srcY1, srcX2, srcY2, colorRemapTable ); } else { vga_back.put_bitmap_area_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, srcX1, srcY1, srcX2, srcY2 ); } } //---- the whole sprite is inside the view area ------// else { if( colorRemapTable ) { vga_back.put_bitmap_trans_remap_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr, colorRemapTable ); } else { vga_back.put_bitmap_trans_decompress( x1+ZOOM_X1, y1+ZOOM_Y1, bitmap_ptr ); } } } // --------- end of function FirmBitmap::draw_at ---------//